comma vs andalso

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

comma vs andalso

by Joel Reymont :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I noticed that inets code uses

foo(...) when Condition1 andalso Condition2 -> ...

Is the comma deprecated? For example, why not

foo(...) when Condition1, Condition2 -> ...

A related pet peeve of mine is that the following does not properly  
indent in the latest Emacs mode

handle_info({tcp, Socket, Bin}, State)
   when State#state.transport /= undefined,
State#state.socket == Socket ->
...

I have to manually insert spaces to align State#state... above and  
using andalso above does not help either.

        Thanks, Joel

---
Mac hacker with a performance bent
http://www.linkedin.com/in/joelreymont


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Magnus Henoch-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Joel Reymont <joelr1@...> writes:

> A related pet peeve of mine is that the following does not properly
> indent in the latest Emacs mode
>
> handle_info({tcp, Socket, Bin}, State)
>   when State#state.transport /= undefined,
> State#state.socket == Socket ->
> ...
>
> I have to manually insert spaces to align State#state... above and
> using andalso above does not help either.

I found that this happens because there is a "." in the guard.  This
change to erlang-mode (actually erlware-mode, but the code should be
similar) seems to fix it:

diff --git a/erlang.el b/erlang.el
index 6ad03ea..916037e 100644
--- a/erlang.el
+++ b/erlang.el
@@ -2097,7 +2097,7 @@ Value is list (stack token-start token-type in-what)."
             ((looking-at "when[^->\.]*case[^->\.]*->"))
             ((looking-at "when[^->\.]*receive[^->\.]*->"))
             ;; Normal when case
