Erlang multiple Guards on `when`

1.6k Views Asked by At

Fellow stackoverflow-ers,

I am currently learning Erlang. Could someone point me why do I get an illegal guard expression with this guard?

add_new_prime(Idx, Primes, Ref) when length(Primes) =:= 0 ; math:sqrt(Idx) < hd(Primes) -> Ref ++ [Idx];

If I "un-optimise" it by doing only add_new_prime(Idx, Primes, Ref) when length(Primes) =:= 0 -> Ref ++ [Idx];

it works. I've seen multiple examples where there are more than one 'statement' per clause but can't see why mine is not working.

Thanks a lot!

2

There are 2 best solutions below

0
On BEST ANSWER

Please see:

The set of valid guard 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, calls to the BIFs specified below, term comparisons, arithmetic expressions, boolean expressions, and short-circuit expressions (andalso/orelse).

In you case, math:sqrt(Idx) is not a valid guard expression.

Read the documentation here: http://www.erlang.org/doc/reference_manual/expressions.html#id81357

0
On

In addition to @BlackMamba's answer, the idiomatic Erlang approach would be:

add_new_prime(Idx, [], Ref) -> Ref ++ [Idx];
add_new_prime(Idx, [Prime | Primes], Ref) when Idx < Prime * Prime -> Ref ++ [Idx];
...

The inclusion of length/1 in guard tests has always been more than a bit dodgy. It's better taste to avoid it.