# Defining custom pipe operator

**URL:** <https://discourse.julialang.org/t/defining-custom-pipe-operator/18315>\
**Category:** General Usage\
**Created:** [December 5, 2018, 12:44pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315 "2018-12-05T12:44:48Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 5, 2018, 12:44pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/1 "2018-12-05T12:44:48Z")

</div>

Hello! I’m trying to define a pipe operator which propagates `nothing`. It sounds quite easy: `⇒(x, f) = x == nothing ? nothing : f(x)`. This operator works fine when there is a single application of it, e.g. `[1, 2, 3] ⇒ collect`. However, multiple consequtive applications are called “backwards”: `[1, 2, 3] ⇒ collect ⇒ length` tries to call `length(collect)` first, and throws an error of course. Is there a way to modify this behaviour and call operator from left to right?

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [December 5, 2018, 3:35pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/2 "2018-12-05T15:35:13Z")

</div>

```julia
⇒(x, f) = x == nothing ? nothing : f(x)
⇒(g::Function, f) = g ∘ f
[1, 2, 3] ⇒ collect ⇒ length # returns 3

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 5, 2018, 3:38pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/3 "2018-12-05T15:38:54Z")

</div>

It kinda-works, but not always. First, you have a typo - it should be `f \circ g`, not the other way. Also compare this: `sin |> typeof` gives `typeof(sin)`, while `sin ⇒ typeof` gives `#52 (generic function with 1 method)`. However, for most cases I guess this should be ok…

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [December 5, 2018, 3:40pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/4 "2018-12-05T15:40:11Z")

</div>

A worse problem is that `nothing`s that are output by `f` are not propagated at all. I need to think about this a bit more.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [December 5, 2018, 3:43pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/5 "2018-12-05T15:43:28Z")

</div>

It is not possible to change the left/right associativity of operators programmatically since that happens at the parser level.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [December 5, 2018, 3:56pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/6 "2018-12-05T15:56:07Z")

</div>

This should work, as long as the first input, `x`, is not a function.

```julia
⇒(x, f) = x == nothing ? nothing : f(x)
⇒(f::Function, g) = x -> ((x ⇒ f) ⇒ g)

```

---

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [December 5, 2018, 4:09pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/7 "2018-12-05T16:09:58Z")

</div>

> [@aplavin](#):
>
> [1, 2, 3] ⇒ collect ⇒ length

Consider using the existing `|>` operator.

```julia-auto
julia> [1, 2, 3] |> collect |> length
3

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 5, 2018, 4:37pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/8 "2018-12-05T16:37:10Z")

</div>

But aren’t there any other predefined operators with the associativity needed here? I hoped that arrows are treated the same as `|>`, but apparently not.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 5, 2018, 4:37pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/9 "2018-12-05T16:37:59Z")

</div>

The whole point is to make an operator similar to `|>`, which propagates `nothing`s. Of course, I could overload `|>` itself, but this doesn’t look right.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 5, 2018, 5:20pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/10 "2018-12-05T17:20:45Z")

</div>

> [@aplavin](#):
>
> But aren’t there any other predefined operators with the associativity needed here?

All of the [`*` and `+` like operators are left-associative, for example](https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity-1), which is what you want. For example, you could use `▷` (tab-complete `\triangleright`).

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [December 5, 2018, 5:33pm UTC](https://discourse.julialang.org/t/defining-custom-pipe-operator/18315/11 "2018-12-05T17:33:01Z")

</div>

Oh, thank you! It’s not really intutinve how to get the associativity of all those unicode operators.
