
Hi, Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger. You can get it here: http://spirit.sourceforge.net/dl_more/phoenix-2.zip You can browse the draft docs here: http://tinyurl.com/6crgp What's new? A lot. This is a total rewrite based on earlier discussions with Jaakko Jarvi. The library's is built on top of Fusion and of course MPL. Of particular interest are local variables and lambda-lambda scopes: http://tinyurl.com/3mn6w There is also a set of lazy functions that work on STL sequences (e.g. push_back etc.): http://tinyurl.com/46bbm and pretty soon, a final TODO item (built on top of scopes/ lambda), lazy STL algorithms (e.g. find_if, etc). The scopes section (link provided above) in the docs illustrates how to write lazy functions that accept higher order functions (e.g. for_each). Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Hi. Here's a preview of Phoenix V2. ... You can browse the draft docs here: http://tinyurl.com/6crgp
Hi Joel, It looks interesting. I've only read the Starter Kit page so far. You went from this (without using the library): find_if(c.begin(), c.end(), &is_odd) To: find_if(c.begin(), c.end(), is_odd(arg1)); But your functor is a lot longer, and the advantage wasn't explained (or perhaps what I mean is that the advantage of lazy evaluation wasn't explained or demonstrated here). Is it any quicker to run? If the advantage is that you get better re-use, then I think you need a follow-on example that shows that re-use, and how that wouldn't be achieved with normal c++ functors. Darren

Darren Cook wrote:
Hi. Here's a preview of Phoenix V2. ... You can browse the draft docs here: http://tinyurl.com/6crgp
Hi Joel, It looks interesting. I've only read the Starter Kit page so far. You went from this (without using the library): find_if(c.begin(), c.end(), &is_odd)
To: find_if(c.begin(), c.end(), is_odd(arg1));
Actually, it's this: bool is_odd(int arg1) { return arg1 % 2 == 1; } find_if(c.begin(), c.end(), &is_odd) to this: find_if(c.begin(), c.end(), arg1 % 2 == 1) You seem to have missed that. It's easy to miss because it's shorter. http://tinyurl.com/6h4xr
But your functor is a lot longer, and the advantage wasn't explained (or perhaps what I mean is that the advantage of lazy evaluation wasn't explained or demonstrated here).
Is it any quicker to run? If the advantage is that you get better re-use, then I think you need a follow-on example that shows that re-use, and how that wouldn't be achieved with normal c++ functors.
I can't explain eveything in the starter kit. It's explained in latter parts of the doc: http://tinyurl.com/6kpcn. The starter kit is meant to be as concise as possible. However, the fact that you mentioned it makes me want to improve on it. Any suggestion is very welcome. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Darren Cook wrote:
But your functor is a lot longer, and the advantage wasn't explained (or perhaps what I mean is that the advantage of lazy evaluation wasn't explained or demonstrated here).
Is it any quicker to run? If the advantage is that you get better re-use, then I think you need a follow-on example that shows that re-use, and how that wouldn't be achieved with normal c++ functors.
I can't explain eveything in the starter kit. It's explained in latter parts of the doc: http://tinyurl.com/6kpcn. The starter kit is meant to be as concise as possible.
However, the fact that you mentioned it makes me want to improve on it. Any suggestion is very welcome.
Hmmm.... Ok, maybe I can put a blurb or that links to the main doc. Anyway, thanks for the comment. I think your suggestion (follow-up example that shows that re-use) might also work fine. It's hard to keep the starter kit as minimal as possible, yet sufficient. I'll think about it a some more. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

It looks interesting. I've only read the Starter Kit page so far. You went from this (without using the library): find_if(c.begin(), c.end(), &is_odd)
To: find_if(c.begin(), c.end(), is_odd(arg1));
Actually, it's this:
bool is_odd(int arg1) { return arg1 % 2 == 1; }
find_if(c.begin(), c.end(), &is_odd)
to this:
find_if(c.begin(), c.end(), arg1 % 2 == 1)
That seemed to be an intermediate stage as you then took it further and made a functor. If you'd stopped the tutorial at the above line I'd have had no complaint :-). Darren

