2008/5/15 David Mercer <<a href="mailto:dmercer@gmail.com" target="_blank">dmercer@gmail.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;">


<div>> The main snag is that the rules for both syntax and semantics of<br>
> guards is subtly different from those of normal expressions, so<br>
> it's hard to extend what you can write in an if-guard in a way that<br>
> does not change the behaviour anywhere in all the existing code.<br>
<br>
</div>What are the subtle differences?  I suspect most new users do not completely<br>
grok that, since this subject comes up repeatedly.</blockquote><div><br>There are 2 differences between guards and normal expressions:<br><br>1. The most obvious: guards are restricted to using a subset of BIFs. Basically those that are side-effect free. This is both easy and difficult to understand. Easy, because you can read in the manual which ones are allowed, difficult because it may not be obvious why only a restricted subset is allowed.<br>


<br>2. The more subtle difference is handling of errors. In a "normal" expression, even ones only using the guard subset, an error generates an error which crashes the process if not caught in some way. In a guard, however, no error is generated, the only result is that the guard fails and the next if/case/receive clause is tried.<br>


<br>This means that the following are *NOT* equivalent:<br><br>    if  5 * X > 39 -> ... ;<br>        true -> ...<br>    end<br><br>    case 5 * X > 39 of<br>        true -> ... ;<br>        false -> ...<br>


    end<br><br>Assume X is not a number. In the 'if' case then all that will happen is that the if test, a guard, will fail and the second clause will be chosen as the test in an if is a guard. In the 'case' case, however, an error will be generated and neither case chosen.<br>


<br>A normal expression has two outcomes: it can succeed and return a value or it can generate an error. A guard (expression) has 3 outcomes: it return true (succeed), it return false (fail) or it can generate an error. BUT for a guard generating an error results in the guard failing, i.e. it is equivalent to it returning false.<br>


<br>This was done to make the testing easier and remove obvious explicit type tests. As guards originally were just flat sequences of simple tests this caused no real logical problem. When guards were extended to be a sequence of guards, separated by ';', an error now caused that guard in the sequence to fail leading to testing the next sequence. As guards were still flat sequences of simple tests it was still easy to comprehend.<br>
<br>Now guards can be full boolean expressions and it is not quite so clear how errors in guards should be handled. How far do you go up before returning false? The actual operation which caused the error? Up to the next boolean operator and return false to it? All the way? What is done is the same as before, an error fails that guard in the guard sequence.<br>
<br>This answer became a little longer than I had anticipated but I hope things are a little clearer now.<br><br>Robert<br><br></div></div>