Reputation: 3009
Recently I started learning Erlang, coming from an imperative background things are somewhat different...
I was doing fine (learning Erlang) till I came across something I did not understood while working in Eshell, can someone explain me what is happening?
17> One.
1
18> One = 1.
1
19> true andalso f(One).
ok
20> One.
1
Why One
is still bound to a value? Since the right side of the expression was indeed evaluated. Now, If I use f()
alone, things work as expected
21> f(One).
ok
22> One.
* 1: variable 'One' is unbound
Why?
Upvotes: 2
Views: 259
Reputation: 20014
Assuming there are no current variable bindings, the command
1> One = 1.
adds a binding for One
by calling erl_eval:add_binding('One',1,[])
where the final argument is a list of current bindings. The bindings are then [{'One',1}]
.
Next, we run the andalso
expression:
2> true andalso f(One).
ok
3> b().
One = 1
ok
What happens for this command is that when true
gets evaluated, the bindings are [{One,1}]
. Since true
makes the left-hand side of the andalso
successful, the right-hand side is then evaluated, also with bindings of [{One,1}]
, and the f(One)
command there results in a call to erl_eval:del_binding('One',[{'One',1}])
, changing the bindings for only the right-hand side to the empty list []
. The result of that part of the expression, ok
, becomes the overall result because of the way andalso
works. Once that result is available, the bindings for the right-hand side are dropped because all that's needed is the result. The original bindings are still around because of the left-hand side, and those bindings stay in effect. The subsequent b()
command to show the bindings therefore still shows One = 1
.
A very similar effect happens if you run this:
4> true andalso (Two = 2).
2
5> b().
One = 1
ok
The second part of the andalso
, (Two = 2)
, adds a binding for Two
only to the bindings for that part of the evaluation. The result, 2
, is kept, but the bindings for that part are dropped, and only the bindings for the left half stay in effect. When we again run b()
to see all bindings, we still see only One = 1
.
Upvotes: 4