[Erlang0048] Erlang guard

Source: Internet
Author: User
In [Erlang 0009] Erlang 30th, I mentioned a small trap about the if statement:
30. If statements will catch the guard clause, so if 1/0-> A; true-> B end. Returns B rather than throwing an exception.
Don't believe it? Open Erlang shell and drill down to see:
Eshell V5.9  (abort with ^G)
1> F = fun(X) -> if 1/0 -> a; true -> b end end.
#Fun<erl_eval.6.111823515>
2> F(1).
b
3> G=1/0 , if G->a; true ->b end.
** exception error: bad argument in an arithmetic expression
in operator '/'/2
called as 1 / 0
The third statement above provides a response policy, that is, place the condition calculation outside the if clause, so that an exception will be thrown out, it will not enter the unexpected logical branch in case of exceptions;
Why is there such a result? The official Erlang documentation says the following is true:

If
Guardseq1->
Body1;
...;
Guardseqn->
Bodyn
End

The branches of an IF-expression are scanned sequentially until a guard sequence guardseq which evaluates to true is found. Then the corresponding body (sequence of expressions separated by ',') is evaluated.

If expression execution scans guard clauses one by one until the calculation result is true. The execution result of 1/0 in the preceding special case is an exception, Not true, The exception here is only treated as a special return value, so it will continue to scan the subsequent GuardClause! The problem is not complete yet. On the Erlang Learning Website learn you some Erlang, when talking about guard, the author made a special note:

Note:I 've compared,And;In guards to the operatorsandalsoAndorelse. They're not exactly the same, though. the former pair will catch exceptions as they happen while the latter won't. what this means is that if there is an error thrown in the first part of the guardX >= N; N >= 0, The second part can still be evaluated and the guard might succeed; if an error was thrown in the first partX >= N orelse N >= 0, The second part will also be skipped and the whole guard will fail.

However (there is always a 'however '), only andalsoAnd orelseCan be nested inside guards. This means (A orelse B) andalso CIs a valid guard, while (A; B), CIs not. Given their different use, the best strategy is often to mix them as necessary.
Traceback: http://learnyousomeerlang.com/syntax-in-functions#guards-guards
I think the author's understanding here is biased. ,;And andalso orelse think of things at the same level, compare their similarities and differences, and draw a conclusion: the former will do exception capture the latter will not, that is, when x> = N; if the first half of the expression is abnormal, the operation is performed on the second half; if the first half of x> = n orelse n> 0 is abnormal, the latter part is skipped. the author summarizes that andalso orelse can be nested in guard, ,;No. What are their hierarchies? See the figure below:

Is to reorganize the expression of the official document

AGuard SequenceIs 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

AGuardIs a sequence of guard expressions, separated by comma (,). The guard is true if all guard expressions evaluate to true.
Guardexpr1,..., guardexprn

The set of validGuard expressions(Sometimes called guard tests) is a subset of the set of valid Erlang expressions. the reason for restricting the set of valid expressions is that evaluation of a guard expression must be guaranteed to be free of side effects. valid guard expressions are:

  • The atom true,
  • Other constants (terms and bound variables), all regarded as false,
  • Callto the BIFS specified below,
  • Term comparisons,
  • Arithmetic expressions,
  • Boolean expressions, and
  • Short-circuit expressions (andalso/orelse ).
Traceback: http://www.erlang.org/doc/reference_manual/expressions.html#id79005 that is Guard SequenceIs contains multiple guard clauses. Guard clauses are separated by semicolons. As long as one of the guard clauses returns true, the value of this expression is true, and subsequent clauses are not executed; the guard clause contains several Guard expressionsWhen all expressions return true, guard returns true. Valid guard expressions in Erlang include short-circuit judgment expressions short-circuit (andalso/orelse ). the author's conclusion is correct, but the guard clause separator, expression separator, short-circuit judgment statement are confused. I will send an email to the author to correct it. through email communication, I understand why the author wants to do this: learn you some Erlang is positioned to make learning Erlang interesting, easy to understand, and reduce the learning curve. the intuitive description may be better than the strict description. The author replies as follows:
Ah, I understand what you mean, you're right there. if lyse were to be more of a reference manual, I wocould definitely update the definition to reflect this. however, I feel it might be going against the tone to go with such strict definitions. I made the same choice when it came to explaining that 'functions end in. and that module attributes do the same. I cocould have used the broader distinction between forms and expressions, that ', 'Act As expression separators,'; 'Act As branch separators, And that '. 'terminate forms (do not separate them), but that the Erlang shell breaks the rules by using '. as a way to end expressions, which isn't valid by the modules 'Definitions. however, while the strict definition is 100% true, It isn' t the easiest thing when it comes to learning, in my opinion. my definition wouldn't work for someone writing a parser, and it wouldn't work for someone who wants to understand the absolute truth about the language, I however feel it helps in understanding the concept of guards when you have never encountered it before. it's a bit how we coshould teach children that PI is '3. 1416 'and let them use this as a notion; they need not to know that PI is irrational, that it has an infinite amount of digits, etc. you may disagree with me on the approach, but I do believe it works rather well. by the way, thanks for writing me about this I'm enjoying the discussion. regards, Fred.
Here, we will understand that it is not a small trap of the IF statement but a guard design. Let's look at the example below: F = fun (x) When 1/0-> X; (x) when x> 0-> X end. there is an obvious exception in the first clause of this fun method. What is the execution result of this method? Note that this is also guard!
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.