W0025 - Boolean Precedence
Warning
foo(X) ->
predicate(X) or X > 10.
%% ^^ 💡 warning: 'or' has higher precedence than the operator around it, so this may not be grouped as intended.
%% | Use 'orelse' instead, or add parentheses to make the grouping explicit.
Explanation
The and/or operands have higher precedence than comparison ops
(unlike andalso/orelse) so this could be a source of bugs.
17> F = fun(X) -> is_integer(X) and X > 0 end.
#Fun<erl_eval.42.105768164>
18> F(-1).
** exception error: bad argument
in operator and/2
called as true and -1
Note that changing this may affect the semantics, as and/or always
evaluate both arguments, so guarantee any side-effects in those
computations take place. In contrast, andalso/orelse do
short circuit evaluation
so may not execute the RHS of the expression.
Fixes
Two fixes are available. elp lint --apply-fix applies the first one,
unless another is selected with --fix-id:
boolean_precedence_replace_operator: replaceandwithandalso(or,in a guard) andorwithorelse.boolean_precedence_add_parens: keep the operator and add parentheses around the operand of the surrounding operator, e.g.predicate(X) or (X > 10).
If it is necessary to use and/or, you can preceed
the expression with a special comment to silence the linter:
% elp:ignore W0025 - An optional explanation here