Reputation: 4065
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
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
using the @pipe macro
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
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