Darren Cook wrote:
to this:
find_if(c.begin(), c.end(), arg1 % 2 == 1)
That seemed to be an intermediate stage as you then took it further and made a functor. If you'd stopped the tutorial at the above line I'd have had no complaint :-).
Understood. In that case, then I need to do something about it by emphasizing it more. At any rate, thanks for noting that. -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman <joel@boost-consulting.com> writes:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
val(3) val("Hello, World") The first evaluates to a nullary function (a function taking no arguments) that returns an int, 3. The second evaluates to a nullary function that returns a char const*, "Hello, World". Really? I'd have expected a char const(&)[13]. No? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Joel de Guzman <joel@boost-consulting.com> writes:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
val(3) val("Hello, World")
The first evaluates to a nullary function (a function taking no arguments) that returns an int, 3. The second evaluates to a nullary function that returns a char const*, "Hello, World".
Really? I'd have expected a char const(&)[13]. No?
You are right of course. My bad! Fixed. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman <joel@boost-consulting.com> writes:
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
If these basic rules are not followed, the result is either in error, or is immediately evaluated. Some examples: var(x) = 123 // good (lazy) x = 123 // oops (immediate) var(x)[0] // good (lazy) x[0] // oops (immediate) var(x)[var(i)] // good (lazy) x[var(i)] // bad and illegal (x is not a phoenix primitive or composite) var(x[var(i)]) // bad and illegal (x is not a phoenix primitive or composite) I would avoid attaching value judgements, and in this case, vertically align the comments: x = 123 // immediate var(x) = 123 // lazy x[0] // immediate var(x)[0] // lazy var(x)[var(i)] // lazy x[var(i)] // illegal (x is not a phoenix primitive or composite) var(x[var(i)]) // illegal (x is not a phoenix primitive or composite) And this leaves me wondering what about: var(x)[i] ?? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Joel de Guzman <joel@boost-consulting.com> writes:
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
If these basic rules are not followed, the result is either in error, or is immediately evaluated. Some examples:
var(x) = 123 // good (lazy) x = 123 // oops (immediate) var(x)[0] // good (lazy) x[0] // oops (immediate) var(x)[var(i)] // good (lazy) x[var(i)] // bad and illegal (x is not a phoenix primitive or composite) var(x[var(i)]) // bad and illegal (x is not a phoenix primitive or composite)
I would avoid attaching value judgements, and in this case, vertically align the comments:
x = 123 // immediate var(x) = 123 // lazy
x[0] // immediate var(x)[0] // lazy
var(x)[var(i)] // lazy x[var(i)] // illegal (x is not a phoenix primitive or composite) var(x[var(i)]) // illegal (x is not a phoenix primitive or composite)
Done. Thanks!
And this leaves me wondering what about:
var(x)[i]
Lazy. Equivalent to: var(x)[val(i)] Added to the examples. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel <joel@boost-consulting.com> writes: In my original posting, there were blank lines
I would avoid attaching value judgements, and in this case, vertically align the comments: -------------here------------------ x = 123 // immediate var(x) = 123 // lazy -------------here------------------ x[0] // immediate var(x)[0] // lazy -------------and here------------------ var(x)[var(i)] // lazy x[var(i)] // illegal (x is not a phoenix primitive or composite) var(x[var(i)]) // illegal (x is not a phoenix primitive or composite)
Done. Thanks!
-- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Joel <joel@boost-consulting.com> writes:
In my original posting, there were blank lines
[...] Done. Thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

David Abrahams wrote:
Joel <joel@boost-consulting.com> writes:
In my original posting, there were blank lines
[...] Done. Thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
You can get it here: http://spirit.sourceforge.net/dl_more/phoenix-2.zip
I like it!
You can browse the draft docs here: http://tinyurl.com/6crgp
There is a typeo in the table at composite.html#phoenix.operator: Include Files: #include <boost/spirit/phoenix/operator/self.hppp> ---------------------------------------------------^
What's new? A lot. This is a total rewrite based on earlier discussions with Jaakko Jarvi. The library's is built on top of Fusion and of course MPL.
Of particular interest are local variables and lambda-lambda scopes: http://tinyurl.com/3mn6w
There is also a set of lazy functions that work on STL sequences (e.g. push_back etc.): http://tinyurl.com/46bbm
and pretty soon, a final TODO item (built on top of scopes/ lambda), lazy STL algorithms (e.g. find_if, etc). The scopes section (link provided above) in the docs illustrates how to write lazy functions that accept higher order functions (e.g. for_each).
I have written lazy veraions of pair.first and pair.second (see attachment). Regards, Reece // (C) Copyright 2004: Reece H. Dunn. Distributed under the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_SPIRIT_PHOENIX_STL_UTILITY_HPP #define BOOST_SPIRIT_PHOENIX_STL_UTILITY_HPP #include <boost/spirit/phoenix/function/function.hpp> namespace boost { namespace phoenix { namespace stl { template< typename C > struct first_type_of{ typedef typename C::first_type type; }; template< typename C > struct second_type_of{ typedef typename C::second_type type; }; struct first { template< typename C > struct apply { typedef typename first_type_of< C >::type & type; }; template< typename C > typename apply< C >::type operator()( C & c ) const { return c.first; } }; struct second { template< typename C > struct apply { typedef typename second_type_of< C >::type & type; }; template< typename C > typename apply< C >::type operator()( C & c ) const { return c.second; } }; } /** Get the first item in a pair. * The standard way of accessing the first item in a pair is to use the * p.first syntax. This will not work in a lazy context: * arg1.first; // error: first not a member of arg1. * To make this work in a lazy context, you need to use the first function: * first( arg1 ); // lazy evaluation. */ function< stl::first > const first = stl::first(); /** Get the second item in a pair. * The standard way of accessing the second item in a pair is to use the * p.second syntax. This will not work in a lazy context: * arg1.second; // error: second not a member of arg1. * To make this work in a lazy context, you need to use the second function: * second( arg1 ); // lazy evaluation. */ function< stl::second > const second = stl::second(); }} #endif

