Pass in an anonymous function to spawn/1

I’m on my Elixir learning curve and when reading the book, I saw the following expression:

spawn(fn -> IO.puts("Hello, Alpha Centauri!") end)
#=> Hello, Alpha Centauri!
#PID<0.114.0>

I tried to extract the used lambda into a separate anonymous function and pass it in the spawn/1 as follows:

iex(6)> hello = fn -> IO.puts("Hello, Alpha Centauri!") end
#Function<21.91303403/0 in :erl_eval.expr/5>
iex(7)> hello.()
Hello, Alpha Centauri!
:ok

But it raised the error:

iex(9)> hello.() |> spawn()
Hello, Alpha Centauri!
** (ArgumentError) argument error
    erlang.erl:2793: :erlang.spawn(:ok)

Why so?

Hi!

Here you’re passing spawn the result of executing the function. Instead, you should pass the function itself:

hello |> spawn()

1 Like

Thank you for the response, another syntax also worked for me:

iex(2)> hello = fn -> IO.puts("Hello, Alpha Centauri!") end
#Function<21.91303403/0 in :erl_eval.expr/5>
iex(3)> spawn(fn -> hello.() end)
Hello, Alpha Centauri!
#PID<0.107.0>

That certainly works, but it’s also kind of redundant: you are creating an anonymous function whose only job is to call another function. spawn(hello) is more concise and IMO more readable. Just saying.

2 Likes

You can write it as:

ex(1)> hello = fn -> IO.puts("Hello, Alpha Centauri!") end
#Function<43.3316493/0 in :erl_eval.expr/6>
iex(2)> spawn(hello)
Hello, Alpha Centauri!
#PID<0.113.0>
iex(3)> hello |> spawn()
Hello, Alpha Centauri!
#PID<0.115.0>