Why comparing function results is an illegal guard

2019-02-16 17:51发布

问题:

Why is it illegal?

min1_e_( F, X, E) ->
    if 
        F( X + 2*E ) < F( X + E ) ->   % ?
            min1_e_( F, X, E*2 );
        true ->
            E
    end.

I mean, if I define both parts of expression separately, it works fine. But comparing function returns should be trivial, shouldn't it? Think I'm missing something more beneath that.

回答1:

If expression does not work in Erlang in the same way as in other programming languages.

According to http://www.erlang.org/doc/reference_manual/expressions.html (paragraph 7.7 If):

The branches of an if-expression are scanned sequentially until a guard sequence GuardSeq which evaluates to true is found.

In your example, the expression F( X + 2*E ) < F( X + E ) is treated not as a normal expression, but as a guard expression, which might have non-deterministic results (Erlang allows to use only deterministic expressions in the guard expressions), so Erlang refuses to use it in the "if" expression.

To resolve the issue, I would recommend to use a case expression instead. Something like this:

    min1_e_( F, X, E) ->
            case F(X + 2*E) < F(X + E) of
                    true -> min1_e_( F, X, E*2 );
                    false -> E
            end.


标签: erlang guard