[erlang-questions] Why the output differs in these two erlang expression sequence in shell?

Hugo Mills hugo@REDACTED
Thu Oct 5 13:17:17 CEST 2017


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:

1> Total=15.
15
2> Calculate = fun(Number) -> Total = 2*Number end.
#Fun<erl_eval.6.52032458>
3> f(Total).
ok
4> Calculate(6).
** 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
   point.

>     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:

> 12

   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.

-- 
Hugo Mills             | Prof Brain had been in search of The Truth for 25
hugo@REDACTED 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20171005/c57d3019/attachment.bin>


More information about the erlang-questions mailing list