Reputation: 2334
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
Reputation: 10061
Yes you can.
from the agent docs for get_and_update/3
.
The function
fun
is sent to theagent
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