Learn By Example: What’s the ampersand in Elixir (capture operator)?

Seeing the ampersand for the first time in Elixir was really confusing, but here’s some examples to clarify how it works.

Seeing the ampersand for the first time in Elixir I wanted to dig deep into what it meant. The ampersand is called the capture operator in Elixir. The first & effectively either gets a reference to the original function or starts an anonymous function. Any ampersand after the first that references the positional argument passed to it. You could use this to write very concise anonymous functions.

Here’s a couple of examples:

				
					messages = ["One", "Two"]

no_capture_operator = fn msg ->
  IO.inspect(msg, label: 'no_capture_operator')
  %{itemValue: msg}
end
# no_capture_operator: "One"
# no_capture_operator: "Two"

messages |> Enum.map(no_capture_operator)

new_messages = messages |> Enum.map(&%{itemValue: &1})

IO.inspect(new_messages)
# [%{itemValue: "One"}, %{itemValue: "Two"}]

new_messages = messages |> Enum.map(fn msg ->
  IO.inspect(msg)
  %{itemValue: msg}
end)
# "One"
# "Two"

IO.inspect(new_messages, label: "new_messages =")
# new_messages =: [%{itemValue: "One"}, %{itemValue: "Two"}]

message_func = fn msg ->
  IO.inspect(msg)
  %{itemValue: msg}
end

messages |> Enum.map(&message_func.(&1))
# "One"
# "Two"

# the enum tuples have zero-based indexes, hence the + 1
message_with_odd_even = &%{itemValue: &1, type: (if rem(&2 + 1, 2) === 0, do: "even", else: "odd")}

msg_tuple = {"One", 0}

IO.inspect(message_with_odd_even.(elem(msg_tuple, 0), elem(msg_tuple, 1)))
# %{itemValue: "One", type: "odd"}

IO.inspect(message_with_odd_even.("One", 0))
# %{itemValue: "One", type: "odd"}

new_messages = messages |> Enum.with_index |> Enum.map(&message_with_odd_even.(elem(&1, 0), elem(&1, 1)))

IO.inspect(new_messages, label: 'new_messages 2 =')
# new_messages 2 =: [%{itemValue: "One", type: "odd"}, %{itemValue: "Two", type: "even"}]

messages |> Enum.each(&IO.inspect(&1, label: "label for " <> &1))
# label for One: "One"
# label for Two: "Two"
				
			

Never miss another post!

Get my latest articles delivered directly to your inbox.

Never miss another post!

Get my latest articles delivered directly to your inbox.

🙏

Great Choice!

Thanks for enabling notifications! Don’t worry, I hate spam too and I won’t ever disclose your contact information to 3rd parties.