-            ((looking-at "when [^->\.]*->")
+            ((looking-at "when [^->]*->")
              (erlang-push (list 'when token (current-column)) stack))
             ((looking-at "after[.]+->")
              (erlang-push (list 'icr token (current-column)) stack))

Not sure what other cases that would mess up, though.  The comment above
mentions one possible gotcha:

            ;; In test suites you may want to do something like
            ;; ?match(Mem when integer(Mem), mnesia:table_info(Tab,
            ;; memory)), and then the following if/case/receive
            ;; statement will mess up the indentation by fooling the
            ;; erlang mode to think the 'when' in the argument is a
            ;; "real" when. The following three clauses will avoid
            ;; this problem.

--
Magnus Henoch, magnus@...
Erlang Training and Consulting
http://www.erlang-consulting.com/

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Roberto Ostinelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 06/lug/09, at 13:13, Joel Reymont wrote:

> I noticed that inets code uses
>
> foo(...) when Condition1 andalso Condition2 -> ...
>
> Is the comma deprecated? For example, why not
>
> foo(...) when Condition1, Condition2 -> ...

the difference is very simple. comma indicates that both guard  
operators need to be evaluated, while on the contrary 'andalso' means  
that the second condition is evaluated ONLY if condition1 is true.  
same goes for 'orselse'.

this is particularly relevant when condition2 would result for  
instance in an evaluation error if condition1 is not met, as in:

foo(..) when (islist(X) == true ansalso (lists:nth(1,X) == 'test') -> ..

hope this clears.

r.


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Roberto Ostinelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 06/lug/09, at 14:19, Roberto Ostinelli wrote:

> foo(..) when (islist(X) == true ansalso (lists:nth(1,X) == 'test') -
> > ..

that would be

foo(..) when (islist(X) =:= true) ansalso (lists:nth(1,X) =:= 'test') -
 > ..

pardon me i was in python mode.

r.


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by whongo@gmail.com :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Jul 6, 2009 at 2:21 PM, Roberto Ostinelli <roberto@...>wrote:

>
> On 06/lug/09, at 14:19, Roberto Ostinelli wrote:
>
>  foo(..) when (islist(X) == true ansalso (lists:nth(1,X) == 'test') -> ..
>>
>
> that would be
>
> foo(..) when (islist(X) =:= true) ansalso (lists:nth(1,X) =:= 'test') -> ..
>

'==' and '=:=' are equivalent except when applied to numbers, are they not?
(1 == 1.0) is true, while (1 =:= 1.0) is false. When applied to atoms, as in
your example, there is no difference.
And the difference between comma and 'andalso' doesn't actually matter much
for the purpose of avoiding evaluation errors in guard context, since such
an error in a guard just means that the guard fails. For instance, try this:
1> length(a).
** exception error: bad argument
  in function length/1
  called as length(a)
2> Foo = fun(X) when length(X) > 3 -> "Long list"; (X) -> "Short or no list"
end.
3> Foo(a).
"Short or no list"
Also, lists:nth(X) is an illegal guard expression. ;)

Parent Message unknown Re: comma vs andalso

by Roberto Ostinelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 06/lug/09, at 15:00, Hynek Vychodil wrote:

>
> It seems you are still in python mode. lists:nth/2 is not allowed in  
> guard expression.

you are definitely right :)

let me point another (and correct) example then:

foo(..) when X =/= 0 andalso 1/X > 0.1 -> ..

the following expression would fail instead:

foo(..) when X =/= 0, 1/X > 0.1 -> ..

r.


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Roberto Ostinelli wrote:
> the difference is very simple. comma indicates that both guard operators
> need to be evaluated, while on the contrary 'andalso' means that the
> second condition is evaluated ONLY if condition1 is true. same goes for
> 'orselse'.

No, the comma separator in guards also uses short-cut evaluation
and will not evaluate the subsequent tests if one test fails. If
there are alternatives expressed with semicolon, the next such
alternative will be tried instead; otherwise, the whole guard fails.

What you describe is true for the 'and' operator compared to 'andalso'.

    /Richard

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Parent Message unknown Re: comma vs andalso

by Roberto Ostinelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 06/lug/09, at 15:21, Hynek Vychodil wrote:

> It seems no difference for me:
>
> 1> F = fun(X) when X=/=0, 1/X > 0.1 -> true; (_) -> false end.
> #Fun<erl_eval.6.13229925>
> 2> F2 = fun(X) when X=/=0 andalso 1/X > 0.1 -> true; (_) -> false end.
> #Fun<erl_eval.6.13229925>
> 3> [ F(X) || X <- [0, 0.0, 0.1, 10, 9]].
> [false,false,true,false,true]
> 4> [ F2(X) || X <- [0, 0.0, 0.1, 10, 9]].
> [false,false,true,false,true]
>
> --  
> --Hynek (Pichi) Vychodil

yes, at it has been pointed out by richard already:

On 06/lug/09, at 15:10, Richard Carlsson wrote:

> and will not evaluate the subsequent tests if one test fails. If
> there are alternatives expressed with semicolon, the next such
> alternative will be tried instead; otherwise, the whole guard fails.
>
> What you describe is true for the 'and' operator compared to  
> 'andalso'.

my fault.

as you can see:

1> F3 = fun(X) when X=/=0 and (1/X > 0.1) -> true; (_) -> false end.
#Fun<erl_eval.6.13229925>
2> [ F3(X) || X <- [0, 0.0, 0.1, 10, 9]].
[false,false,false,false,false]

r.



________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Roberto Ostinelli wrote:
> let me point another (and correct) example then:
>
> foo(..) when X =/= 0 andalso 1/X > 0.1 -> ..
>
> the following expression would fail instead:
>
> foo(..) when X =/= 0, 1/X > 0.1 -> ..

Aye, but an exception in a guard test is always caught and
treated as if the test evaluated to "false". In this example,
there is no observable difference between the two.

   /Richard


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by whongo@gmail.com :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Jul 6, 3:25 pm, Roberto Ostinelli <robe...@...> wrote:

>
> 1> F3 = fun(X) when X=/=0 and (1/X > 0.1) -> true; (_) -> false end.
> #Fun<erl_eval.6.13229925>
> 2> [ F3(X) || X <- [0, 0.0, 0.1, 10, 9]].
> [false,false,false,false,false]

Ah, but that's because the expression (0 and (1/X > 0.1)) is bad.
(I've learned to be very afraid of how strongly 'and' binds. ;))

By contrast,

25> F4 = fun(X) when (X =/= 0) and (1/X > 0.1) -> true; (_) -> false
end.
#Fun<erl_eval.6.13229925>
26> [ F4(X) || X <- [0, 0.0, 0.1, 10, 9]].
[false,false,true,false,true]

And to iterate my previous point,

28> F5 = fun(X) when 1/X > 0.1 -> true; (_) -> false end.
#Fun<erl_eval.6.13229925>
29> [F5(X) || X <- [0, 0.0, 0.1, 10, 9]].
[false,false,true,false,true]


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: Re: comma vs andalso

by Roberto Ostinelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 06/lug/09, at 15:52, whongo@... wrote:
>
> Ah, but that's because the expression (0 and (1/X > 0.1)) is bad.
> (I've learned to be very afraid of how strongly 'and' binds. ;))

definitely interesting. i guess you've learned it the hard way :)

r.


Re: comma vs andalso

by Richard O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jul 7, 2009, at 12:19 AM, Roberto Ostinelli wrote:
> the difference is very simple. comma indicates that both guard  
> operators need to be evaluated, while on the contrary 'andalso'  
> means that the second condition is evaluated ONLY if condition1 is  
> true. same goes for 'orselse'.

He's wrong, but he's not _crazy_.
Section 6.24 of the reference manual _ought_ to explain this
clearly, but doesn't.

--------------------------
6.24 Guard Sequences
A guard sequence is a sequence of guards,
separated by semicolon (;).
The guard sequence is true if at least one of the guards is true.
(The remaining guards, if any, will not be evaluated.)
Guard1;...;GuardK

A guard is a sequence of guard expressions,
separated by comma (,).
The guard is true if all guard expressions evaluate to true.
GuardExpr1,...,GuardExprN

--------------------------
I propose rewriting these paragraphs something like this:

A guard sequence is a sequence (G1;...;Gk) of guards
separated by semicolons.  Guards are tested from left
to right.  If some guard succeeds, the guard sequence
as a whole succeeds, and the remaining guards will not
be checked.  If all guards fail, the guard sequence as
a whole fails.

A guard is a sequence (GE1,...,GEn) of guard
expressions separated by commas.  Guard expressions
are tested from left to right.  If some guard
expression fails, the guard as a whole fails, and the
remaining guard expressions will not be checked.  If
all guard expressions succeed, the guard as a whole
suceeds.

A guard expression is a very special restricted
expression.  It is said to succeed it it evaluates to
true.  It is said to fail if it evaluates to anything
else or raises an exceptions.  Exceptions never
propagate out of guard expressions, they are just taken
as lack of success.

(then continue with the existing third paragraph)



________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Andrew Thompson-15 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Jul 07, 2009 at 12:47:23PM +1200, Richard O'Keefe wrote:
>
> I propose rewriting these paragraphs something like this:

<snip>

I found your explanation a *lot* clearer and even learned something
reading it, so I'd definitely agree that it's an improvement.

I'm still unclear as to where 'andalso' differs from a comma though, how
is

true, false.

any different from

true andalso false.

Andrew

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Roberto Ostinelli :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 07/lug/2009, at 02.47, "Richard O'Keefe" <ok@...> wrote:

>
> On Jul 7, 2009, at 12:19 AM, Roberto Ostinelli wrote:
>> the difference is very simple. comma indicates that both guard  
>> operators need to be evaluated, while on the contrary 'andalso'  
>> means that the second condition is evaluated ONLY if condition1 is  
>> true. same goes for 'orselse'.
>
> He's wrong, but he's not _crazy_.
> Section 6.24 of the reference manual _ought_ to explain this
> clearly, but doesn't.

that is the paragraph i'd been referring to and apparently i had been  
interpreting it wrongly.

i thought this had already been cleared yesterday and yes, an editing  
as proposed would be a good thing, i might not be the only one doing so.

r.

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Richard O'Keefe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jul 7, 2009, at 4:16 PM, Andrew Thompson wrote:
> I found your explanation a *lot* clearer and even learned something
> reading it, so I'd definitely agree that it's an improvement.

Purr.

>
> I'm still unclear as to where 'andalso' differs from a comma though,  
> how
> is
>
> true, false.
>
> any different from
>
> true andalso false.

First, some historical background.
Erlang was influenced by Prolog via Strand-88.
(By the way, does anyone have a Strand manual they don't want?)
In Prolog, there is one and only one way to get and-then (,)
and one and only one way to get or-else (;).  To oversimplify,
     <disjunction> ::= <conjunction> {';' <conjunction>}...
     <conjunction> ::= <primary> {',' <primary>}...
     <primary>     ::= ['\+'] ( <call> | '(' <disjunction> ')' )
     <call>        ::= <atom>['(' <arguments> ')']
One of the things I've left out of that is infix, prefix, and
postfix operators.  So something like

        cousin_sibling_or_self(X, Y) :-
            ( father(X, P) ; mother(X, P) ),
             ( father(Y, Q) ; mother(Y, Q) ),
            ( father(P, G) ; mother(P, G) ),
            ( father(Q, G) ; mother(Q, G) ).

is possible, where "or" is nested inside "and".

Let's return to Erlang.

This syntax was adopted for Erlang guards, *ALMOST*.
(It was also adopted for Erlang function bodies, almost.
  The C-like use of comma in Erlang expressions is rooted
  in Prolog's comma, not C's.)
The *ALMOST* part is that Erlang does not allow nesting.
You cannot write

        f(X, Y) when (X == 1 ; X == 2), (Y == 1 ; Y == 2) ->

You aren't even allowed to write (GE1,GE2),GE3 but *must*
write GE1,GE2,GE3.  Nor may you write G1;(G2;G3).  Weird.
This has never made sense to me.  Such combinations are
perfectly meaningful, and allowing them would make the
definition of some guard macros considerably easier.

The obvious thing to do is to remove this arbitrary
restriction.

That's not the path Erlang took.  (Honestly, you couldn't
make this stuff up.)  Instead, *new* operators 'andalso'
and 'orelse' (copied from SML, which is a fine language
with some fine compilers) were added.

Most of the time, you can use 'andalso' and 'orelse' in
a guard, where you would have used ',' and ';'.  "Most of
the time" means "when under the normal rules of evaluation
you would certainly not have had an exception."

Let's take two apparently similar functions:

f(X) when is_atom(element(3, X)) ; true -> 42.

g(X) when is_atom(element(3, X)) orelse true -> 42.

By actual test, f(99) -> 42.
By actual test, g(99) -> a function_clause exception.

That is, in a guard, an expression using 'andalso' or
'orelse' is still an expression, and if an exception
occurs in the left-hand operand, the whole expression
is still skipped.

The thing is that 'andalso' and 'orelse' can be used in
any expression, not just guards.  Erlang is treating
them in guard expressions exactly the same way that it
treats them in any other expressions.  And that's
_different_ from the way ',' and ';' are treated when
there's an exception.

I conclude that
(1) you had best be EXTREMELY cautious about using 'andalso'
     and 'orelse' in guards; they are NOT drop-in replacements
     for ',' and ';', and
(2) it is long past time that Erlang allowed nested use of
     ',' and ';' in guards.






________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Alpar Juttner-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> I conclude that
> (1) you had best be EXTREMELY cautious about using 'andalso'
>      and 'orelse' in guards; they are NOT drop-in replacements
>      for ',' and ';', and
> (2) it is long past time that Erlang allowed nested use of
>      ',' and ';' in guards.

(3) this topic should be discussed in details (with examples) in the
doc.

Alpar



________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Thomas Lindgren :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message






----- Original Message ----

> From: Richard O'Keefe <ok@...>
>
> Let's take two apparently similar functions:
>
> f(X) when is_atom(element(3, X)) ; true -> 42.
>
> g(X) when is_atom(element(3, X)) orelse true -> 42.
>
> By actual test, f(99) -> 42.
> By actual test, g(99) -> a function_clause exception.
>
> That is, in a guard, an expression using 'andalso' or
> 'orelse' is still an expression, and if an exception
> occurs in the left-hand operand, the whole expression
> is still skipped.
....
> I conclude that
> (1) you had best be EXTREMELY cautious about using 'andalso'
>     and 'orelse' in guards; they are NOT drop-in replacements
>     for ',' and ';', and
> (2) it is long past time that Erlang allowed nested use of
>     ',' and ';' in guards.


Guards are an awful mess in Erlang. I'd be quite surprised if the above difference in behaviour was intentional. If so, what possible purpose does it serve?

At one point, you could also use "and"/"or", the boolean operators manque, in guards. (I haven't checked recently whether this is still the case.) So we then have three very similar sets of guard operators.

Not to mention the twin set of type tests, introduced, as far as I know, to get rid of the lone double entendre of float/1 (as a test or conversion not the most frequent of operations). And now, for our convenience, the shorter form of these tests is being deprecated. Sigh.

Best,
Thomas



     


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Lindgren wrote:
> ----- Original Message ----
>> From: Richard O'Keefe <ok@...>
>> That is, in a guard, an expression using 'andalso' or 'orelse' is
>> still an expression, and if an exception occurs in the left-hand
>> operand, the whole expression is still skipped.
>
> Guards are an awful mess in Erlang. I'd be quite surprised if the
> above difference in behaviour was intentional. If so, what possible
> purpose does it serve?

It is intentional in the respect that 'andalso'/'orelse' behave just
like any other operator in a guard test. As for purpose, all Erlang's
operators are allowed in guard expressions, so why make an exception?

> At one point, you could also use "and"/"or", the boolean operators
> manque, in guards. (I haven't checked recently whether this is still
> the case.) So we then have three very similar sets of guard
> operators.

'and'/'or' have always (as far back as I can remember, anyway) been
allowed in guards, again, probably simply by virtue of being general
operators in the language. And they don't behave like ','/';' either.
So to add to Richard O'Keefe's examples:

 h(X) when is_atom(element(3, X)) or true -> 42.

which for h(99) behaves just like the orelse version, i.e., throws
a function_clause error. Quite simply, and/or/andalso/orelse behave
just like +, ==, or any other operator; compare e.g.:

 i(X) when is_atom(element(3, X)) == true -> 42.

> Not to mention the twin set of type tests, introduced, as far as I
> know, to get rid of the lone double entendre of float/1 (as a test or
> conversion not the most frequent of operations).

That was one details, yes, but the main reason was to make it possible
to refactor a piece of code without being forced to change the names
of the function tests if you moved an expression from within a guard
to an ordinary expression and vice versa. Recall that before the is_...
versions, there was no way of saying e.g., "Bool = (is_integer(X) and
is_atom(Y))" without writing a case/if or a separate predicate function.

The old type tests didn't correspond to any built-in functions, so you
had to treat them as "primops" inside the compiler, you couldn't refer
to them and pass them around, etc. But the old type test names "atom(X)"
and so forth could not simply be made to work outside guards because
there would be name clashes (with the float(X) bif and with any existing
code that defined a function such as list(X) or integer(X)), hence the
is_... prefix for the generally usable versions that are proper built-in
functions (defined in the 'erlang' module along with all the others).

Now that we have the new is_-forms, the old forms are merely an obstacle
to refactoring. As a simple example, this macro nowadays works in both
guard expressions and in general expressions - it didn't back then:

  -define(is_a_foo(X), (is_integer(X) or is_binary(X))).

(we can even use orelse here, and it will still work in a guard).

> And now, for our convenience, the shorter form of these tests is being
> deprecated.

Hold your horses - nobody is deprecating the use of ',' and ';'. But
as Richard O'Keefe has rightly described, they *are* different from
the plain boolean operators.

A guard has the following general form:

  ... when  *, ..., *  ;  *, ..., *  ;  ...  ->

that is, one or more semicolon-separated alternatives, each consisting
of one or more comma-separated _tests_ (marked with a * here). Each test
is (conceptually) evaluated in a try/catch that simply transforms any
exception into 'false'. (Subexpressions of a test are evaluated as
normal, which is why 'orelse' does not continue executing if there
is an exception in the left-hand expression.) This fail-to-false
behaviour was in my opinion a mistake, because it occasionally hides
a bug in the guard and turns what should have been an observable runtime
crash into a silent "well, we take the next clause then". Some people
like to use this as a trick to write more compact guards, but that
makes it hard for someone reading the code to tell whether the
crash-jumps-to-the-next-case is intentional or not.

However, Erlang seems to be stuck with these semantics of guards. But
it means that if you do things inside your guard test like element(N,T),
length(Xs), or anything else that could crash if it gets bad arguments,
you need to think about the effect on what clause, if any, will be
selected. The thing to remember is that exceptions always stop at the
top of each separate test in the guard. Complicated expressions that
might throw an unwanted exception are generally better evaluated before
the switch, so that bugs are not hidden.

I'm not sure I have any real arguments against nesting of ','/';',
but I fear the grammar could get rather messy, and that such nested
guards could be quite difficult to read in practice.

    /Richard

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Richard Carlsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Lindgren wrote:
> Not to mention the twin set of type tests, introduced, as far as I
> know, to get rid of the lone double entendre of float/1 (as a test or
> conversion not the most frequent of operations). And now, for our
> convenience, the shorter form of these tests is being deprecated.
> Sigh.

Oh, and I forgot this beauty, which is a consequence of the
doubleplusweird scope rules for the old type tests in guards:

  1> if integer(42) -> ok; true -> no end.
  ok
  2> if integer(42) == true -> ok; true -> no end.
  * 1: illegal guard expression

because, you see, it is only at the absolute top of the guard test
that the name 'integer(X)' can be used to refer to the type test.
Shove it into one side of an '==', and it is no longer recognized.
The new forms work everywhere:

  3> if is_integer(42) == true -> ok; true -> no end.
  ok
  4> if is_integer(42) == true -> ok; true -> no end.
  ok

And for my final trick, here's the old double entendre you mentioned:

  5> if float(3.14) -> ok; true -> no end.
  ok
  6> if float(3.14) == true -> ok; true -> no end.
  no

why, isn't it obvious? The first clause uses the type test float(X),
while the second ensures that 3.14 is cast to a float and then
compares the number to 'true'.

Sticking to the modern is_-forms of the type tests lets you stay sane.

    /Richard

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: comma vs andalso

by Robert Virding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/7/8 Richard Carlsson <richardc@...>

> Thomas Lindgren wrote:
> > Not to mention the twin set of type tests, introduced, as far as I
> > know, to get rid of the lone double entendre of float/1 (as a test or
> > conversion not the most frequent of operations). And now, for our
> > convenience, the shorter form of these tests is being deprecated.
> > Sigh.
>
> Oh, and I forgot this beauty, which is a consequence of the
> doubleplusweird scope rules for the old type tests in guards:
>
>  1> if integer(42) -> ok; true -> no end.
>  ok
>  2> if integer(42) == true -> ok; true -> no end.
>  * 1: illegal guard expression
>
> because, you see, it is only at the absolute top of the guard test
> that the name 'integer(X)' can be used to refer to the type test.
> Shove it into one side of an '==', and it is no longer recognized.


It has nothing to do with scope rules really. In the original guards only
simple tests were allowed so there was no problem. It only became weird when
expressions were allowed.

Life was simpler in the old days! :-)

Robert
< Prev | 1 - 2 | Next >