[erlang-questions] The If expression

Hakan Mattsson <>
Fri Jan 2 12:05:32 CET 2009


On Thu, 1 Jan 2009, Fredrik Svahn wrote:

>   if Expression -> Body  else -> ElseBody  end
> 
> which should act as syntactical sugar for the more clumsy and unintuitive:
> 
>   case Expression of
>      true -> Body;
>      _Else -> ElseBody
>   end
>
> My hope is that with this improvement 'if'-statements would be the
> recommended choice for expressions evaluating to a bool() and
> 'case'-statements the natural choice for all other expressions. This
> proposal is in no way competing with other recently proposed control
> flow improvements, such as using the already reserved word 'cond' and
> "unnesting case statements".

I do not fancy any of these two code examples as they promote a sloppy
programming style. In my opinion, a boolean expression should be a
boolean expression and nothing else. If a boolean expression evaluates
to anything else than 'true' or 'false', the evaluation should fail in
the normal case. Sometimes catch-all-clauses are useful, but in many
cases they may delay detection of bugs.

> 2. At least of of the guards have to evaluate to true, otherwise a
> runtime error will occur. This leads to unintuitive constructs like:
> 
>    if Bool -> do_true();
>       true -> do_false() end.
> Which could be replaced by a more intuitive:
> 
>   if Bool -> do_true()  else -> do_false() end.

How realistic is it to expect that the common form of future
if-statements are written as one-liners?

If the if-statement does not fit in one line, I think that the the new
proposed syntax and the classic case-statement are very similar:

    if 
      Bool -> do_true()
      else -> do_false()
    end.

    case Bool of
       true  -> do_true();
       false -> do_false()
    end.

They are in fact so similar so that I see no point in adding a new
language construct.

You argued that the following code is unintuitive

    if 
      Bool -> do_true();
      true -> do_false()
    end.

while the following is intuitive

    if 
      Bool -> do_true()
      else -> do_false()
    end.

I find the new proposed syntax to be very similar to the old
if-statement. The old syntax may be a little bit uglier than the new
syntax, but that is not the same as unintuitive. I definitely prefer
the case-syntax, for if-then-else statements.

> An open question is if it should also be allowed to have expressions
> without an 'else' clause, as proposed by Damien Katz, i.e.:
> 
>   if Expression -> Body end
> 
> Which might be useful in some cases, e.g.
> 
>   if Logging -> log:write("Aiee") end,

This would be an incompatible language change that breaks lots of
code. I frequently write code that is intended to provoke a crash (for
example by not having a catch-all-clause in if-statements) in those
cases when some variable has an unexpected value.
 
> This could be handled by introducing a default return value for the
> else clause in the odd cases where we might sometimes care about the
> value of the "if"-expression, i.e.:
> 
>   LoggingSucceded = if Logging -> log:write("Aiee") end
> 
> In this particular case returning false might seem like a good idea,
> but in other cases e.g. an empty list might be just as natural. I am
> just not sure how to apply the rule of least surprise to this...
> 
> Another proposal might be to allow "if"-expressions without an else
> clause only when it is obvious to the compiler that the return value
> will be discarded. The second example would thus result in a
> "LoggingSucceded is unsafe in 'if' (line x)" error when compiling
> (similar to what exists for e.g. case clauses today).

Is this what you mean with intuitive? ;-)

/Håkan
---
Håkan Mattsson (uabhams)
Erlang/OTP, Ericsson AB


More information about the erlang-questions mailing list