[erlang-questions] Intel Quad CPUs
ok
ok@REDACTED
Mon Sep 10 03:22:44 CEST 2007
On 8 Sep 2007, at 2:31 am, Richard Carlsson wrote:
> - you couldn't just cut out a guard and paste it in somewhere,
> because the scope wasn't the same - atom(X) and the other tests
> were not defined outside guards
You *still* can't do that because the *semantics* is different.
Consider
atom(X), integer(Y)
or, if you prefer to be long-winded,
is_atom(X), is_integer(Y).
As a guard, this asserts the conjunction "X is an atom (and) Y is an
integer". As an expression, it says "determine whether X is an atom
or not but forget the answer; now tell me whether Y is an integer".
With comma having different semantics in the two environments, it is
actually a very useful protection when a guard test uses a name that
is not available in expression.
atom(X), integer(Y)
has the decency to raise an exception if you try to use it in an
expression, instead of quietly giving you the wrong answer.
>
> - you couldn't access the type tests directly as a boolean value,
> as in "Bool = atom(A)" - you'd have to write "Bool = (if atom
> (A) ->
> true; true -> false end)", which is not exactly elegant
This was trivially fixable with a macro:
?G(X) ===> if X => true ; true => false end
Note that the semantics of 'length', amongst others, is subtly
different between guard and expression contexts, so
?G(length(X) < 10)
is *not* the same as
length(X) < 10
>
> - some names could have different meaning depending on whether they
> were used as guard tests or as normal expressions - float(X) is
> a boolean test for float-ness if it's a guard, but if it's a
> normal expression then it refers to the int-to-float conversion
> function
That is the only persuasive argument I've ever heard, and in
light of the other semantic differences, it would have been better
to rename the convert-to-float function to as_float/1.
More information about the erlang-questions
mailing list