Fixing the Piping/Chaining Issue

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.

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.

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

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.

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 :wink: 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…

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.

1 Like