[erlang-questions] illegal guard expression for IF illegal guard expression for "if"

Barco You barcojie@REDACTED
Mon Dec 5 02:44:56 CET 2011


Hi Ulf,

Thank you a lot for your insightful explanation!


BRs,
Barco

On Sun, Dec 4, 2011 at 5:17 PM, Ulf Wiger <ulf@REDACTED> wrote:

> You should see guards as an extension of pattern matching.
>
> If a guard function would have side-effects, the overall evaluation would
> most likely not be deterministic, and - most importantly perhaps - would be
> extremely difficult to understand and reason about. Ideally, the function
> should also be O(1), although a few O(N) guards, like length/1, are also
> allowed. For this reason, programmers can normally regard pattern-matching
> as extremely efficient, and use it extensively, trusting that the compiler
> will do a good job optimizing it.
>
> It is correct that the compiler is not able to determine, at present,
> whether a function is referentially transparent. It also cannot determine
> the complexity of a function.
>
> BR,
> Ulf W
>
> On 4 Dec 2011, at 09:51, Barco You wrote:
>
> But, if explaining in this way it has nothing to do with side-effect. It's
> just because the guard expression is stochastic rather than deterministic.
>
> If having a deterministic function in the 'if' guard expression, we still
> get 'illegal guard expression'. According to the document provided by some
> guys in previous mails, the foundamental reason is that the erlang VM does
> not make sure whether a function in the guard expression has side-effect.
>
> So, I hope to know why functions with side-effect can not be the guard
> expression.
>
> Thank you all!
> Barco
> On Dec 2, 2011 10:42 PM, "Barco You" <barcojie@REDACTED> wrote:
>
>> Ooooh! Maybe I understand now!
>>
>> It means that if the first branch is not satisfied, saying get 0.7, then
>> random:uniform() would be evaluated again in the second branch and it
>> possible to get a value less than 0.5, which then makes a paradox. Right?
>>
>> In the contrast, with case statement, the condition is only evaluated
>> once no matter whichever branch would be satisfied.
>>
>> How smart erlang is, and how amazing you erlangers are!
>>
>> Barco
>> On Dec 2, 2011 6:18 PM, "CGS" <cgsmcmlxxv@REDACTED> wrote:
>>
>>> **
>>> Just to make it clearer:
>>>
>>> The second condition is equivalent with the expression: "if the value of
>>> random:uniform() is greater or equal to 0.5 then report 'bad'". In this
>>> case, if you entered with value 0.4 in the first branch and modified it to
>>> 0.7 in the first branch, the second branch should be executed as well. That
>>> is against the if statement purpose which should report only one branch at
>>> the time as valid. Therefore, Erlang requires for the compared values to be
>>> constant during the if statement processing.
>>>
>>> CGS
>>>
>>>
>>>
>>> On 12/02/2011 11:06 AM, CGS wrote:
>>>
>>> If statement is not a block statement (to fix the variables values at
>>> the entrance of the statement) in Erlang. That means, if an
>>> uniform:random() value (say, 0.4) is used for checking the first branch
>>> condition and the value is changed within the branch (say, 0.7), then you
>>> enter a paradox related to if the function should be considered for the
>>> first or the second branch. To avoid this, Erlang requires an assurance
>>> that the compared values do not change while processing the if statement.
>>>
>>> CGS
>>>
>>>
>>>
>>> On 12/02/2011 10:56 AM, Barco You wrote:
>>>
>>> Hi CGS,
>>>
>>>  I can't understand your statement --- " if in the first branch you use
>>> again random:uniform(), the second branch condition can report an
>>> inaccurate result."  Could you please make it clearer? Thanks!
>>>
>>>  Hi Others,
>>>
>>>  Why functions with side effect can not be in the guard expressions?
>>>
>>>
>>>  Thank you!
>>> Barco
>>>
>>>  On Fri, Dec 2, 2011 at 5:50 PM, CGS <cgsmcmlxxv@REDACTED> wrote:
>>>
>>>>  Hi,
>>>>
>>>> To put in simple words for better understanding, you can have only
>>>> constant variables withing the guard expression. That means, in your case,
>>>> if in the first branch you use again random:uniform(), the second branch
>>>> condition can report an inaccurate result.
>>>>
>>>> Alternatively, you can use case statement:
>>>>
>>>> case (random:uniform()<0.5) of
>>>>      true -> good;
>>>>      false -> bad
>>>> end
>>>>
>>>> I hope this answer will help you.
>>>>
>>>> CGS
>>>>
>>>>
>>>>
>>>>
>>>> On 12/02/2011 10:30 AM, Barco You wrote:
>>>>
>>>>  Why does the following expression got "illegal guard expression" when
>>>> compiling:
>>>> X = 0.5,
>>>> if
>>>>     random:uniform() < X ->      %error reported for this line
>>>>            good;
>>>>     true ->
>>>>            bad
>>>> end.
>>>>
>>>>  But if I change it to following expression, it's ok:
>>>>  X = 0.5,
>>>> Ran = random:uniform(),
>>>> if
>>>>      Ran < X ->
>>>>            good;
>>>>     true ->
>>>>            bad
>>>> end.
>>>>
>>>>  BRs,
>>>> Barco
>>>>
>>>>
>>>> _______________________________________________
>>>> erlang-questions mailing listerlang-questions@REDACTED://erlang.org/mailman/listinfo/erlang-questions
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> 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/20111205/46c099be/attachment.htm>


More information about the erlang-questions mailing list