Elixir construct help needed

I am reading some code and I see this:

SomeModule.call(
  service: &UpdateModule.process(&1, &2, &3, option1: conn.assigns.option1)
)

It does work, but I do not understand how to tie it to the constructs I know exist (such as &Module.fun/1 for example a reference to a function in Module named fun with arity 1).

Can anyone explain to me what this does and where in the docs I can read about this usage?

TIA,
Alex.

Kernel.SpecialForm.&/1 gives you syntactic sugar around fn … -> … end.

This might help you, in addition to the docs posted: https://dockyard.com/blog/2016/08/05/understand-capture-operator-in-elixir

The specific usage you mentioned isn’t covered explicitly in that post, but essentially & is “create an anonymous function with what follows” and &1, &2 and so on mean “use argument number 1 here, number 2 here, etc.”.

Putting all that together,

&UpdateModule.process(&1, &2, &3, option1: conn.assigns.option1)

translates to

fn arg_1, arg_2, arg_3 ->
  UpdateModule.process(arg_1, arg_2, arg_3, option1: conn.assigns.option1)
end

I think this is an example of were less isn’t more. I find

&(UpdateModule.process(&1, &2, &3, option1: conn.assigns.option1))

much easier to parse than

&UpdateModule.process(&1, &2, &3, option1: conn.assigns.option1)

the lack of parentheses sets me up to expect:

&UpdateModule.process/4

causing me to stall when I get to the argument list. In my mind the &(...) and &.../n patterns are easily differentiated - &... not so much - scanning left to right I have to get to end of the function name to know what I’m actually dealing with.

1 Like