Re: Why the output differs in these two erlang expression sequence in shell?
On Thu, Oct 05, 2017 at 04:27:16PM +0530, Greg wrote:
> In Erlang shell why the following produces different result?
It's about scope of variables, closures, and the fact that the =
operator isn't an assignment operator but a matching operator.
> 1> Total=15.
Match the unbound "Total" against value 15: Total is bound to the
value "15". At this point, "Total" is now a bound variable in the
outer scope (the shell).
> 2> Calculate=fun(Number)-> Total=2*Number end.
"Total" is already bound, so you're using the _bound_ variable in
the fun, so it has a value (which is immutable) in the context of
the fun. The fun here actually consists of a function of one
variable, plus a context which contains the bound variable Total,
which is the context in which that fun is evaluated. This
combination of a fun+context is usually called a closure.
> 3> Calculate(6).
Total is bound to the value 15 in the context of the
closure. 2*Number is 12. 15 does not match 12, and so:
> **exception error: no match of right hand side value 12**
Observe that if you ran f(Total) to make the shell forget about the
value of Total, the original value of Total would still be bound
into the Calculate closure, and you get the same result:
2> Calculate = fun(Number) -> Total = 2*Number end.
** exception error: no match of right hand side value 12
> 1> Calculate=fun(Number)-> Total=2*Number end.
Defines a fun where Total is _unbound_ in the fun, and is local to
the fun, so the closure doesn't contain "Total" (or at least,
contains an unbound "Total").
> 2> Total=15.
Defines a different binding of Total, in the scope of the
shell. This can't affect the local variable inside the fun at this
> 3> Calculate(6).
Computes 2*Number, which is 12, and matches it against the unbound
local variable Total, which binds Total to the value 12. The value
of the function is then:
Note that the fun definition (i.e. the closure) isn't modified by
this operation. So you can safely run the fun again, and the Total
value is still unbound, because it's only bound to a value within
the context of a function call. Each call to the function uses the
original context which was attached to the fun (thus making a
closure) when the fun was defined.
I'm not sure if that actually helps make things any clearer. I hope
so. Basically, if you bind a variable to a value and then, in the same
context, define a fun which uses that variable, the value of the
variable at that moment gets included in the fun definition.
Hugo Mills | Prof Brain had been in search of The Truth for 25
hugo@... carfax.org.uk | years, with the intention of putting it under house
http://carfax.org.uk/ | arrest.
PGP: E2AB1DE4 | Zeb Carter, The Number of the Beast