
At Sun, 19 Dec 2010 13:40:42 -0500, Brent Spillner wrote:
I uploaded sample code to the Vault (in the "Miscellaneous/" directory) that provides a concise notation for list comprehensions. The comprehensions are evaluated lazily and can be used to populate a std::list, vector, or deque, appended to the same, inserted after a given iterator, or interpreted as a boost::range, including compatibility with BOOST_FOREACH. Containers, iterator-defined ranges, or nullary function objects can be used as generators, and arbitrary function objects can be used to specify filter conditions.
I love it!!
For example, the Pythagorean Triples example from http://rosettacode.org/wiki/List_comprehensions can be coded as
std::vector< boost::tuple<int,int,int> > triples =_(x, y, z)[x <<= range(1, n), y <<= range(x, n), z <<= range(y, n), x*x + y*y == z*z];
, and the (toy) prime number generator at http://www.secnetix.de/olli/Python/list_comprehensions.hawk can be implemented as
std::vector<int> nonprimes = _(j)[i <<= range(2, sqrt_max), j <<= range(2 * i, sqrt_max * sqrt_max, i)];
boost::function<std::vector<int>::const_iterator ()> is_composite = bind(std::find<std::vector<int>::const_iterator, int>, nonprimes.begin(), nonprimes.end(), ref(p));
Not sure the above is portable, FWIW. Last I recall you can't take the address of standard library functions (because of the possibility of overloads causing ambiguity).
BOOST_FOREACH(int x, (_(p)[p <<= range(2, sqrt_max * sqrt_max), call(is_composite) == nonprimes.end()])) { std::cout << x << std::endl; }
I'm usually interested in comprehensions like (in Python): [ x, foo(x) for x in some_other_sequence ] and your consistent use of range() above obscures whether "for x in some_other_sequence" can be modeled in general. Can I substitute any sequence for range(...) in the above examples? Anyway, very promising. Keep up the great work! -- Dave Abrahams BoostPro Computing http://www.boostpro.com