[erlang-questions] case expression scope

Richard A. O'Keefe ok@REDACTED
Mon Mar 3 22:02:24 CET 2014


On 4/03/2014, at 5:59 AM, Daniel Goertzen wrote:

> One thing that repeatedly bites me is the way variables bindings leak out of case expressions.  For example, the following code fails to even compile because the Ps and Qs smack into each other...
> 
> f1(X, Y) ->
>     A = case {X,Y} of
>             {0, Q} -> Q;
>             {P, Q} -> P*Q
>         end,
> 
>     B = case {X,Y} of
>             {0, Q} -> Q;
>             {P, Q} -> P+Q
>         end,
>     {A,B}.

That is of course a sketch, not real code.
But as a sketch, it looks like something that
is crying out for a couple of functions:

f1(X, Y) ->
    A = f1_A(X, Y),
    B = f1_B(X, Y),
    {A,B}.

f1_A(0, Q) -> Q;
f1_A(P, Q) -> P*Q.

f1_B(0, Q) -> Q;
f1_B(P, Q) -> P+Q.


> The binding leakages seems like nothing but hassles and headaches to me, so my questions is, is there actually a reason why bindings need leak out of case expressions?

Yes.  (It's not just 'case' either.)
Calling it "leaking" is rather prejudicial;
when you turn on the tap over your kitchen sink
you do not complain that it's "leaking".

> Is there a programming style that leverages this feature?

Yes.

> Is there a limitation in the emulator that forces it to be this way?

Certainly not.
> 
> I'd love to have a 'hygienic' case expression.  Could it be faked with parse transforms?

All selection expressions in Erlang do this, and it is as
hygienic as anyone could wish work.

You don't need a parse transform.
(It would be an AMAZINGLY bad idea to have things that
*look* like 'case' expressions not *act* like them.)

In fact all you really need is

-define(BEGIN, ((fun () ->).
-define(END,   end)())).

f1(X, Y) ->
    A = ?BEGIN
        case {X,Y}
          of {0,Q} -> Q
           ; {P,Q} -> P*Q
        end
    ?END,
    B = ?BEGIN
        case {X,Y}
          of {0,Q} -> Q
           ; {P,Q} -> P+Q
        end
    ?END,
    {A,B}.

Hmm.  I seem to recall that this very same solution
has already been posted in this mailing list.

Right now, I suggest you take this deliberate design
feature of Erlang as a style warning: "You are using
the same variable for two different purposes in a
single clause; this is pretty much guaranteed to
confuse people so DON'T."

Think of it is not entirely unlike gcc's -Wshadow.





More information about the erlang-questions mailing list