Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in order to pipe into an arbitrary argument, I will create a named function instead. My code becomes a bit more verbose, but I think it often comes with additional clarity. With that said, Lets get on with the discussion.
There was recently another proposal in order to pipe into an arbitrary argument of a function. I’m not really here to discuss the validity of that proposal. That proposal did get me to think about a potential different approach (that may or may not have come up in the past, please point me to it if it was brought up) that may get us (hopefully) 80% of what people are looking for.
When I see these discussions crop up, I realize that people are not showing “real” code most of the time and are just coming up with toy examples to show off the proposed syntax. With that said, it appears that people want to pipe into the second parameter more frequently (again, it may just be toy examples though).
So I am mostly here to ask, if you had to take a guess (and if you have some time, maybe scour a codebase or two), what percentage of time are you trying to pipe to the 2nd argument vs 3rd+. I’m not really interested in piping to the first, because we already have a working solution for that.
If it turns out that most of the time people are looking to pipe to the 2nd argument, Maybe we could implement flip/2
. The first argument is the value you want to become argument 2 of the second argument (that is comfusing…). Lets take a look at a couple examples
"foo"
|> String.upcase()
|> flip(Regex.scan(~r/foo/))
map
|> Map.get(:foo)
|> process()
|> flip(GenServer.call(pid, 10_000))
I got the idea from Haskell, though I’m sure something similar is in many languages. We are unable to do exactly the same thing because currying is not really a thing by default in Elixir. Haskell’s version is actually (a -> b -> c) -> b -> a -> c
, which roughly transaltes to the first argument being a function that takes 2 arguments, the secound argument is some value b
and the third argument being some value a
. Roughly translated to Elixir could look something like fn (fun, b, a) -> fun.(a, b) end
flip/2
would really only be intended to be used inside a pipe chain, because writing flip("foo", Regex.scan(~r/foo/))
is not as clear as Regex.scan(~r/foo/, "foo")
So if anyone has any thoughts on flip/2
, I would love to hear them. And if anyone can either go through some code, or take a guess at percentages for 2nd vs above 2nd argument for pipes, it would be appreciated.
Also, if you would like to test it out in some code, I threw the flip package up onto hex and you can find the code on github.