C++ Streams
jscheiny.github.io
jscheiny.github.io
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]).[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...
total = sum $ take 10 (map (\x->x*x) [1..])
For this C++ code: int total = MakeStream::counter(1)
| map_([] (int x) { return x * x; })
| limit(10)
| sum();
C++ code doesn't look that bad! let total = (1..).map(|x| x*x).take(10).sum();
to have no more overhead than the ideal Haskell code (though I could be oblivious to some very important GHC optimization... when posed this question my Haskell-using friends simply respond with "it's complicated"). let total = (1..).map(|x| x*x).take(10).fold(0, |acc, x| acc+x);
You could replace the fold with ".sum()" if you use the unstable std::iter::AdditiveIterator. Or you could incorporate the squaring map into the fold, but then we're no longer comparing the same thing. let total = (1..).map(|x| x * x).take(10).fold(0, Add::add);
This is an application of UFCS, which allows you to call methods as regular functions. int total = recurrence!"n+1"(0)
.map!(x => x*x)
.take(10)
.sum();
Replacing that last sum() with reduce() from std.parellelism and you can sum them using multiple threads (obviously not useful with a set this small but the documentation for reduce() coincidentally includes a benchmark for the sum of squares running 2.5x faster when done in parallel).int total = iterate(0, n -> n + 1).map(x -> x*x).limit(10).sum();
int total = IntStream.rangeClosed(1, 10).map(x -> x*x).sum();
using namespace folly::gen;
auto total = seq(1) | mapped([](auto i) { return i * i; }) | take(10) | sum; >>> sum(x*x for x in xrange(1,11))
385
You could use a map in Python as well, but really, the generator expression is much cleaner: >>> sum(map(lambda x: x*x, xrange(1,11)))
385The C++ equivalent of your Python would be something like:
typedef boost::counting_iterator<int> ci;
auto sum = std::accumulate(ci(0), ci(10), 0, [](auto x, auto y) { return x + (y*y); });
No special streaming library required. >>> from itertools import islice,count
>>> sum(x*x for x in islice(count(1),10))
385 +/*:>:i.10
It's kind of cheating because J doesn't really do lazy evaluation of infinite sequences AFAIK, but I thought it was fun.EDIT:
i. integer range
*: square
>: increment
+/ sum
so this reads sort of like: sum(square_each(increment_each(integer_range(10))) +/2*⍨⍳10
No need for increment, since index is set to start at 1. You can set it to 0 too, if you work that way.+ addition
/ reduce
2 (to be fed to exponential operator * for square)
* exponential
⍨ commute
⍳ iota - index generator
I would consider C++ with this library over Haskell just because you get the world of C++, but with a bit more of the expressiveness I like in the functional languages.
sum [x^2 | x <- [1..10]]Prelude is functional, C++ STL and the C library are imperative.
There is a valid argument that a 'good ol' fashioned' bit of procedural code (for loop) makes this same algorithm easier to read than either of these (it certainly makes it shorter), since it tells you explicitly what it is doing rather than assuming (usually a safe assumption) that programmers can understand and trust things like sum, map and take/limit.
i'm thinking of something like:
int iTotal = 0;
for( int i = 0; i < 10; ++i )
{
iTotal += i * i;
}(Not to say this is an example of bug-due-to-process-over-intention, but you do have a bug – you're summing from 0 to 9 instead of 1 to 10.)
or do you mean the bit about it being less code and easier to read?
well done on catching the bug. :)
this is my own fault for being sloppy and not paying attention.
var total = Stream
.iterate(0, function (n) {
return n + 1;
})
.map(function (x) {
return x * x;
})
.limit(10)
.sum(); var Lazy = require('lazy.js');
var total = Lazy
.generate(i => i + 1)
.map(i => i * i)
.take(10)
.sum();
C#, with LINQ: IEnumerable<int> NaturalNumbers()
{
var i = 1;
while (true)
yield return i++;
}
var total = NaturalNumbers().Select(n => n * n).Take(10).Sum();
As, of course, int has a maximum, it would be more sensible to use: Enumerable.Range(1, int.MaxValue).Select(n => n * n).Take(10).Sum();
And if you already know that you want 10, as in the above, you'd likely do: Enumerable.Range(1, 10).Select(n => n * n).Sum(); (->> (rest (range)) (map #(* % %)) (take 10) (reduce +)) let total = Seq.initInfinite ((+) 1)
|> Seq.map (fun x -> x*x)
|> Seq.take 10
|> Seq.sum
Alternatively one could use [1..System.Int32.MaxValue] to create the initial sequence.It's definitely possible (même likely?) there are other more subtle things in use too.
In any case, most of C++14 (outside of automatic lambda parameter deduction) can be emulated or straight copied into C++ using C++11. Most of the implementations of library specific things can be found at [1], so if you find a feature in C++14 that you're missing, go ahead and search the draft standard files (most of which are verbatim the same implementation) and copy into your own project.
To be fair though, one of the bigger features of C++11 / C++14 brings to the table is just easier template / std::algorithm usage (via lambdas), and smart pointers. Beyond that, most things aren't as necessary or as widespread in use even within std / STL. So for the most part, if you (or parent) has been interested in learning some modern C++, for the most part you can start leveraging a lot of the more useful tools / tricks immediately, even if the compilers haven't fully implemented C++14 yet [2].
[1] https://isocpp.org/files/papers/
[2] My understanding is that libc++ and clang are fully caught up, but g++ / libstdc++ won't be 100% C++14 compliant until after gcc-5.0. Either way, the corner cases exist, but for the most part you can take advantage of most of the great areas of modern C++ without waiting for gcc-5.0.
Const iterators in the form of cbegin() and cend() member functions on the standard containers were part of C++11, I'm pretty sure. It's either that or the C++ Primer 5e included some post-C++11 things in it.
What was missing from C++11, and probably an oversight, was std::cbegin() and std::cend() free functions, a la std::begin() and std::end(), for overloading and C arrays and so forth.
[1]: https://github.com/facebook/folly/blob/75278c6326af4e6a81b87...
Tried Safari, it's working as well.
http://www.boost.org/doc/libs/1_57_0/libs/range/doc/html/ran...
interesting stuff... although i do not enjoy the novel operator overloading, it does keep it tidy.