Guards?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Guards?

Roberto Ostinelli
All,
I'm a little stumped and I feel I'm missing something sooooooo beginner here.

1> F = fun(X) when (is_integer(X) or is_float(X)) and X < 5 -> ok end.
#Fun<erl_eval.6.50752066>
2> F(1).
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(1) 
3> F2 = fun(X) when (is_integer(X) or is_float(X)) and (X < 5) -> ok end.
#Fun<erl_eval.6.50752066>
4> F2(1).
ok

...Can some kind soul clarify?

Thank you,
r.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Bengt Kleberg
For F, did you mean:
((is_integer(X) or is_float(X)) and X) < 5

On 04/05/2016 02:27 PM, Roberto Ostinelli wrote:
All,
I'm a little stumped and I feel I'm missing something sooooooo beginner here.

1> F = fun(X) when (is_integer(X) or is_float(X)) and X < 5 -> ok end.
#Fun<erl_eval.6.50752066>
2> F(1).
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(1) 
3> F2 = fun(X) when (is_integer(X) or is_float(X)) and (X < 5) -> ok end.
#Fun<erl_eval.6.50752066>
4> F2(1).
ok

...Can some kind soul clarify?

Thank you,
r.



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Roberto Ostinelli


On Tue, Apr 5, 2016 at 2:30 PM, Bengt Kleberg <[hidden email]> wrote:
For F, did you mean:
((is_integer(X) or is_float(X)) and X) < 5

Not really, no :)

1> F = fun(X) when ((is_integer(X) or is_float(X)) and X) < 5 -> ok end.
#Fun<erl_eval.6.50752066>
13> F(1).
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(1) 


 

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Kostis Sagonas-2
In reply to this post by Roberto Ostinelli
On 04/05/2016 02:27 PM, Roberto Ostinelli wrote:

> I'm a little stumped and I feel I'm missing something sooooooo beginner
> here.
>
> 1> F = fun(X) when (is_integer(X) or is_float(X)) and X < 5 -> ok end.
> #Fun<erl_eval.6.50752066>
> 2> F(1).
> ** exception error: no function clause matching
> erl_eval:'-inside-an-interpreted-fun-'(1)
> 3> F2 = fun(X) when (is_integer(X) or is_float(X)) and (X < 5) -> ok end.
> #Fun<erl_eval.6.50752066>
> 4> F2(1).
> ok
>
> ...Can some kind soul clarify?

It's a long story.  Its short version is that you will have a much
better state of mind if you forget the presence of 'or' and 'and' in
guards and use ';' and ',' when you can, and 'orelse' and 'andalso' when
you cannot (as in your F fun).

1> F = fun(X) when (is_integer(X) orelse is_float(X)) andalso X < 5 ->
ok enD.
#Fun<erl_eval.6.50752066>
2> F(1).
ok


Kostis
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Douglas Rohrer
What you're missing is operator precedence [1] - "and" takes precedence over "<", so your guard clause ends up looking, to the runtime, like what Bengt pointed out - you have the boolean expression `is_inteteger(X) or is_float(X)` followed by and, followed by X - which is evaluated before the < operator. The evaluation of your guard looks something like this:

