# [erlang-questions] conditional expressions

Richard Carlsson richardc@REDACTED
Wed Nov 19 19:26:33 CET 2008

```David Mercer wrote:
> Richard Carlsson wrote:
>> David Mercer wrote:
>>> Can someone please explain the tail recursion problem with andalso?
>> Thanks.
>>
>> It checks that the return value of the right hand side is a boolean,
>> so it must wait for the evaluation to return; it can't just do a tail
>> call if the left hand side evaluates to true. (The OTP folks thought
>> that error checking was more important than tail recursion for these
>> operators.)
>
> Thanks for the reply, but I still do not understand.  If the first operand
> evaluates to true the second operand must necessarily be checked, since they
> both have to be true in order for the expression to evaluate to true.  What
> am I missing (or mißing :-) )?

If the LHS is true, then it all hangs on the RHS, so you can A) call it
with a tail call (if the result of the andalso will be returned as the
result of the current function) and hope that it evaluates to a boolean
as it ought to, or B) call it, get the return value, check that it is
indeed a boolean, and either return it as it is or throw an exception
if it is not a boolean.

The current implementation does B, which makes it less suitable for
this  kind of thing:

all_true([H|T]) -> H andalso all_true(T);
all_true([]) -> true.

which would be a simple traversal if the implementation was A,
but as it is, we have to return down the stack and check that we
are getting neat little booleans all the way. (Yes, type analysis
could sometimes save the day, but far from always.)

On the other hand, B prevents uses such as this:

maybe_goodbye(X) -> X andalso io:format("adieu").

(which returns false if X is false, and otherwise prints
a message and returns ok).

/Richard

```