<div dir="ltr">The boolean operators and, or, xor and not are the originals and evaluate all their arguments, they have never been short circuiting, and are like the bitwise C operators. Orelse and andalso came much later.<br>
<br>2008/7/21 Thomas Lindgren <<a href="mailto:thomasl_erlang@yahoo.com">thomasl_erlang@yahoo.com</a>>:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I normally agree with those recommendations, but with a couple of caveats:<br>
<br>
1. You can't nest ';', but you can nest orelse. This can be useful for macros and suchlike.<br>
<br>
2. I seem to recall that ';' is implemented by duplicating the clauses, while andalso/orelse is not. If so, andalso/orelse _may_ yield somewhat more compact code.<br>
<br>
Both of these properties are basically accidents of history (ie, hacks that have been cast in stone).</blockquote><div><br>Yes, you have to go back in history to see why guards are what they are.<br><br>Guards were originally meant to be just simple tests which were
considered part of the pattern matching process but were clearer and
simpler to write outside the actual pattern. They came directly from
the guards occurring in the flat concurrent logic languages.<br>
<br>
Originally guards were a sequence of simple tests, a guard sequence, which could either succeed or fail. An exception in a guard test was made to be equivalent to failure of the test to make the guards simpler and shorter. With these original guards the order of evaluation *was*  irrelevant but the compiler did them left to right.<br>
<br>    when test1, test2, ... -><br><br>Then their came a request to have alternate guards for the same head and body. To do this guards were extended to be a set of alternate guard sequences separated by ';'. The semantics were the same within each guard sequence. The sequences were evaluated from left to right, if a sequence failed then the next one was tried. An exception was equivalent to failure as before but the only led to that sequence failing, not the whole guard. This was consistent with other uses of ';' as separator.<br>
<br>    when guard_seq1 ; guard_seq2 ; ... -> ..<br><br>Guard tests were still quite different semantically from "normal" expressions and it was not too different to *see* the difference.<br><br>Finally guards were extended to be full boolean expressions, more or less. While this made them more useful in some ways it also made them much more difficult and confusing. As well as making them look more like "normal" expressions which they still aren't.<br>
<br> There is no problem with code duplication when using ';'.<br><br>Robert<br><br></div></div></div>