[erlang-questions] nested variable assignment : bug or the expected behaviour ?
Richard Carlsson
carlsson.richard@REDACTED
Tue Jun 26 14:05:21 CEST 2012
On 06/26/2012 01:55 AM, James Churchman wrote:
> If i have a function like :
>
> f()->[J=100,J].
>
> Or put in the shell:
> {J=200,J}.
>
> Or
>
> erlang:'+'(J=10,J).
>
> Or any other combination of where i try to set a variable nested
> inside somewhere else, it will say "variable 'J' is unbound" .. is
> this the expected behaviour ?
Yes, it's expected. Each expression and subexpression in Erlang has an
input environment and an output environment (which is the same as the
input environment unless the expression creates additional bindings).
Environments are chained so that in the comma-separated body of a
clause, the output from one expression becomes the input of the next.
However, arguments to a single expression, such as f(A, B) or {A, B},
are always evaluated in the same input environment. Hence, even if you
write f(X=1, X), where X is a previously unbound variable, both
arguments are evaluated in the environment that does not contain X, and
the compiler complains about the second X being unknown.
The output environment from an expression is the combination of the
output environments from its subexpressions, so f(X=1, Y=2) exports both
X and Y. To preserve the constraint that a variable occurring in more
than one pattern has the same value independent of evaluation order, if
you write f(X=a(), X=b()), the compiler will actually insert a test
after the evaluation of the arguments to check that the intermediate
results of a() and b() are in fact the same value and so either can be
taken as the value of X.
As Richard O'Keefe said in his reply, Erlang uses strict left-to-right
evaluation order also in function arguments (even where it to someone
writing a compiler might seem to be backwards). This is to ensure that
an Erlang program behaves the same regardless of compiler
implementation, and to eliminate a source of confusion: programmers
shouldn't have to remember a bunch of special cases where evaluation
order is right-to-left or undefined. What you see is what you get.
But at the same time, the known evaluation order (with respect to side
effects) should not be something that programmers can abuse to write
unreadable code like f(1+g(X=h(Y),42),{foo,X}). Therefore, the scoping
rules enforce that bindings are effectively treated as if the evaluation
order of arguments was unknown, or could be changed from one version of
Erlang to the next without changing the meaning of the program.
/Richard
More information about the erlang-questions
mailing list