Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pipe operator behaviour

Tags:

elixir

According to Elixir Tutorial on Enumerables and Streams:

The |> symbol is the pipe operator: it simply takes the output from the expression on its left side and passes it as the input to the function call on its right side.

All the functions in the Enum module are eager.

So what is the difference in following statements? Why does the last one return a different result?

iex(1)> 1..1_000 |> Enum.reverse |> Enum.take 5
[1000, 999, 998, 997, 996]

iex(2)> (Enum.reverse 1..1_000) |> Enum.take 5
[1000, 999, 998, 997, 996]

iex(3)> Enum.reverse 1..1_0000 |> Enum.take 5
[5, 4, 3, 2, 1]
like image 614
Lukasz Szozda Avatar asked Jul 04 '15 15:07

Lukasz Szozda


1 Answers

Arguments for methods before a pipe operator should be in parenthesis.

All of these are equivalent:

1..1_000 |> Enum.reverse |> Enum.take 5
#=> [1000, 999, 998, 997, 996]

(Enum.reverse 1..1_000) |> Enum.take 5
#=> [1000, 999, 998, 997, 996]

Enum.reverse(1..1_000) |> Enum.take 5
#=> [1000, 999, 998, 997, 996]

Except this one:

Enum.reverse 1..1_0000 |> Enum.take 5
#=> [5, 4, 3, 2, 1]

Here, Elixir first calculates the Enum.take/2 method with 1..1_0000 and 5 as arguments and then calls Enum.reverse/1 on the result.

# It is actually equal to this:
Enum.reverse(1..1_0000 |> Enum.take 5)

# or this if you simplify it:
Enum.reverse(Enum.take(1..1_0000, 5)
like image 61
Sheharyar Avatar answered Oct 27 '22 07:10

Sheharyar