Nona
Nona

Reputation: 5462

Why does this call to Agent#update with the capture operator work in Elixir 1.4.2?

So I understand the capture operator in this context:

sum_it = &(&1 + 2)
sum_it.(1) # result is 3

But I don't understand it here:

# stores "Peter" where pid = #PID<0.82.0>
Agent.update(pid, &["Peter" | &1])

It looks like it's turning the List into an anonymous function? And the "&1" somehow represents the tail of a list?

Upvotes: 0

Views: 53

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

The capture operator is a syntactic sugar/shorthand for declaring an anonymous function of minimal arity 1. Kernel.SpecialForms.& just takes it’s argument, looks up for all the &N inside it and converts the whole into anonymous function. The most contrived example would be:

iex(1)> f = &(&1)
#Function<6.50752066/1 in :erl_eval.expr/5>
iex(2)> f.(42)
42

Elixir treats spaces in a free manner (unlike e. g. Python :). If there is no ambiguity, the spaces are ignored. One might write f = &(&1) or f = & &1 or f =& &1, all the above are equivalent. If there is no ambiguity, the space might be omitted:

iex(3)> sum_it = &[&1 | 42]
#Function<6.50752066/1 in :erl_eval.expr/5>
iex(4)> sum_it.(3.14)
[3.14 | 42]

The above is essentially the same as sum_it = &([&1 | 42]). That said, the above is a syntactic sugar for:

iex(5)> sum_it = fn arg1 -> [arg1 | 42] end

Hope that clarifies things.

Upvotes: 1

Justin Wood
Justin Wood

Reputation: 10061

Agent.update/3 takes a function that takes the state of the agent and returns a new state.

So if I take some Agent

iex(1)> {:ok, pid} = Agent.start(fn -> 4 end)
{:ok, #PID<0.90.0>}
iex(2)> pid
#PID<0.90.0>
iex(3)> Agent.update(pid, &(&1 + 2))
:ok
iex(4)> Agent.get(pid, &(&1))

Now, as for the syntax you are questioning.

iex(1)> [1, 2, 3]
[1, 2, 3]
iex(2)> [1 | [2 | [3]]]
[1, 2, 3]

Essentially it is a way to prepend a value to a current list.

iex(3)> [1, 2 | 3]
[1, 2 | 3]

You will need to be careful when using the | to create a list. You will want to be sure that you already have a list as you can create an improper list which may accidentally lead to some issues if you are not expecting one.

Upvotes: 1

Related Questions