yeyo
yeyo

Reputation: 3009

Why this expression does not unbound the variable?

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

Answers (1)

Steve Vinoski
Steve Vinoski

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

Related Questions