I keep finding myself wanting to do this:
def foo(m1, m2) do
m1
|> transform("some arg")
|> &other_func(m2, &1)
end
Which doesn’t work because |> only works with function calls, not functions.
If you convert it to a function call, it works! But the syntax is ugly.
def foo(m1, m2) do
m1
|> transform("some arg")
|> &(other_func(m2, &1)).()
end
Is there any reason to not make the first (prettier) form work? Basically, modify pipe operator to “if receive a function of arity 1, call the function passing in the arg”.
Or is there a better way to do what I’m trying to do? Thanks!
2 Likes
Im really not an expert, but if you can’t simply do
def foo(m1, m2) do
m1
|> transform("some arg")
|> other_func(m2)
end
Because m2 is the first argument of the function, I would probably made a helper function like this
def other_func_helper(m1, m2) do
other_func(m2, m1)
end
Of course i probably would think more about the naming. And as I said i’m not an expert, might misunderstood something, etc 
Ps. and if arguments are of different type I would probably do even
def other_func(m1, m2) when is_TYPE(m1) do # by type I mean list, map, whatever is good in your context.
other_func(m2, m1)
end
3 Likes
I’m not clear about what you’re trying to do either. Are you doing this simply to put the previously piped value as the 2nd argument?
1 Like
Yes, so you can keep the pipe going:
foo
|> transform1("data1")
|> transform2("data2")
|> &transform_with_args_in_wrong_order("data3", &1)
|> transform4("data4")
This has been discussed in various forms at great length on the core mailing list. Basically, write a small helper function, or break up the pipeline.
(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)
I feel you already have the solution there… If you find the .() too ugly just use a normal function wrapping your functionality. I think there is no better way, and the reason for not making the pipe is related to a discussion over lisp1 vs lisp2 function calls. Elixir just settles on one.
For instance, if you could have a variable contain an anonymous function in Elixir with zero arguments, it would be very difficult for Elixir to know when that function should be called or be used as a value, as the parenthesis may be omitted.
http://stackoverflow.com/questions/4578574/what-is-the-difference-between-lisp-1-and-lisp-2
2 Likes
There are really two subject matters at work here.
foo
|> bar.()
just isn’t that bad. What’s ugly is
foo
|> &(bar(x, &1).()
```
but this latter problem simply stems from a wrong approach to piping in the first place.
As has been covered extensively in the relevant mailing list threads, the solution is to either:
```
thing =
foo
|> bar
|> baz
other_value
|> fun(thing)
|> etc
```
OR
```
def helpfully_named_fun(piped_value, other_value), do: fun(other_value, piped_value)
foo
|> bar
|> baz
|> helpfully_named_fun(other_value)
|> etc
```
Which is better depends on what produces the most readable code.
2 Likes