[erlang-questions] Intel Quad CPUs

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.

	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