Most
Why is the capture syntax &+/2 equivalent to &(&1 + &2)
I don’t understand how the capture syntax in the following expression is aware of how to use arguments without specifying &1 and &2:
Enum.reduce([1, 2, 3], 0, &+/2)
I understand this version of an equivalent expression since it is explicit how the arguments &1 and &2 are used in the function:
Enum.reduce([1, 2, 3], 0, &(&1 + &2))
Most Liked
peerreynders
It simply takes advantage of the positional function parameters.
+/2 is Kernel.+/2, i.e. Kernel.+(left, right) is equivalent to left + right.
The & operator captures the function rather than evaluate it - so it’s &Kernel.+/2 or &+/2.
Now look at the spec for Enum.reduce/3
reduce(t, any, (element, any -> any)) :: any
(element, any -> any) tells us that it takes a two parameter function. The first parameter (element) comes from the enumeration, the second parameter (any) is the accumulator which is the same type as the function’s result.
So the element (first) argument goes into the left parameter and the any (second) argument goes into right parameter of Kernel.+/2 (… and the result becomes the next right and so on).
bbense
Let’s start with some iex
iex(1)> h Kernel.+/1
def +(value)
Arithmetic unary plus.
Allowed in guard tests. Inlined by the compiler.
Examples
┃ iex> +1
┃ 1
iex(2)> h Kernel.+/2
def +(left, right)
Arithmetic addition.
Allowed in guard tests. Inlined by the compiler.
Examples
┃ iex> 1 + 2
┃ 3
The important thing to remember with Elixir is that no matter what the syntax looks like, it all gets turned into function calls. Every time you use + it gets turned into one of those two functions.
iex(3)> quote do: 1 + 2
{:+, [context: Elixir, import: Kernel], [1, 2]}
iex(4)> quote do: + 1
{:+, [context: Elixir, import: Kernel], [1]}
So let’s look at what the parser sees in each case.
iex> +(1, 2)
In this case the parser looks to somehow call Kernel.+1/ but it’s given an arg list that
is two elements long. This generates an syntax error.
iex> 1 Kernel.+ 2
Here the parser sees a number so it starts looking for an infix operator it can turn into a function call. While + is defined as an infix operator, arbitrary elixir functions cannot be used
as infix operators. So again it generates a syntax error.
What is going on is that the parser is attempting to be as friendly as possible and allow you to use constructs you are familiar with like 1 + 2. However, that can only be extended so far before it starts to break the underlying model of a functional programming language. + is particularly tricky since it exists in the parser as both a prefix and infix operator.
The effects you see are the attempts of the parser to understand + as both. Once you
put Kernel.+ into the equation all the special parsing rules are turned off, and it behaves like any other Elixir function.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








