Abs
Abs

Reputation: 2334

Can you pass a function as a message in Elixir/Erlang?

It is said that functions are first class citizens in Elixir/Erlang. Can functions be passed as messages?

While exploring the Elixir API, I came across Agent#get_and_update(agent, fun, timeout \\ 5000). I imagine get and update operation is atomic. The only way I think this is possible is if the fun is run on agent process rather than the client process that interacts with the Agent.

If fun is run on the client process, it opens up to a lot of questions about guaranteeing atomicity and client process failure.

Upvotes: 1

Views: 428

Answers (1)

Justin Wood
Justin Wood

Reputation: 10061

Yes you can.

from the agent docs for get_and_update/3.

The function fun is sent to the agent which invokes the function passing the agent state.

The agent process itself runs the function, updating its state atomically.

Under the hood, Agents are just a specialized GenServer. So if we look at the code for get_and_update/3, we can see that we are actually just passing the function to a GenServer to run.

@spec get_and_update(agent, (state -> {a, state}), timeout) :: a when a: var
def get_and_update(agent, fun, timeout \\ 5000) when is_function(fun, 1) do
  GenServer.call(agent, {:get_and_update, fun}, timeout)
end

Upvotes: 5

Related Questions