[erlang-questions] difference between ", " and "andalso" in guards

Thomas Lindgren thomasl_erlang@REDACTED
Mon May 19 15:47:54 CEST 2014


I've heard this explanation before, and it probably explains how it's implemented, but I think it easily leads to confusion. (Much like the rest of Erlang's booleans, unfortunately.) 

I'd prefer this, which perhaps should be an EEP: 

Define guards as (restricted) boolean expressions connected by "," and ";". Disjunctions ";" should furthermore be permitted to be nested with conjunctions ",", which I believe is not the case today. The boolean expressions are known as tests (e.g., "is_integer(X)" or "length(hd(A)) > 0" and are taken from the currently well-known collection of guard tests.

So, the guard grammar is this:

G ::= G1, G2 | G1 ; G2 | T

where T is a test. Conjunction binds tighter than disjunction and both are associative, so the syntax is nearly the same as what we have today. As an example, and in contrast with today, "G1, (G2 ; G3), G4" is a valid guard if G1 to G4 are valid guards (which may themselves contain "," and ";" if so desired).

Conjunction "," means logical AND, while disjunction ";" means logical OR. AND/OR are lazily evaluated left to right. Thus, in the grammar above, G1 is evaluated before G2, and G2 is not evaluated unless required. 

Tests T that fail/crash or do not return a boolean are treated as if they evaluate to false. (Subexpressions can of course evaluate to non-booleans. If a subexpression crashes during evaluation, the whole test fails.) 


Finally, if the guard of a clause evaluates to false, the clause head fails and evaluation moves on to try to match the next clause.

In this approach, andalso/orelse/and/or can possibly be permitted as tests (or subexpressions of tests), but I'd suggest to not allow them in guard contexts since they lead to the (needless) ambiguities discussed above.

(Other connectives like negation and implication could also be allowed, as well as more powerful tests, but I'll leave that for future work.)

Best,
Thomas
On Monday, May 19, 2014 10:33 AM, Håkan Huss <huss01@REDACTED> wrote:
 

>
>
>Isn't the easiest way to explain the difference between E1; E2 and E1 orelse E2 is that the former is two guards combined with ; while the latter is one guard containing an orelse operator. If E1 would give an exception, E1 fails in the first case, and the next guard is evaluated. In the second case, if E1 would give an exception the (only) guard fails.
>
>/Håkan
>
>
>
>
>2014-05-19 2:59 GMT+02:00 Fred Hebert <mononcqc@REDACTED>:
>
>On 05/19, Richard A. O'Keefe wrote:
>>>
>>>
>>> This is seriously misleading.
>>>
>>> The difference between  X > Y , X < Z
>>> and X > Y andalso X < Z
>>> with respect to exceptions has NOTHING TO DO with whether
>>> it's comma or andalso.  The right semantic model is that
>>> it is the tests X > Y and X < Z themselves which change.
>>> If a guard test would have raised an exception, that
>>> turns into a simple failure of the guard test.
>>>
>>> Example:
>>>
>>> 1> F1 = fun (X) when X+1 > 2 -> ok ; (_) -> oops end.
>>> 2> F2 = fun (X) -> B = (X + 1 > 2), if B -> ok ; true -> oops end end.
>>> 3> F1(snark).
>>> oops
>>> 4> F2(snark).
>>> ** exited: {badarith,...} **
>>>
>>> This being so, "," never gets to *see* an exception,
>>> so how could it catch one?
>>>
>>> You can't verify Fred's statement, because it isn't true.
>>> "," and ";" no more catch exceptions than "->" does.
>>>
>>
>>There is no practical difference between ',' and 'andalso' in any way,
>>because as you mentioned, an exception would turn into a failure of the
>>guard test no matter which one is used. This would be the same no matter
>>what the implementation as far as I can tell.
>>
>>For ';' and 'orelse', there is a practical difference. They don't
>>properly 'catch' exceptions, but when learning Erlang I've found the
>>explanation I used in LYSE useful and practically applicable (which is
>>why I put it in the book).
>>
>>Of course you can look at the assembler or even at the result of fun2ms
>>to see an example of the practical difference:
>>
>>1> ets:fun2ms(fun(X) when hd(X) > 0 orelse true -> ok end).
>>[{'$1',[{'orelse',{'>',{hd,'$1'},0},true}],[ok]}]
>>2> ets:fun2ms(fun(X) when hd(X) > 0; true -> ok end).
>>[{'$1',[{'>',{hd,'$1'},0}],[ok]},
>> {'$1',[true],[ok]}]
>>
>>Showing an example interpretation where the clauses are entirely
>>disjoint and more equivalent to two different function clauses than a
>>logical operator when observed that way. The same way calling the
>>function:
>>
>>f([]) -> a;
>>f(_) -> b.
>>
>>as f([]) doesn't result in the first clause 'catching' a badmatch
>>exception, the ';' doesn't end up catching exceptions either. It's just
>>that I personally found the simple rule I put in LYSE to be good enough
>>and understandable.
>>
>>The other comparison point I used in the text was 'nesting' with
>>parentheses:
>>
>>> However (there is always a 'however'), only andalso and orelse can be
>>> nested inside guards. This means (A orelse B) andalso C is a valid
>>> guard, while (A; B), C is not. Given their different use, the best
>>> strategy is often to mix them as necessary.
>>
>>I believe I ended up grouping ',' and ';', 'andalso' and 'orelse', and
>>'and' and 'or' (that's a confusing sentence) in the explanations of this
>>chapter because they just fit well together in pairs. That did end up
>>suggesting ',' catches exceptions, while it clearly shouldn't.
>>
>>People are of course free to question the method I used there and to
>>disagree with it. I won't be debating it in much detail because, as I
>>said, I felt entirely satisfied with the method I used to explain it,
>>and felt it is more easily understandable than going into the details of
>>how everything gets compiled lower down.
>>
>>LYSE probably papers over a lot of issues in that manner, especially in
>>the earlier chapters. That's both a result of me writing the book as the
>>entire learning experience was still fresh in my mind (and I reported
>>things as they made sense to me back then), and not wanting to get into
>>details before people are even able to compile code.
>>
>>I'm hoping, for the benefit of their own learning experience, that
>>readers who feel like getting a more formal approach to learning Erlang
>>likely wouldn't pick the book with the weird squid and badly written
>>title over the other alternatives. Hopefully I can't be accused of false
>>representation on the book's cover and tone.
>>
>>I'm also hoping people are generally satisfied with LYSE, but of course,
>>there's no guarantee, and the errata of the book[1] only proves I am able
>>to make a ton of mistakes.
>>
>>Regards,
>>Fred.
>>
>>[1] http://www.nostarch.com/erlang#updates (click on 'show updates')
>>
>>_______________________________________________
>>erlang-questions mailing list
>>erlang-questions@REDACTED
>>http://erlang.org/mailman/listinfo/erlang-questions
>>
>
>
>_______________________________________________
>erlang-questions mailing list
>erlang-questions@REDACTED
>http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140519/523fd7dd/attachment.htm>


More information about the erlang-questions mailing list