def adder(v):
return lambda x: v + x
Can I then send the result of (say) "adder(5)" over the network and have it work?On a erlang shell in node A, do:
register('test', self()).
receive F -> ok end.
(this gives the shell a registered name, and then waits for a message)On a debug shell on node A do:
AddrFactory = fun (X) -> fun (Y) -> Y + X end end.
{test, NodeA} ! AddrFactory(5).
Then, back on node A, do F(10).
And you'll get 15For more fun, you could have node A send the value to go into the closure, etc.
NodeA is something like 'demo@hosta.example.org'
NodeA would be started with something like erl -name demo@hosta.example.org -setcookie demo
and NodeB started like erl -name demo@hostb.example.org -setcookie demo
I don't want to discourage you from using erlang and Elixir, because the beam is amazing, plenty of very lucrative companies (like bet365) do, just, be aware of things you might versus might not run in an actual prod situation.
Do not run distributed Erlang with nodes you don't trust. Do not run distributed Erlang on a network you don't trust (VPN/TLS can help).
variable = 5
lambda = &(&1 + variable)
File.write!("pickle", :erlang.term_to_binary(lambda))
close terminal, open new shell unpickled = "pickle" |> File.read! |> :erlang.binary_to_term
unpickled.(5)
yields 10.You could, of course, send that file over the network (via email, tcp/ip, carrier pigeon, whatever), and it's even easier if you use built-in erlang distribution primitives, which indeed do this under the hood.
Keep in mind that by default values are immutable, so when you're building that lambda it takes out a fixed-in-time reference to that 5 (or whatever, you could even make it user input). In other languages, if that variable changes... Something strange might happen, depending on what that underlying datatype is. In particular, side effects can exist for lists but not scalars in python.
In elixir, you can rebind that variable 5 to something else but it won't change the lambda (erlang doesn't allow you to do that at all, except in the repl, sort of). You could also do that with, say, a list datatype, and you get the same deal.
for example:
list = [1,2,3]
lambda = fn -> length(list) end
lambda.() #==> 3
list = list ++ [4, 5]
list #==> [1,2,3,4,5]
lambda.() #==> 3
which is what lets you have a lambda with no expectation on the mutability of the bound-in values. What you get is what you expect, no matter how far away or disconnected or even dead the source is. And that respect for the physics of causality and relativity, at the core, is what makes the BEAM languages so great for distributed systems.https://erlang.org/doc/apps/ssl/ssl_distribution.html#specif...