Similar to this effort, Eric Niebler's range library [1,2] aims at improving algorithm composability. The range library offers both an eager and lazy API. This is the lazy version (views):
int sum = accumulate(view::ints(1)
| view::transform([](int i) {return i * i;})
| view::take(10), 0);
And this the eager (via actions):
extern std::vector<int> read_data();
std::vector<int> vi = read_data(); action::unique;
vi = std::move(vi) | action::sort | action::unique;
Eric puts in a lot of effort to make this library part of the C++ standard (see proposal N4128 [3]).
Using "|" to indicate flow of data from producer to consumer is idiomatic, if you consider the Unix command line. Personally, I find this kind of operator overloading tasteful and sensical.
[1] https://github.com/ericniebler/range-v3
[2] User Manual with code examples: https://ericniebler.github.io/range-v3/index.html
[3] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n412...