Can someone please explain '&>/2'?

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

9 Likes

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.

9 Likes

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

Is same as, writing our own:

defmodule CustomOps do
  def plus(a, b), do: a + b
end

[1, 1, 1, 1, 1]
|> Enum.reduce(0, &CustomOps.plus/2)

# 5
3 Likes

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.

1 Like