6 ms·
Well this can help when you have many nested functions that are chained together, for example, like this: auto r = select(where(numbers, [](int x) { return
by pfultz2 12y ago
Well this can help when you have many nested functions that are chained together, for example, like this:
auto r = select(where(numbers, [](int x) { return x > 2; }), [](int x) { return x * x; });
Because of nesting this can be hard to read(and even write). If we can make the function pipable, the above can be written like this:
auto r = numbers | where([](int x) { return x > 2; }) | select([](int x) { return x * x; });
Which it is easier to see what this does. So this blogpost goes over how to implement an utility that will take care of the boilerplate involved in writing a function that can be pipable.
It does take advantage of a lot of C++14 features to implement this such as such as vardiac templates, rvalue reference, generic lambdas, and auto type deduction, but those feature actually make it simpler. I have in the past implemented something similar for C++03 and the code looks awful with way too much noise.
> this is madness.
Why do you consider this madness?
Maybe my mind has already been warped by C++.
- grundprinzip 12y agoI really like your above example. For people coming from Ruby on Rails or Python Django, such a notation makes it simple to understand what the code will do, even without knowing how to implement it. Thanks
- pcmonk 12y agoTo me, the first is much easier to read, but perhaps my mind has been warped by functional programming languages. At any rate, the thing that's strange about it is how verbose and hackish everything is. It's obvious the language wasn't designed to do anything like this, so the only way you can incorporate features like this is with unnecessarily obtuse and complex blocks of code.
- pfultz2 12y ago> To me, the first is much easier to read, but perhaps my mind has been warped by functional programming languages. Actually, pipable is very similiar to haskell's `$` function. So a similiar thing is done to improve readability of chaining functions in functional languages as well. > At any rate, the thing that's strange about it is how verbose and hackish everything is. It's obvious the language wasn't designed to do anything like this, so the only way you can incorporate features like this is with unnecessarily obtuse and complex blocks of code. How is the code obtuse and complex? I am using fairly straightforward techniques. I understand that I am working around the lack of perfect capturing for lambdas, but it is not complicated or clever the workaround.
- jschwartzi 12y agoThe first one looks like you're chaining functions together, while the second one looks like you're taking multiple bitwise or operations over the result of each function. I think it's fascinating to see how the language can be extended. On the other hand I would not want to be the poor bastard stuck maintaining either construct after discovering some compiler edge case. If I've learned anything it's that just because you can do something doesn't mean you should. The issue with extending operators in this fashion is that you're violating the principle of least surprise. | is an operator that should only really do exactly what it always does--bitwise or. If composition of functions is fundamentally analogous to taking the bitwise or of two values then I would concede that your second syntax is a bit clearer. Personally I feel that this is not the case.
- pfultz2 12y ago> The issue with extending operators in this fashion is that you're violating the principle of least surprise. It is really common for the `|` operator to be used for piping functions together. There are several libraries that support it: [Boost.Range](http://www.boost.org/doc/libs/1_56_0/libs/range/doc/html/index.html http://www.boost.org/doc/libs/1_56_0/libs/range/doc/html/ind...), [PStade Oven](http://p-stade.sourceforge.net/oven/doc/html/index.html http://p-stade.sourceforge.net/oven/doc/html/index.html), [Linq](http://pfultz2.github.io/Linq/ http://pfultz2.github.io/Linq/), and [Streams](http://jscheiny.github.io/Streams/ http://jscheiny.github.io/Streams/). Plus, its even being proposed as part of the ranges library in future C++: https://github.com/ericniebler/range-v3/blob/master/doc/D4128.md https://github.com/ericniebler/range-v3/blob/master/doc/D412... So just as the bit shift operators in C++ also have the meaning of streaming in and out, the bitwise or also has the meaning of pipe, so this is should not at all be a suprise.
- jschwartzi 12y agoInteresting. I was not aware of this, so thank you.
- nawitus 12y agoI'd say JavaScript-style chaining is more (or atleast as) readable as that. E.g. numbers.where().select();