Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pipe on next line in iex (syntax error before: '|>')

In chains of pipes in Elixir, it's standard to place the pipe at the beginning on the line:

1
|> IO.inspect(label: "initial value")
|> Kernel.+(1)
|> IO.inspect(label: "plus one")
|> Kernel.*(2)
|> IO.inspect(label: "times two")
|> Integer.to_string(2)
|> IO.inspect(label: "in binary")

However, when I try to do this in IEx, the following happens:

iex(1)> 1
1
iex(2)> |> IO.inspect(label: "initial value")
** (SyntaxError) iex:2:1: syntax error before: '|>'

It is possible to workaround by moving the pipe operator to the end of the line:

iex(1)> 1 |>
...(1)> IO.inspect(label: "initial value") |>
...(1)> Kernel.+(1) |>
...(1)> IO.inspect(label: "plus one") |>
...(1)> Kernel.*(2) |>
...(1)> IO.inspect(label: "times two") |>
...(1)> Integer.to_string(2) |>
...(1)> IO.inspect(label: "in binary")
initial value: 1
plus one: 2
times two: 4
in binary: "100"
"100"

But that's tedious and unidiomatic. Is it possible to use pipes in IEx with the pipe on the next line, like we do in source files?

like image 552
Adam Millerchip Avatar asked Mar 01 '23 19:03

Adam Millerchip


1 Answers

This is supported in recent versions:

Interactive Elixir (1.12.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> [1, [2], 3]
[1, [2], 3]
iex(2)> |> List.flatten()
[1, 2, 3]

Prior to Elixir 1.12, it was not possible to copy-paste multi-line pipes like your example verbatim into IEx. This was a symptom of the fact that code in IEx is evaluated line-by-line.

The simplest workaround is to wrap the expression in parentheses:

iex(1)> (
...(1)>     1
...(1)>     |> IO.inspect(label: "initial value")
...(1)>     |> Kernel.+(1)
...(1)>     |> IO.inspect(label: "plus one")
...(1)>     |> Kernel.*(2)
...(1)>     |> IO.inspect(label: "times two")
...(1)>     |> Integer.to_string(2)
...(1)>     |> IO.inspect(label: "in binary")
...(1)> )
initial value: 1
plus one: 2
times two: 4
in binary: "100"
"100"

You can also escape the newlines:

iex(1)> 1 \
...(1)> |> IO.inspect(label: "initial value") \
...(1)> |> Kernel.+(1) \
...(1)> |> IO.inspect(label: "plus one") \
...(1)> |> Kernel.*(2) \
...(1)> |> IO.inspect(label: "times two") \
...(1)> |> Integer.to_string(2) \
...(1)> |> IO.inspect(label: "in binary") \
...(1)>
initial value: 1
plus one: 2
times two: 4
in binary: "100"
"100"
like image 65
Adam Millerchip Avatar answered Apr 06 '23 05:04

Adam Millerchip