Diego Torres — La Furia (1997)

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) -> 1

1> ; F(X) -> X * F(X-1)

1> end.

#Fun<erl_eval.30.52032458>

2> Fact(1).

1

3> 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().

ok

5> Fact = fun F(0) -> 1

5> ; F(X) when X > 0 -> X * F(X-1)

5> end.

#Fun<erl_eval.30.52032458>

6> Fact(10).

3628800

7> 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().

ok

9> Fact = fun F(0) -> 1

9> ; 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)