ParamPipe - parameterized pipe in Elixir

Thanks for you reply, but I think your logic is wrong. If something is useless in one situation, you think it is useless in all situations.

I just gave the most complex/possible example to use. I never say that I will use foo function in real world.

I give you an example: https://github.com/cjen07/infix/blob/master/lib/infix/infix.ex
in which file and {l0, l1} are temporary varaible, if you use this library, the pipe will not be broken into three parts.

By the way, metaprogramming/abstraction means less code but same functionality. Readability, I think, is not the only goal or even the goal in this process, similarly, I donā€™t think while(n < 10) cout << n++; increases any readability.

If the first time you learned the syntax &(&1), and you think it increases any readability than (fn x -> end) , I will apologize.

This example is not the real world case. I think there are other situations like case/cond that will break the original pipe operater into parts, which I dislike when coding in such a flexible language.

And if you look into the source code of param_pipe, despite it is short, perhaps, you will find it is hard to understand (in your words, completely indecipherable) unless you are familiar with Macro.unpipe

I think there is some confusion between readability and familiarity. Of course a construct someone is not familiar will be unreadable to most.

The trouble with this proposal is that it puts the burden on reading code even when I am familiar with the construct, the pipe operator. When I read the examples above, I need to manually unwind the operator and place the argument on where it needs to be. It prioritizes writing code over reading code and thatā€™s a trade-off I would hardly make.

Every time I want to pipe to another argument, I write a private function and give it a decent name. No shortcuts. And the final code will read better too.

5 Likes

You are certainly right, I will try to make an improvement in such a direction. I think assigning a variable within this pipe operator is at least an update/improvement of this library, just in another direction, after all I spent a whole afternoon in adding this. Much more to be done. :slight_smile:

upgrade to 0.1.3, support elixir v1.6.1

2 Likes

fix a bug, more tests added, assigning a variable when piping into anonymous function is supported, Erlang 20.2, Elixir v1.6.2

I appreciate anyone who is willing to contribute or to find more bugs :wink:

1 Like

I think Clojureā€™s solution is quite elegant here : it has -> and ->> (thread-first and thread-last macros) and as-> (kind of a mix between compose and a let-binding). It also has some-> and some->> (null-safe piping) and cond-> and cond->> (conditional piping).

|> and |>> might be enough compared to the possibly not very readable |n>

1 Like

I donā€™t think Clojure way is elegant, and is just syntax-level. I think readability is important but I think it refers to the whole code and the module orchestration. When you read code with proper readability, you can easily tell if some piece of code is relavant or not to your task.

Anyway, parampipe 0.2.0 that confroms with elixir 1.7.3 is published

1 Like

Hello @cjen07
Whatā€™s the status of this project?

When I started to practice more and more Elixir, I immediately found myself in the same need.
That is, using an indexed pipe operator (it was the name that came into my mind).

Indeed, one of the use case I thought was when transforming data (usually done with functions that take the data as a first argument) and then finishing with a kind of a final function (like write, save and the like) that takes the data in other place than the first argument.

I also found that many functions from erlang modules could take what usually is the first argument on elixir side functions in the last positionā€¦

So I just did a google search for elixir indexed pipe and without surprised it gave some results, this post being the first.

I read the thread and I should admit that many points (e.g. the ones from @NobbZ) are relevant.

For example in a transformation pipeline (where until the end every function take the data as the first argument) there is usually a write/save like function which takes the data in other positionā€¦
Well it makes sense to break the pipeline here since there is a change in the ā€œsemanticā€ā€¦
I mean, saving the result is not anymore about transforming the data.
So having an extra line better translates the intent.

Anyway, in my thought here is how I thought about this indexed operator:

  • First, definitely indexed at 1.
    |1> being the default |>.
    So the operator would have make sense only starting from |2>.
    Obviously it should be fully compatible with piping before or after with the default operator.
  • The |$> (symbol usually synonym of ending like in regex, vim etc.) for piping as the last argument no matter how many argument the function is taking.
  • The |#> (symbol for ignoring like in comments and because it has some kind of stroke effect) could have been used as a discarding pipe operator.
    This could definitely bring some confusion since the following function call will need the full set of its arguments.
    So what could have been the purpose here? Maybe if there is a need to produce a side effect like sending a notification or setting a flag (though I agree that this does NOT suit AT ALL the pureness of functions of FP paradigm) while itā€™s necessary to continue the pipeline with the previous data unmodifiedā€¦

I wanted to learn more about meta programming (still never practice macro, quote, unqote and the like) to experiment around this ideaā€¦

However as I said Iā€™m not sure anymore if this will not be more confusing than useful (particularly if itā€™s not a native functionality accepted by everyone).

Anyway, I still find this idea very great and might be interested to try your package in some projects to see if it might help or confuse in the long runā€¦
So just wanted to have some newsā€¦

Cheersā€¦

hello @Sanjibukai ,

Currently, I am doing timeseries algorithms using python and c++ (because of work), and itā€™s been almost a year since last time I did serious elixir coding.

I have read your thought, thatā€™s really interesting!

Feel free to add features to the project in any way!

Meta programming is fantastic and exciting and is quite next to program synthesis, the Holy Grail of computer science.

Hopefully you will benefit a lot from it.

Sincerely
Wang Chen

1 Like

This bring me several memories (as a former EE engineer worked a lot with signalsā€¦)

Yes Iā€™m pretty convinced of thatā€¦
Yet when I jumped into ruby (from assembly/c) I was astonished by Ruby meta-programming abilitiesā€¦
And Iā€™m sure that it will be ever more interesting in elixir.
Iā€™m just taking the time to embrace FP before going onā€¦

Anyway good luck to youā€¦

1 Like

Frankly speaking, I find the parametrized pipe hard to read and understand, so I donā€™t really have an intention to use the library. Having said that, I applaud your persistence and Iā€™m very happy that Elixir allows you to even do these things!

On a side note, I think an explicitly ā€œindexedā€ pipe would gain my interest (Iā€™m looking at you File.write). Something like:

data
|> foo(1, 2)         # pipe into the first argument
|>> bar(4, _, 6)     # pipe into the second

So the idea is here that thereā€™s a new operator and I can explicitly state which argument I want to pipe into. The |>> is far from perfect, since it breaks the alignment.