How to change the variable value outside of the block?

699 views
Skip to first unread message

lijie

unread,
Oct 29, 2013, 3:47:29 AM10/29/13
to elixir-l...@googlegroups.com
In ruby/irb, I can do this:

$ irb
irb(main):001:0> a = 1
=> 1
irb(main):002:0> f = proc do
irb(main):003:1* a = 2
irb(main):004:1> end
=> #<Proc:0x007fa7fd02f740@(irb):2>
irb(main):005:0> f.call
=> 2
irb(main):006:0> a
=> 2

But in Elixir, variable not changed:

$ iex
Erlang R16B02 (erts-5.10.3) [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (0.10.4-dev) - press Ctrl+C to exit (type h() ENTER for help) 
iex(1)> a = 1
1
iex(2)> f = fn () -> a = 2 end
#Function<20.80484245 in :erl_eval.expr/5>
iex(3)> f.()
2
iex(4)> a
1

How to change it? I want to change the variable in callback function.



Best regards.

José Valim

unread,
Oct 29, 2013, 3:56:54 AM10/29/13
to elixir-l...@googlegroups.com
TLDR: You can't. 

In Elixir, a closure/function creates a new binding. This means a function cannot change a variable defined "above", nor "below" can change the variable of a function. This is very important for concurrency because it avoids race conditions. Imagine this example in Ruby:

x = 1
execute_in_thread { x = 2 }
# Do something more
puts x

Where execute_in_thread will execute the given block concurrently. So, what is the value of x? It is hard to tell. 

It may be 1, if the block was not executed yet. Or 2, if the block was. That's a race condition and behaviour like that makes it really hard to write concurrency software. Even more in a language like Elixir which was designed to run thousands of processes concurrently.

That's why in Elixir we end up using functions like Enum.map and Enum.reduce more frequently because whatever computation we do, the results need to be explicitly returned.




José Valim
Skype: jv.ptec
Founder and Lead Developer


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

lijie

unread,
Oct 29, 2013, 4:54:33 AM10/29/13
to elixir-l...@googlegroups.com
That is good, I should use ets.

Thanks. 
Reply all
Reply to author
Forward
0 new messages