X = 1
(((is_integer(1) or is_float(1)) and 1) < 5

(((true) and 1) < 5)

`true and 1` cannot be evaluated (throws an exception, as `and` doesn't take integer arguments). Now, your guard expression threw an exception - what happens then:

"If an arithmetic expression, a Boolean expression, a short-circuit expression, or a call to a guard BIF fails (because of invalid arguments), the entire guard fails. If the guard was part of a guard sequence, the next guard in the sequence (that is, the guard following the next semicolon) is evaluated." [2]

So, your guard ends up not matching - you have no other function clauses, so you have "no function clause matching."

Make sense now?

Doug


On Apr 5, 2016, at 8:38 AM, Kostis Sagonas <[hidden email]> wrote:

On 04/05/2016 02:27 PM, Roberto Ostinelli wrote:
I'm a little stumped and I feel I'm missing something sooooooo beginner
here.

1> F = fun(X) when (is_integer(X) or is_float(X)) and X < 5 -> ok end.
#Fun<erl_eval.6.50752066>
2> F(1).
** exception error: no function clause matching
erl_eval:'-inside-an-interpreted-fun-'(1)
3> F2 = fun(X) when (is_integer(X) or is_float(X)) and (X < 5) -> ok end.
#Fun<erl_eval.6.50752066>
4> F2(1).
ok

...Can some kind soul clarify?

It's a long story.  Its short version is that you will have a much better state of mind if you forget the presence of 'or' and 'and' in guards and use ';' and ',' when you can, and 'orelse' and 'andalso' when you cannot (as in your F fun).

1> F = fun(X) when (is_integer(X) orelse is_float(X)) andalso X < 5 -> ok enD.
#Fun<erl_eval.6.50752066>
2> F(1).
ok


Kostis
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Roger Lipscombe-2
In reply to this post by Roberto Ostinelli
That gets parsed as:

F = fun(X) when ((is_integer(X) or is_float(X)) and X) < 5 -> ok end.

You can check by looking at the output of erlang:fun_info(F), which
shows the parse tree for the guard condition.

On 5 April 2016 at 13:27, Roberto Ostinelli <[hidden email]> wrote:

> All,
> I'm a little stumped and I feel I'm missing something sooooooo beginner
> here.
>
> 1> F = fun(X) when (is_integer(X) or is_float(X)) and X < 5 -> ok end.
> #Fun<erl_eval.6.50752066>
> 2> F(1).
> ** exception error: no function clause matching
> erl_eval:'-inside-an-interpreted-fun-'(1)
> 3> F2 = fun(X) when (is_integer(X) or is_float(X)) and (X < 5) -> ok end.
> #Fun<erl_eval.6.50752066>
> 4> F2(1).
> ok
>
> ...Can some kind soul clarify?
>
> Thank you,
> r.
>
>
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Roberto Ostinelli
In reply to this post by Douglas Rohrer

What you're missing is operator precedence [1] - "and" takes precedence over "<", so your guard clause ends up looking, to the runtime, like what Bengt pointed out - you have the boolean expression `is_inteteger(X) or is_float(X)` followed by and, followed by X - which is evaluated before the < operator. The evaluation of your guard looks something like this:

X = 1
(((is_integer(1) or is_float(1)) and 1) < 5

(((true) and 1) < 5)

`true and 1` cannot be evaluated (throws an exception, as `and` doesn't take integer arguments). Now, your guard expression threw an exception - what happens then:

"If an arithmetic expression, a Boolean expression, a short-circuit expression, or a call to a guard BIF fails (because of invalid arguments), the entire guard fails. If the guard was part of a guard sequence, the next guard in the sequence (that is, the guard following the next semicolon) is evaluated." [2]

So, your guard ends up not matching - you have no other function clauses, so you have "no function clause matching."

Make sense now?

Doug

Thank you Doug. Yes - it makes sense. However operator precedence, which I previously checked, do not specify and & or:

Therefore I assumed precedence was the same, and that is confusing. 


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Roberto Ostinelli
Thank you Doug. Yes - it makes sense. However operator precedence, which I previously checked, do not specify and & or:

Scratch that. Going to get a coffee. ^^_ 

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Douglas Rohrer
I had the same reaction when I first scanned that table - and coffee is a good idea.

Glad you got it worked out.

Doug


On Tue, Apr 5, 2016 at 9:07 AM Roberto Ostinelli <[hidden email]> wrote:
Thank you Doug. Yes - it makes sense. However operator precedence, which I previously checked, do not specify and & or:

Scratch that. Going to get a coffee. ^^_ 

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Guards?

Richard A. O'Keefe-2
In reply to this post by Roberto Ostinelli
Thank you Doug. Yes - it makes sense. However operator precedence, which
I previously checked, do not specify and & or:
> http://erlang.org/doc/reference_manual/expressions.html#prec

Actually, that section of the reference manual DOES specify 'and' and 'or'.
They are right there in the 4th and 5th rows of table 8.6.

/ * div rem band AND
+ - bor bxor bsl bsr OR xor

This makes no sense to me.  I mean, it REALLY makes no sense.
'and' and 'or' are for combining "boolean" values.
The way to *get* boolean values is to do a comparison.
What would have made *sense* would have been to put
'and' and 'andalso' at the same level (and forbid mixing them)
and to put 'or' and 'orelse' at the same level (and forbid mixing them).

If I were daft enough ever to use 'and' or 'or' in Erlang, this would
*certainly* confuse the heck out of me.  For the sake of my sanity,
I make sure *never* to use them.

For what it's worth, R has '&&' and '||' which operate lazily on
single logical values, rather like C, and also has '&' and '|',
which are strict and vectorised.  In R, & and && have the
same precedence, and | and || have the same precedence, and
confusion would reign supreme if they did not.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions