Processes
Section
p = spawn(fn -> IO.puts("✨") end)
Process.alive?(p)
p = spawn(fn -> 42 end)
Process.alive?(p)
p =
spawn(fn ->
receive do
sender -> send(sender, 42)
end
end)
IO.puts(Process.alive?(p))
me = self()
send(p, me)
Process.sleep(1000)
IO.puts(Process.alive?(p))
receive do
value -> value
end
# ATM, recursive anonymous functions ain't a thing
print_loop = fn ->
receive do
message -> IO.puts(message)
end
print_loop.()
end
defmodule Main do
def print_loop() do
receive do
message -> IO.puts(message)
end
print_loop()
end
end
import Main
pp = spawn(&print_loop/0)
send(pp, "Hello!")
send(pp, "Holla!")
Section
# A first version of PF could avoid the permanent process and allocate one new
# when it's called and then let it die.
defmodule PF do
defstruct pid: nil
# function single-arged for now. Dunno how to do NOT hardcode the number of args
def new(function) do
sender = self()
pid = spawn(fn -> loop({sender, function}) end)
%PF{pid: pid}
end
def call(pf, arg) do
pid = pf.pid
send(pid, {:call, self(), arg})
receive do
{:return, ^pid, value} -> value
_ -> raise "Unexpected message ..."
end
end
# This this is messy! Recursive anonymous functions would solve that, right?
# here "state" provide information hiding (somehow).
defp loop(state) do
{sender, function} = state
receive do
{:call, ^sender, arg} -> send(sender, {:return, self(), function.(arg)})
_ -> raise "Sh*t happened"
end
loop(state)
end
end
pf = PF.new(fn x -> x + 42 end)
PF.call(pf, 56)