# Fixing the Piping/Chaining Issue

**URL:** https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654
**Category:** Internals & Design
**Tags:** proposal, piping, chaining, partial-evaluation, threading
**Created:** [November 2, 2022, 11:04am UTC](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654 "2022-11-02T11:04:36Z")
**Posts on this page:** 1
**Showing post:** 6

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [November 2, 2022, 10:36pm UTC](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654/6 "2022-11-02T22:36:04Z")

</div>

> [@mcabbott](#):
>
> `(1:5) |> filter(isodd) # filter just works (Julia 1.9)`

Admittedly, functions like `map`, `filter`, and `reduce` were some of the primary drivers motivating the backfix operator `\>`.

Maybe the practice of offering alternate curried function forms such as `filter(f) = x -> filter(f, x)` will become standard practice in Julia, so that `|>` will be all that’s ever needed? My gut feel is that a convention of specifying method variations solely for the sake of currying could begin to inhibit other uses of multiple dispatch and unduly burden the task of specifying interfaces, so maybe not.

> [@mcabbott](#):
>
> ```julia
> # [1, 2, 3, 4] \> filter(iseven) \> map(sqrt) /> join(", ")
> [1, 2, 3, 4] |> filter(iseven) .|> sqrt |> join(_, ", ")
> 
> ```

Ideally the frontfix and backfix operators will work with broadcasting (e.g. `[1,2,3] /> sqrt.()`), but the demo macro doesn’t yet support it. This is why in my examples I used `map` so frequently. But the intent eventually is to support broadcasting.

> [@mcabbott](#):
>
> `# (1:100) \> mapreduce(2 \> ^, +) /> √()"`

admittedly some of the examples are a bit contrived just to illustrate what’s possible.

> [@mcabbott](#):
>
> How easy is it to invent (or ideally, find in the wild) examples for which this is not true? I.e. for which this proposal does things you couldn’t easily do with 24990? Both work “one level deep”, I think, so perhaps they are always close.

Perhaps the biggest difference is in assisting tab autocomplete by specifying argument(s) before starting on the function name.

They’re both useful for chaining, and they’re both useful for specifying partially evaluated functions. It seems like the most prominent difference is in storing and passing partial functions: whereas `/>` and `\>` partially evaluate on _one argument_, `_` syntax partially evaluates on _every argument except one_. _ **EDIT: THIS IS INCORRECT.** _ This means that it’s possible to create partial functions with `/>` and `\>` that cannot be created with `_`, yet every partial function from `_` can be made with `/>` and `\>` (although whether it’s worthwhile to do so is another question entirely).

An example of this is among my “fun examples” list: the partial function `hello_replace` can take multiple arguments, as illustrated by the second call to it. If I’m not mistaken, a function partially evaluated by `_` syntax cannot do this.

On the other hand, when you want to partially evaluate a multi-argument function until it has only one argument left, curry underscore can be much easier. It’s _possible_ to do the same with `/>` and `\>`, but not before pulling out your hair in the process. Then again, most of the time the goal when creating single-argument partial functions is for `|>` chaining, which `/>` and `\>` handle already without the need for `|>`.

So it seems a cost/benefit analysis is in order.

> [@Palli](#):
>
> I’m focusing mainly on the `/>` operator for compatibility with other languages (except for how it looks), do we need the corresponding `\>`? Would it be really useful (other languages do without similar)?

If it helps, one can think of frontfix `/>` and backfix `\>` as being infix variants of Clojure’s thread-first `->` and thread-last `->>` macros. Perhaps we could instead use `/>` and `/>>` for a greater sense of consistency with Clojure 😉 I’m attracted to `/>` and `\>` because of the inclusion of the backslash character `\`, which one can associate with the backfix operation: which threads the object into the _back_ of the argument list. Silly perhaps to fixate on such a minor detail, but I like it.

Including backfix `\>` was largely for want to assist functions such as `filter`, `map`, `reduce`, and `mapreduce`, which take the threadable object as a last argument, but it’s useful anywhere one would have used `Base.Fix2` as well.

If ever `args...` slurping becomes available for the first or middle arguments, use of backfix `\>` could become more generally useful as people begin to see the last argument position as a viable location for important arguments (similar to filenames coming last in command line arguments). But until then…

> [@Palli](#):
>
> Whatever we do, TAB completion should be an/the (main) objective. I think that’s the main reason OOP people like OOP, not because it’s single-dispatch.

This sentiment is important.

Encapsulating methods in classes is rendered largely unnecessary by multiple dispatch; the remaining wall to tear down is a respectable autocomplete, as [illustrated by this thread](https://discourse.julialang.org/t/my-mental-load-using-julia-is-much-higher-than-e-g-in-python-how-to-reduce-it/18902/).

---

_[View the full topic](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654)._