Reece Dunn wrote:
Joel de Guzman wrote:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
You can get it here: http://spirit.sourceforge.net/dl_more/phoenix-2.zip
I like it!
Thanks!
There is a typeo in the table at composite.html#phoenix.operator:
Include Files:
#include <boost/spirit/phoenix/operator/self.hppp>
Fixed. Thanks!
I have written lazy veraions of pair.first and pair.second (see attachment).
Nice! Seems like a beginning of a utility module. If you'd like to submit it as part of the library, I'd need a test program. I'd also request conformance with the implied coding styles for the sake of consistency. Many thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel wrote:
Reece Dunn wrote:
I have written lazy veraions of pair.first and pair.second (see attachment).
Nice! Seems like a beginning of a utility module. If you'd like to submit it as part of the library, I'd need a test program.
Done. Note that the libs/spirit/phoenix/test/Jamfile.v2 needs + # bring in rules for testing + import testing ; at the top to allow you to run bjam from that directory, otherwise it complains about 'run' being unrecognised.
I'd also request conformance with the implied coding styles for the sake of consistency.
Done.
Many thanks!
:) Regards, Reece

Reece Dunn wrote:
Joel wrote:
Reece Dunn wrote:
I have written lazy veraions of pair.first and pair.second (see attachment).
Nice! Seems like a beginning of a utility module. If you'd like to submit it as part of the library, I'd need a test program.
Done. Note that the libs/spirit/phoenix/test/Jamfile.v2 needs
+ # bring in rules for testing + import testing ;
Great! Many thanks! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman <joel@boost-consulting.com> writes:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
I've been wondering, now that result_of is semi-standard, whether we really should have used apply<> in the Lazy function interface, rather than result<>, as that is compatible with result_of. Maybe there's a SFINAE way to make either one work? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Joel de Guzman <joel@boost-consulting.com> writes:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
I've been wondering, now that result_of is semi-standard, whether we really should have used apply<> in the Lazy function interface, rather than result<>, as that is compatible with result_of. Maybe there's a SFINAE way to make either one work?
:) Phoenix used to use result<>. Yes, "result" has certain advantages. Another is backward compatibility with Phoenix-1. However, compatibility with MPL is important too. So, I don't really know what to say. Have them both? ... Oh BTW, Dave: Dan Marsden has incorporated most of your review issues into the documentation. Thanks Dan! And Thanks for your review Dave! I shall upload an updated copy as soon as possible. Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman <joel@boost-consulting.com> writes:
David Abrahams wrote:
Joel de Guzman <joel@boost-consulting.com> writes:
Hi,
Hi. Here's a preview of Phoenix V2. This will probably be the last release of the library. Phoenix V2 will be the basis of the Phoenix and Boost.Lambda merger.
I've been wondering, now that result_of is semi-standard, whether we really should have used apply<> in the Lazy function interface, rather than result<>, as that is compatible with result_of. Maybe there's a SFINAE way to make either one work?
:) Phoenix used to use result<>. Yes, "result" has certain advantages. Another is backward compatibility with Phoenix-1. However, compatibility with MPL is important too. So, I don't really know what to say. Have them both?
Seems to me that for Phoneix, result<>/result_type is much more useful/appropriate than apply<>/type. I now lean toward the same for Fusion. Yes, I know I was the one who suggested you go the other way :( You can make adapters that help when you need both.
... Oh BTW, Dave: Dan Marsden has incorporated most of your review issues into the documentation. Thanks Dan! And Thanks for your review Dave! I shall upload an updated copy as soon as possible.
Looking forward to it. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (5)
-
Darren Cook
-
David Abrahams
-
Joel
-
Joel de Guzman
-
Reece Dunn