# There are Guards and Guards

The next one in my list of Erlang battle-stories was actually published in the erlang-questions mailing list and explained by Kostis Sagonas and Doug Rohrer, but it was so WAT-provoking that I couldn’t leave it out of my list.

It’s all about guards and precedence…

#### Boolean Operators in Guards

Not to use the same example that Roberto Ostinelli used in the mailing list, let’s do something that no-one else did before us. Let’s define factorial in Erlang:

`1> Fact = fun F(0) -> 11>          ; F(X) -> X * F(X-1)1>        end.#Fun<erl_eval.30.52032458>2> Fact(1).13> Fact(10).3628800`

So far, so good. But you know the next step, right? Some wise dev comes in and tells us that our function hangs for negative numbers. So, we improve it…

`4> f().ok5> Fact = fun F(0) -> 15>          ; F(X) when X > 0 -> X * F(X-1)5>        end.#Fun<erl_eval.30.52032458>6> Fact(10).36288007> Fact(-1).** exception error: no function clause matching erl_eval:’-inside-an-interpreted-fun-’(-1)`

That’s awesome, but to be fair, factorial only makes sense for integers. Now that we are at it, we should add that to our guard, right?

`8> f().ok9> Fact = fun F(0) -> 19>          ; F(X) when is_integer(X) and X > 0 -> X * F(X-1)9>        end.#Fun<erl_eval.30.52032458>10> Fact(2.0).** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(2.0)`

All looks good and shinny, except that now…

`11> Fact(10).** exception error: no function clause matching erl_eval:’-inside-an-interpreted-fun-’(10)`

#### What’s going on here?

You can, as usual, try to figure this one out for yourselves, although I must confess I haven’t done any research myself this time.

I’ll just state that I know it’s a matter of operator precedence, even when I’m not exactly sure what are the rules that apply here. What I do know are two examples that actually work as expected. This is one:

`11> f().ok12> Fact = fun F(0) -> 112>          ; F(X) when is_integer(X) and (X > 0) -> X * F(X-1)12>        end.#Fun<erl_eval.30.52032458>13> Fact(10).362880014> Fact(10.0).** exception error: no function clause matching erl_eval:’-inside-an-interpreted-fun-’(10.0)15> Fact(-1).** exception error: no function clause matching erl_eval:’-inside-an-interpreted-fun-’(-1)a`

This is the other one:

`21> f().ok22> Fact = fun F(0) -> 122>          ; F(X) when is_integer(X) andalso X > 0 -> X * F(X-1)22>        end.#Fun<erl_eval.30.52032458>23> Fact(10).362880024> Fact(10.0).** exception error: no function clause matching erl_eval:’-inside-an-interpreted-fun-’(10.0)25> Fact(-1).** exception error: no function clause matching erl_eval:’-inside-an-interpreted-fun-’(-1)`

I would like to wrap this up by quoting Kostis:

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).
Like what you read? Give Brujo Benavides a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.