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("|", " ")
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.
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 :).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With