so I saw the following
Enum.sort(list, &>/2)
Can anyone explain me what that &>
does? I think /2
is just dividing by two, right?
so I saw the following
Enum.sort(list, &>/2)
Can anyone explain me what that &>
does? I think /2
is just dividing by two, right?
This is called function capturing.
&
captures a function named >
of arity 2 (/2
). Arity means the number of arguments it takes.
You could write the same as: fn a b -> a > b end
I recommend you read through this in the language guide: Modules and functions - The Elixir programming language
To add to what @tcoopman said about function capturing, this code is attempting to sort in descending order, by passing the greater than function as the sorter
argument to Enum.sort/2
. This could arguably be more clearly written as Enum.sort(list, :desc)
.
iex(1)> [0,1,5,4,2,6] |> Enum.sort()
[0, 1, 2, 4, 5, 6]
iex(2)> [0,1,5,4,2,6] |> Enum.sort(&>/2)
[6, 5, 4, 2, 1, 0]
iex(3)> [0,1,5,4,2,6] |> Enum.sort(:desc)
[6, 5, 4, 2, 1, 0
Note that :desc
is subtly different to >
because it’s equivalent to passing >=
, not >
. But >=
is probably what you wanted anyway, because the function is stable if it returns true when items are considered equal, another reason to prefer :desc
:
iex(4)> ["four", "two", "one", "seven"] |> Enum.sort_by(&String.length/1, &>/2)
["seven", "four", "one", "two"]
iex(5)> ["four", "two", "one", "seven"] |> Enum.sort_by(&String.length/1, &>=/2)
["seven", "four", "two", "one"]
iex(6)> ["four", "two", "one", "seven"] |> Enum.sort_by(&String.length/1, :desc)
["seven", "four", "two", "one"]
You can see that >
changes the order of "one"
and "two"
even they are the same length, but >=
and :desc
do not.
I read in Elixir in Action
book, that operators are functions in Elixir. Excerpt:
"Many operators are functions
It’s worth noting that many operators in Elixir are actually functions. For example, instead of calling a+b , you can call Kernel.+(a,b). Of course, no one would ever want to write this kind of code, but operator functions have a benefit when turned into anonymous functions. For example, you can create a two-arity lambda that sums two numbers by calling &Kernel.+/2 or the shorter &+/2."
Example:
[1, 1, 1, 1, 1]
|> Enum.reduce(0, &+/2)
# 5
defmodule CustomOps do
def plus(a, b), do: a + b
end
[1, 1, 1, 1, 1]
|> Enum.reduce(0, &CustomOps.plus/2)
# 5
When we need to pass a function to a function parameter, we need to pass in form of &<function_name>/<arity>
. In Elixir, the >
operator acts like a function defined in Kernel (Kernel — Elixir v1.14.2) and it takes 2 arguments (left and right). That’s why it’s >/2
.
Ah yea cool I was just curious about the 2
there. Thanks!