Francis Smart
Francis Smart

Reputation: 4065

Julia: Piping operator |> with more than one argument

I am attempting to pass multiple arguments to the built in piping operator in Julia |>.

I would like something that works like this:

join([randstring() for i in 1:100], " ")

However, using the piping operator, I get an error instead:

[randstring() for i in 1:100] |> join(" ")

I am pretty sure this is a feature of multiple dispatch with join having its own method with delim in the join(strings, delim, [last]) method being defined as delim="" when omitted.

Am I understanding this correctly? Is there a work around?

For what is is worth the majority of my uses of piping end up taking more than one argument. For example:

[randstring() for i in 1:100] |> join(" ") |> replace("|", " ")

Upvotes: 16

Views: 7498

Answers (2)

Ethan S-L
Ethan S-L

Reputation: 420

Metaprogramming to the rescue!

We'll use a simple macro to allow piping to multi-input functions.

    using Pipe, Random
    @pipe [randstring() for i in 1:100] |> join(_, " ")

So after calling the Pipe package all we're doing is

  1. using the @pipe macro

  2. designating where where to pipe to with the underscore ("_") [if the function only takes one input we don't need to bother with the underscore: e.g.

     @pipe 2 |> +(3,_) |> *(_,4) |> println   
    

will print "20"]

See here or here for more formal documentation of the Pipe package (not that there's much to document :).

Upvotes: 13

mbauman
mbauman

Reputation: 31372

The piping operator doesn't do anything magical. It simply takes values on the left and applies them to functions on the right. As you've found, join(" ") does not return a function. In general, partial applications of functions in Julia don't return functions — it'll either mean something different (via multiple dispatch) or it'll be an error.

There are a few options that allow you to support this:

  • Explicitly create anonymous functions:

    [randstring() for i in 1:100] |> x->join(x, " ") |> x->replace(x, "|", " ")
    
  • Use macros to enable the kind of special magic you're looking for. There are some packages that support this kind of thing.

Upvotes: 21

Related Questions