length() in guards
Richard A. O'Keefe
Tue Sep 30 03:51:18 CEST 2003
I commented that
(1) while computing length(X) is O(length(X)), which is not a nice thing
to do in a guard, *comparing* length(X) <relop> N where N is a number
can be done in O(min(length(X),N)) time, which is not so bad at all.
(2) an examination of a large amount of existing Erlang code showed that
most uses were of the safe/fast kind and that other uses could be
avoided and in avoiding them you would get faster & clearer code anyway.
Bengt Kleberg <Bengt.Kleberg@REDACTED> suggests:
is_length_equal( Var, Length )
is_length_greater( Var, Length )
is_length_less( Var, Length )
this would make it easier to remember, imho.
Well, no. First, the direct connection between length/1 and what's
happening is severed. Second, instead of remembering one function and
8 relational operators, I would now have to remember one function and
16 relational operators, which is not good. Third, the spelling of
"is_length_greater" is arbitrary; my Scheme code uses "length>?" which
conforms to existing Scheme naming conventions, so doesn't require any
special effort of memory. Fourth, and most important, it's not actually
a compatible change. Fifth, there is a substantial documentation cost
for adding these guards.
Here's what I had in mind.
Implement if_length_<relop> instructions in BEAM.
Make the compiler recognise length(X) <relop> E and
E <relop> length(X) as special cases, and generate the
Make the compiler *warn* if there is a use of length/1 in a guard
that isn't caught by step 2, *but* continue to generate the same
code as is now generated.
Encouraged by the warning, people clean up their code.
You were expecting me to say "turn the warning into an error", maybe?
No, there is no step 5.
The point is that _existing_ code can benefit from this observation
_without any change at all_. Code which is unclear/inefficient is
pointed out when you get to step 3, but is never broken.
More information about the erlang-questions