# Pipe operator quiz! Can you guess the result?

**URL:** <https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [September 4, 2020, 12:09pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054 "2020-09-04T12:09:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 4, 2020, 12:09pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/1 "2020-09-04T12:09:55Z")

</div>

_Question 1_

```julia
A=[1,2,3];
B=[1,1,1];

A.>B |> sum

```

_Question 2_

```julia
1:2 .|> x->x^2 |> sum |> inv

```

_Question 3_ (warning: spoilers)

The behaviors above seem just… evil! 😉. Can we fix this? Changing the operator precedence is breaking, but is there really code out there relying on this behavior?

Credits: First example from personal suffering. Second example adapted from this [discussion](https://discourse.julialang.org/t/changing-precedence-of-the-piping-operator/40730), itself adapted from the documentation:

```julia
help?> |>
search: |>

  |>(x, f)

  Applies a function to the preceding argument. This allows for easy function chaining.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> [1:5;] |> x->x.^2 |> sum |> inv
  0.01818181818181818

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 4, 2020, 12:42pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/2 "2020-09-04T12:42:09Z")

</div>

For _any_ programming language, learn the 5 most obvious precedence rules (maybe in Julia `+ -`, `*`, `&& ||`), and **use parentheses for everything else**. Otherwise you get bugs like this, as

```julia
julia> Meta.show_sexpr(:(A.>B |> sum))
(:call, :.>, :A, (:call, :|>, :B, :sum))

```

---

<div class="post-metadata">

**Author:** ![jonniedie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonniedie/32/12842_2.png) [@jonniedie](https://discourse.julialang.org/u/jonniedie)\
**Post date:** [September 4, 2020, 1:15pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/3 "2020-09-04T13:15:39Z")

</div>

The problem is people tend to use the pipe for multi-line operations where visually it’s less obvious to them that they would need to do that. Like:

```julia
(1, 2) .|>
x -> x^2 |>
sum

```

I mean, I agree that its always best to use parentheses when things are ambiguous, but I’ve seen similar code as the above so many times in the wild that I don’t think it’s even in people’s mind that this _could_ be interpreted the way it is.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 4, 2020, 2:03pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/4 "2020-09-04T14:03:59Z")

</div>

@Tamas_Papp I don’t think this rule of thumb really works in practice. At least you probably want to add `[]`, `.`, `^`, `//` and `=`, probably a few others. Nobody wants to write

```julia
(obj.field) = ((A[3]) // (x^2))

```

instead of

```julia
obj.field = A[3] // x^2

```

I agree in spirit: it’s best to use parentheses than rely on non-obvious precedences that few people know by heart (for example when using bitwise operators).

But the problem here is not the ambiguity, it’s that Julia’s behavior is **counter-intuitive**. In the examples above, it’s almost obvious what the precedence “should” be, so users won’t expect parentheses to be necessary.

I think it’s especially bad with the `|>` operator: as @jonniedie says it’s used to write computation steps line-by-line, so users _really_ don’t expect they have to add parentheses there.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [September 4, 2020, 2:29pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/5 "2020-09-04T14:29:38Z")

</div>

Another reason I find the high precedence of `|>` annoying: this operator provides a nice way to build complex computations incrementally in the REPL (only for quick operations obviously). It’s a habit I took from working in Unix shells. It looks like this:

```julia
# look at some values in the REPL
sin.(0:.1:pi)

# add some filter (get previous command with Ctrl-p)
sin.(0:.1:pi) |> x->filter(>(0.5), x)

# that was bad, let's fix it (get previous command with Ctrl-p)
sin.(0:.1:pi) |> x->filter(>(0.4), x)

# OK now let's finish (get previous command with Ctrl-p)
sin.(0:.1:pi) |> x->filter(>(0.4), x) |> sum

```

At the end of the process I have a nice one-liner I can save or share with someone. But it’s much less convenient if after `Ctrl-p` I have to move around to add parentheses…

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 4, 2020, 3:32pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/6 "2020-09-04T15:32:48Z")

</div>

> [@sijo](#):
>
> it’s that Julia’s behavior is **counter-intuitive**

Possibly. People have very heterogeneous intuition about operators that are not common in math and/or language-specific. I don’t feel very strongly about this either way, but since it is a breaking change, I imagine that very good reasons would be requied to change this. The best way forward is probably opening an issue.

Generally, with Unicode, Julia allows [a very large number of operators](https://github.com/JuliaLang/julia/blob/d2daa81b5f3227210bbd0827d2c2f172c83d9ab1/src/julia-parser.scm#L6-L33) with new ones addes all the time, so relying on intuition for precedence is a bit shaky — “intuition for operator precedence” is something people disagree about all the time. One can classify operators to various classes (eg “like +”) as the parser does, but that again is not intuitive for all operators.

Which is why I suggest parenthesizing almost everything nontrivial. Yes, I agree that it is somewhat inconvenient, but I think it has payoffs.

---

<div class="post-metadata">

**Author:** ![Non-Contradiction](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-contradiction/32/2208_2.png) [@Non-Contradiction](https://discourse.julialang.org/u/Non-Contradiction)\
**Post date:** [September 4, 2020, 5:20pm UTC](https://discourse.julialang.org/t/pipe-operator-quiz-can-you-guess-the-result/46054/7 "2020-09-04T17:20:37Z")

</div>

Similar things in R:

```julia
library(magrittr)
> A = c(1,2,3); B = c(1, 1, 1)
> A > B %>% sum
[1] FALSE FALSE FALSE
> 1:2 %>% function(x)x^2 %>% sum
Error: Anonymous functions myst be parenthesized
> 1:2 %>% (function(x)x^2) %>% sum
[1] 5

```

For Question 1, R behaves the same as julia.  
To add something to Tamas, I think the “intuition” can also depends on the context. For example, `==` and `>` should have similar precedence, and what should be the “intuition” for this one?

```julia
 sin.(1:3) .== 1:3 .|> sin

```

For Question 2, R can give the error message when it is “ambiguous” because `%>%` uses “non-standard evaluation” which is similar to macro in julia. Maybe a similar idea can also be tested in various julia pipe packages?  
And I think it is really a good practice to parenthesize anonymous functions, except in very simple cases.
