Concurrent programming in Erlang

2.8. Scope of Variables

Variables in a clause exist between the point where the variable is first bound and the last textual reference to that variable in the clause. The binding instance of a variable can only occur in a pattern matching operation; this can be thought of as producing the variable. All subsequent references to the variable consume the value of the variable. All variables occurring in expressions must be bound. It is illegal for the first use of a variable to occur in an expression. For example:

f(X) ->            % 1
    Y = g(X),      % 2
    h(Y, X),       % 3
    p(Y).          % 4

In line 1, the variable X is defined (i.e. it becomes bound when the function is entered). In line 2, X is consumed, Y is defined (first occurrence). In line 3, X and Y are consumed and in line 4, Y is consumed.

2.8.1. Scope rules for if, case and receive

Variables which are introduced within the if, case or receive primitives are implicitly exported from the bodies of the primitives. If we write:

f(X) ->
    case g(X) of
        true ->  A = h(X);
        false -> A = k(X)
    end,
...

then the variable A is available after the case primitive where it was first defined.

When exporting variables from an if, case or receive primitive one more rule should be observed:

The set of variables introduced in the different branches of an if, case or receive primitive must be the same for all branches in the primitive except if the missing variables are not referred to after the primitive.

For example, the code:

f(X) ->
    case g(X) of
        true -> A = h(X), B = A + 7;
        false -> B = 6
    end,
    h(A).

is illegal since if the true branch of the form is evaluated, the variables A and B become defined, whereas in the false branch only B is defined. After the case primitive a reference is made to A in the call h(A) – if the false branch of the case form had been evaluated then A would have been undefined. Note that this code fragment would have been legal if a call to h(B) had been made instead of h(A) since in this case B is defined in both branches of the case primitive.