Phoenix3 port to proto complete

Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications) So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass - implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time Did I miss something? This is a very tight schedule, I may not be able to finish all points during the GSoC period. Any help will be appreciated. Additionally a review of the current code is highly appreciated to point out some defects that might exist. The code can be checked out at: https://svn.boost.org/svn/boost/sandbox/SOC/2010/phoenix3 I will be happy to answer your questions! Additionally I would like to thank Joel de Guzman and Eric Niebler for their great assistance and initial designs! Best Regards, Thomas Heller

On Fri, Jul 23, 2010 at 2:18 PM, Thomas Heller <thom.heller@googlemail.com>wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
Great news! Speaking as someone who's become a little lost in the maze of phoenix/lambda/proto/bind etc., I'm aware that this port is important for the general roadmap in this area, but am unsure exactly what this port buys us. Could you write a few paragraphs on what issues this solves, and what new capabilities are supported by this port. Many Thanks - Rob.

On Friday 23 July 2010 15:59:46 Robert Jones wrote:
On Fri, Jul 23, 2010 at 2:18 PM, Thomas Heller
<thom.heller@googlemail.com>wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
Great news!
Speaking as someone who's become a little lost in the maze of phoenix/lambda/proto/bind etc., I'm aware that this port is important for the general roadmap in this area, but am unsure exactly what this port buys us.
Could you write a few paragraphs on what issues this solves, and what new capabilities are supported by this port.
Many Thanks
Sure I'll try my best. The main motivation behind the port was from the review for phoenix2. One of the results was conditional acceptance if phoenix3 is implementend with proto as its underlying expression template engine, the other was to improve compatibility with bind, and lambda. Let me try to give an overview of the different components you addressed: Boost.Proto - The working horse behind phoenix3: It serves as the expression template engine and provides utilities to work with it. In general proto can be seen as a Domain Specific Embedded Language (DSEL) compiler construction kit for C++ (based on expression templates. There are already some in boost: spirit and xpressive based on proto. Phoenix is nothing more than DSEL. Well, it is a little special, as it aims to be C++ in C++. With Boost.Proto we have the unique possibilty to (more or less) easily introspect our pheonix expression and do lots of cool stuff with it. Boost.Bind - The competitor of phoenix::bind: Boost.Bind exists for a long time now. phoenix::bind shall be completely compatible to Boost.Bind (API wise). However it shall not replace Boost.Bind, because Boost.Bind has some advantages over phoenix::bind (compile time, legacy compiler support). Boost.Lambda - The predecessor of Boost.Phoenix: Boost.Lambda is the one library which inspired to Joel de Guzman to build Phoenix in the first place. It shares many similarities, but phoenix is built upon more modern concepts. IIUC, the plan was to deprecate Boost.Lambda at some point in favor of phoenix. Some needs to clarify this a bit more. C++0x lambdas - The competitor of Boost.Phoenix: As you heard, C++0x will have its own lambdas. Phoenix will be completely interoperable with C++0x. There will be a section in the new phoenix documentation covering advantages/disadvantages and stuff. I hope you can wait until then. You are welcome.

On Fri, Jul 23, 2010 at 3:25 PM, Thomas Heller <thom.heller@googlemail.com> wrote:
On Friday 23 July 2010 15:59:46 Robert Jones wrote:
On Fri, Jul 23, 2010 at 2:18 PM, Thomas Heller
<thom.heller@googlemail.com>wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
Great News!! [...]
With Boost.Proto we have the unique possibilty to (more or less) easily introspect our pheonix expression and do lots of cool stuff with it.
Is Phoenix finally compatible with result_of instead of using its own protocol?
Boost.Bind - The competitor of phoenix::bind: Boost.Bind exists for a long time now. phoenix::bind shall be completely compatible to Boost.Bind (API wise). However it shall not replace Boost.Bind, because Boost.Bind has some advantages over phoenix::bind (compile time, legacy compiler support).
but phoenix::bind is polymorphic like std::bind, while boost::bind is still monomorphic, right?
Boost.Lambda - The predecessor of Boost.Phoenix: Boost.Lambda is the one library which inspired to Joel de Guzman to build Phoenix in the first place. It shares many similarities, but phoenix is built upon more modern concepts. IIUC, the plan was to deprecate Boost.Lambda at some point in favor of phoenix. Some needs to clarify this a bit more.
As far as I remember from the review, it was decided that Phoenix would just replace boost.lambda (except that boost.lambda would be kept for backward compatibility for some releases); keeping compatibility with the Lambda api was hard and just not worth it.
C++0x lambdas - The competitor of Boost.Phoenix:
as long as C++0x lambdas stay monomorphic, there is really no competition :D. Great job! -- gpd

Giovanni Piero Deretta wrote:
On Fri, Jul 23, 2010 at 3:25 PM, Thomas Heller <thom.heller@googlemail.com> wrote:
On Friday 23 July 2010 15:59:46 Robert Jones wrote:
On Fri, Jul 23, 2010 at 2:18 PM, Thomas Heller
<thom.heller@googlemail.com>wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
Great News!!
[...]
With Boost.Proto we have the unique possibilty to (more or less) easily introspect our pheonix expression and do lots of cool stuff with it.
Is Phoenix finally compatible with result_of instead of using its own protocol?
Yes!
Boost.Bind - The competitor of phoenix::bind: Boost.Bind exists for a long time now. phoenix::bind shall be completely compatible to Boost.Bind (API wise). However it shall not replace Boost.Bind, because Boost.Bind has some advantages over phoenix::bind (compile time, legacy compiler support).
but phoenix::bind is polymorphic like std::bind, while boost::bind is still monomorphic, right?
std::bind and boost::bind are both monomorphic. phoenix::bind is polymorphic!
Boost.Lambda - The predecessor of Boost.Phoenix: Boost.Lambda is the one library which inspired to Joel de Guzman to build Phoenix in the first place. It shares many similarities, but phoenix is built upon more modern concepts. IIUC, the plan was to deprecate Boost.Lambda at some point in favor of phoenix. Some needs to clarify this a bit more.
As far as I remember from the review, it was decided that Phoenix would just replace boost.lambda (except that boost.lambda would be kept for backward compatibility for some releases); keeping compatibility with the Lambda api was hard and just not worth it.
That is correct.
C++0x lambdas - The competitor of Boost.Phoenix:
as long as C++0x lambdas stay monomorphic, there is really no competition :D.
I agree :)
Great job!
Thanks!

On Fri, Jul 23, 2010 at 11:23 AM, Thomas Heller <thom.heller@googlemail.com> wrote:
Giovanni Piero Deretta wrote:
but phoenix::bind is polymorphic like std::bind, while boost::bind is still monomorphic, right?
std::bind and boost::bind are both monomorphic. phoenix::bind is polymorphic!
Just to be clear, std::bind is polymorphic. This is specified in 20.8.10.1.2 paragraph 3: the return type of the bind call wrapper is derived from the argument dependent result_of<>::type for the bound object. Grats by the way! Can't way to use the new Phoenix! Daniel Walker

On 7/24/10 5:31 AM, Ahmed Charles wrote:
std::bind and boost::bind are both monomorphic. phoenix::bind is polymorphic!
Would you (or anyone else) mind explaining polymorphic vs monomorphic in this context? Or point to an explanation?
When you bind a function-pointer or member-function pointer, you are passing in an exact signature with exact argument and return types (e.g. int(*)(int)). OTOH, when you bind a function-object, the bound function object may have various overloads or templates that deal with different argument and return types. However, without decltype, we can't deduce the return type from argument types. The original protocol was to require function objects to have a typedef result_type. But this forces them to be monomorphic since you can't choose the return type depending on the argument types that are actually passed. The new result_of protocol fixes this. Phoenix had polymorphic bind from day one, albeit with a different "resulf" protocol that predates "result_of". Actually, if you look at the result_of documentation, Phoenix is one of the inspirations. Phoenix3 now uses the standard result_of protocol. (http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html) Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

(cross-posting to the proto list) On 7/23/2010 10:25 AM, Thomas Heller wrote:
On Friday 23 July 2010 15:59:46 Robert Jones wrote:
On Fri, Jul 23, 2010 at 2:18 PM, Thomas Heller
<thom.heller@googlemail.com>wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
Great news!
Speaking as someone who's become a little lost in the maze of phoenix/lambda/proto/bind etc., I'm aware that this port is important for the general roadmap in this area, but am unsure exactly what this port buys us.
Could you write a few paragraphs on what issues this solves, and what new capabilities are supported by this port. <snip>
Let me expand a bit on Thomas' post with my own perspective. Currently, the expressions created by Boost.Bind, Boost.Lambda and Boost.Phoenix2 are black boxes. You can pass them to std algorithms for evaluation, but that's about it. In contrast, the expressions created by Boost.Phoenix3 will the Proto expressions. If Phoenix3 is the compiler of a C++-in-C++ domain specific language, then the Proto expression is the intermediate form. It will be documented and part of the Phoenix3 API. The grammar for valid Phoenix3 expressions will also be documented and extensible. For the first time, we will have a way to generate C++-like expression trees, just like the C++ compiler itself does. We have a standard way (Proto) to traverse and manipulate them. Sure, you can just evaluate them as you could before, but now you can do much more. For instance, you can define your own Proto transforms to: - Do various optimizations, just like a real compiler - Add your own custom evaluation strategies for operations on your types - Rewrite Phoenix3 expressions for parallel execution, or whatever - ???!!! Essentially, it means Phoenix3 is a white box, an open platform. Third parties can use just the Phoenix3 front end and intermediate form, substituting their own back ends to make the expressions mean and do completely different and domain-specific things. Expect to see Phoenix3 expressions showing up in other DSEL contexts. It's hard to predict how people will use this. The possibilities are really limitless. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 23/07/10 17:32, Eric Niebler wrote
- Rewrite Phoenix3 expressions for parallel execution, or whatever
Note that it's exactly what I am doing atm after checkign out the P3 code :o Other stuff it adds is the possibility of some JIT stuff from C++ like expression. For ppl who where at Boost'Con 09, next version of Quaff will be based on phoenix 3.

On 7/23/2010 11:42 AM, joel falcou wrote:
On 23/07/10 17:32, Eric Niebler wrote
- Rewrite Phoenix3 expressions for parallel execution, or whatever
Note that it's exactly what I am doing atm after checkign out the P3 code :o Other stuff it adds is the possibility of some JIT stuff from C++ like expression.
For ppl who where at Boost'Con 09, next version of Quaff will be based on phoenix 3.
Awesome. I hope you give status updates on proto@lists.boost.org. This is important real-world usage, and the time for that is now while we still have time to make changes and improvements based on your feedback. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 10-07-23 11:32 AM, Eric Niebler wrote:
In contrast, the expressions created by Boost.Phoenix3 will the Proto expressions. If Phoenix3 is the compiler of a C++-in-C++ domain specific language, then the Proto expression is the intermediate form. It will be documented and part of the Phoenix3 API. The grammar for valid Phoenix3 expressions will also be documented and extensible. For the first time, we will have a way to generate C++-like expression trees, just like the C++ compiler itself does. We have a standard way (Proto) to traverse and manipulate them. Sure, you can just evaluate them as you could before, but now you can do much more.
I'd just like to echo that this functionality is awesome. Heck, I already have two past use cases in mind, let alone what is now possible. Maybe if we hobble along doing this kind of research and practical work enough, C++ will get real meta-programming in 20-something. Although the monomorphic lambdas in C++0x do dampen the enthusiasm a bit... My heartfelt thanks to all Boost library authors, in particular from Boost.Bind to the Proto rewrite. Your work makes the life of thousands of programmers better and keeps C++ interesting and useful.

On 7/23/10 11:32 PM, Eric Niebler wrote:
Essentially, it means Phoenix3 is a white box, an open platform. Third parties can use just the Phoenix3 front end and intermediate form, substituting their own back ends to make the expressions mean and do completely different and domain-specific things.
Expect to see Phoenix3 expressions showing up in other DSEL contexts. It's hard to predict how people will use this. The possibilities are really limitless.
I couldn't have said so better myself. Let me emphasize that Eric and I (with the helf of Joel Falcou and Thomas Heller of course) have taken extreme attention to detail with Phoenix3's extension mechanism. To me, this is the most crucial point. To some extent, Phoenix2 is already a "white-box" due to its extension mechanism. People have already been using and extending Phoenix2 in ways I haven't imagined before. The underlying infrastructure of Phoenix2 is Fusion. This time, the underlying infrastructure is Proto. Expect a lot more power from this concoction! Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On 7/23/10 10:25 PM, Thomas Heller wrote:
Boost.Lambda - The predecessor of Boost.Phoenix: Boost.Lambda is the one library which inspired to Joel de Guzman to build Phoenix in the first place. It shares many similarities, but phoenix is built upon more modern concepts. IIUC, the plan was to deprecate Boost.Lambda at some point in favor of phoenix. Some needs to clarify this a bit more.
Yes. Boost.Lambda will go into maintenance mode. It will be deprecated in favor of Boost.Phoenix but will remain available in parallel for a long time still for backward compatibility. We will have to assimilate as much as we can from Lambda, esp. the tests and documentation. Some years ago, the plan was to eventually assimilate even the name Boost.Lambda. I'm not sure that's desirable anymore since Phoenix has taken a life of its own. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On 23/07/10 14:18, Thomas Heller wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass - implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time
Did I miss something?
I would quite like to know how Phoenix 3 compares to Phoenix 2 in terms of compile speed, even if you haven't fully optimized it yet.

Mathias Gaunard wrote:
On 23/07/10 14:18, Thomas Heller wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass - implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time
Did I miss something?
I would quite like to know how Phoenix 3 compares to Phoenix 2 in terms of compile speed, even if you haven't fully optimized it yet.
Let me give you a small example of what situation we currently have: For this test i used the core/primitives_test.cpp test and g++ 4.5 Phoenix3 total compile time: 3.421s Phoenix3 preprocess time: 1.755s Phoenix3 compile time of preprocessed code: 1.835s Phoenix2 total compile time: 1.891s Phoenix2 preprocess time: 0.745s Phoenix2 compile time of preprocessed code: 1.106s comparing with clang: Phoenix3 total compile time: 3.901s Phoenix3 preprocess time: 2.738s Phoenix3 compile time of preprocessed code: 1.273s Phoenix2 total compile time: 2.015s Phoenix2 preprocess time: 1.320s Phoenix2 compile time of preprocessed code: 0.788s These timings may not be very represantative, but show in what state we currently are, and that there is a high potential to reach phoenix2 compile times.

On Fri, Jul 23, 2010 at 11:14 AM, Thomas Heller <thom.heller@googlemail.com> wrote:
Mathias Gaunard wrote:
On 23/07/10 14:18, Thomas Heller wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass - implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time
Did I miss something?
I would quite like to know how Phoenix 3 compares to Phoenix 2 in terms of compile speed, even if you haven't fully optimized it yet.
Let me give you a small example of what situation we currently have:
For this test i used the core/primitives_test.cpp test and g++ 4.5
Phoenix3 total compile time: 3.421s Phoenix3 preprocess time: 1.755s Phoenix3 compile time of preprocessed code: 1.835s
Phoenix2 total compile time: 1.891s Phoenix2 preprocess time: 0.745s Phoenix2 compile time of preprocessed code: 1.106s
comparing with clang:
Phoenix3 total compile time: 3.901s Phoenix3 preprocess time: 2.738s
Ouch! The Clang guys will be looking into this preprocessor-performance issue to see if we can do better. Thanks for reporting this! - Doug

On 7/23/2010 9:18 AM, Thomas Heller wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass - implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time
Did I miss something?
You did not miss anything but before the world ends, or the sun burns out, documentation for Phoenix in a Boost distribution would be most desirable.

On 23 July 2010 21:57, Edward Diener <eldiener@tropicsoft.com> wrote:
You did not miss anything but before the world ends, or the sun burns out, documentation for Phoenix in a Boost distribution would be most desirable.
http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/index.html

On 7/24/10 5:48 AM, Daniel James wrote:
On 23 July 2010 21:57, Edward Diener<eldiener@tropicsoft.com> wrote:
You did not miss anything but before the world ends, or the sun burns out, documentation for Phoenix in a Boost distribution would be most desirable.
http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/index.html
In the POV of the user, this documentation is still highly relevant. We will have to overhaul the extension mechanim docs though. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On 7/23/2010 5:48 PM, Daniel James wrote:
On 23 July 2010 21:57, Edward Diener<eldiener@tropicsoft.com> wrote:
You did not miss anything but before the world ends, or the sun burns out, documentation for Phoenix in a Boost distribution would be most desirable.
http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/index.html
And how is anybody supposed to find this from a Boost distribution when Phoenix is not listed as a library ? My understanding is that Phoenix works outside of Spirit and so should be documented separately, with whatever links Spirit decides to have to it being Spirit's own business. But if I am wrong and Phoenix is a library only to be used from Spirit, or always to be connected to Spirit and never used otherwise, I will gladly stand corrected.

On 7/24/10 9:35 AM, Edward Diener wrote:
On 7/23/2010 5:48 PM, Daniel James wrote:
On 23 July 2010 21:57, Edward Diener<eldiener@tropicsoft.com> wrote:
You did not miss anything but before the world ends, or the sun burns out, documentation for Phoenix in a Boost distribution would be most desirable.
http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/index.html
And how is anybody supposed to find this from a Boost distribution when Phoenix is not listed as a library ? My understanding is that Phoenix works outside of Spirit and so should be documented separately, with whatever links Spirit decides to have to it being Spirit's own business. But if I am wrong and Phoenix is a library only to be used from Spirit, or always to be connected to Spirit and never used otherwise, I will gladly stand corrected.
:-) Patience... Phoenix has since been a Spirit sub-library until its Boost review sometime ago. After we get all things in order and after a mini-review, Phoenix will be a full fledged Boost citizen and will have a top level documentation. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

At Sat, 24 Jul 2010 09:42:48 +0800, Joel de Guzman wrote:
And how is anybody supposed to find this from a Boost distribution when Phoenix is not listed as a library ? My understanding is that Phoenix works outside of Spirit and so should be documented separately, with whatever links Spirit decides to have to it being Spirit's own business. But if I am wrong and Phoenix is a library only to be used from Spirit, or always to be connected to Spirit and never used otherwise, I will gladly stand corrected.
:-) Patience...
Phoenix has since been a Spirit sub-library until its Boost review sometime ago. After we get all things in order and after a mini-review, Phoenix will be a full fledged Boost citizen and will have a top level documentation.
Why a mini-review? Haven't you now met all the conditions of Phoenix' conditional acceptance? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Sat, Jul 24, 2010 at 2:07 PM, David Abrahams <dave@boostpro.com> wrote:
At Sat, 24 Jul 2010 09:42:48 +0800, Joel de Guzman wrote:
And how is anybody supposed to find this from a Boost distribution when Phoenix is not listed as a library ? My understanding is that Phoenix works outside of Spirit and so should be documented separately, with whatever links Spirit decides to have to it being Spirit's own business. But if I am wrong and Phoenix is a library only to be used from Spirit, or always to be connected to Spirit and never used otherwise, I will gladly stand corrected.
:-) Patience...
Phoenix has since been a Spirit sub-library until its Boost review sometime ago. After we get all things in order and after a mini-review, Phoenix will be a full fledged Boost citizen and will have a top level documentation.
Why a mini-review? Haven't you now met all the conditions of Phoenix' conditional acceptance?
IIRC, a mini review was one of the points for conditional acceptance.

On Sat, Jul 24, 2010 at 8:15 AM, Thomas Heller <thom.heller@googlemail.com> wrote:
On Sat, Jul 24, 2010 at 2:07 PM, David Abrahams <dave@boostpro.com> wrote:
At Sat, 24 Jul 2010 09:42:48 +0800, Joel de Guzman wrote:
And how is anybody supposed to find this from a Boost distribution when Phoenix is not listed as a library ? My understanding is that Phoenix works outside of Spirit and so should be documented separately, with whatever links Spirit decides to have to it being Spirit's own business. But if I am wrong and Phoenix is a library only to be used from Spirit, or always to be connected to Spirit and never used otherwise, I will gladly stand corrected.
:-) Patience...
Phoenix has since been a Spirit sub-library until its Boost review sometime ago. After we get all things in order and after a mini-review, Phoenix will be a full fledged Boost citizen and will have a top level documentation.
Why a mini-review? Haven't you now met all the conditions of Phoenix' conditional acceptance?
IIRC, a mini review was one of the points for conditional acceptance.
Yes, that's my recollection as well. But really, it's just a formality. This project has been nurtured for years by some of the brightest minds in the Boost community. That's has done more for Phoenix than any review could! :-) Daniel Walker

On 7/23/10 9:18 PM, Thomas Heller wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass - implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time
Did I miss something?
This is a very tight schedule, I may not be able to finish all points during the GSoC period. Any help will be appreciated. Additionally a review of the current code is highly appreciated to point out some defects that might exist. The code can be checked out at: https://svn.boost.org/svn/boost/sandbox/SOC/2010/phoenix3
I will be happy to answer your questions!
Additionally I would like to thank Joel de Guzman and Eric Niebler for their great assistance and initial designs!
Let me make my off-list comments public: Hats off to you, Thomas! Another very successful GSOC project. Hopefully, I'll be able to chip in some time again myself. For now: A BIG THANKS! And Congratulations! Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On Fri, Jul 23, 2010 at 3:18 PM, Thomas Heller <thom.heller@googlemail.com> wrote:
Ladies and Gentlemen, I proudly announce that the port of phoenix3 is completed! All testcases pass! (some with minor modifications)
So, What is next? Here is my proposed schedule: - fix some minor issues - improve boost.bind compatibility: make all boost.bind testcases pass
Status update: 21 out of 25 Boost.Bind tests pass! 4 of the unit tests do not pass, because boost::result_of does not support functions with stdcall or fastcall attributes. 2 other tests (bind_cv_test.cpp and bind_stateful_test.cpp) are currently implemented a little hacky, because as of this writing phoenix::bind only cares for const operator() overloads. 2 other tests (bind_eq_test.cpp and bind_function_test.cpp) are only working because i left out some stuff which isn't implemented yet. bind_placeholder_test.cpp is not working as expected, because phoenix3 has no support for real costum placeholders (as in the purpose of this test).
- implement all boost.lambda testcases and make them pass, as far as it is reasonable - add support for C++0x lambdas - make interoperability testcases for std::function, boost::function - adapt the documentation - clean up code (some parts are a little messy as of now) - improve compile time
Did I miss something?
This is a very tight schedule, I may not be able to finish all points during the GSoC period. Any help will be appreciated. Additionally a review of the current code is highly appreciated to point out some defects that might exist. The code can be checked out at: https://svn.boost.org/svn/boost/sandbox/SOC/2010/phoenix3
I will be happy to answer your questions!
Additionally I would like to thank Joel de Guzman and Eric Niebler for their great assistance and initial designs!
Best Regards, Thomas Heller

On 7/27/2010 6:31 AM, Thomas Heller wrote:
Status update: 21 out of 25 Boost.Bind tests pass!
4 of the unit tests do not pass, because boost::result_of does not support functions with stdcall or fastcall attributes.
IIRC, in Bind stdcall/fastcall support is conditional. I bet if you patched result_of to have such conditional support for those calling conventions and submitted a patch, it would be gladly accepted.
2 other tests (bind_cv_test.cpp and bind_stateful_test.cpp) are currently implemented a little hacky, because as of this writing phoenix::bind only cares for const operator() overloads.
Right, you can overload operator() on const, so it matters for return type computation.
2 other tests (bind_eq_test.cpp and bind_function_test.cpp) are only working because i left out some stuff which isn't implemented yet. bind_placeholder_test.cpp is not working as expected, because phoenix3 has no support for real costum placeholders (as in the purpose of this test).
I hope phoenix supports this eventually. Thanks! -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
On 7/27/2010 6:31 AM, Thomas Heller wrote:
Status update: 21 out of 25 Boost.Bind tests pass!
4 of the unit tests do not pass, because boost::result_of does not support functions with stdcall or fastcall attributes.
IIRC, in Bind stdcall/fastcall support is conditional. I bet if you patched result_of to have such conditional support for those calling conventions and submitted a patch, it would be gladly accepted.
2 other tests (bind_cv_test.cpp and bind_stateful_test.cpp) are currently implemented a little hacky, because as of this writing phoenix::bind only cares for const operator() overloads.
Right, you can overload operator() on const, so it matters for return type computation.
The functors in question didn't have a polymorphic return type. It was just a matter, that the non-const operator() overload was never called. Code in question looks something like this: struct X { typedef void result_type; void operator()() {} // (1) void operator()() const {} // (2) }; template <typename F> void g(F f) { F const& h(f); h(); // <-- (2) was expected to be called here, but (1) gets called } int main { using boost::phoenix::bind; X x; bind(x); // binding x in some non-const context } I think phoenix behaves correctly here. But I am not really sure, because it must have been some justification to end up us a Boost.Bind testcase.
2 other tests (bind_eq_test.cpp and bind_function_test.cpp) are only working because i left out some stuff which isn't implemented yet. bind_placeholder_test.cpp is not working as expected, because phoenix3 has no support for real costum placeholders (as in the purpose of this test).
I hope phoenix supports this eventually.
Yes, I will work on that. Might need some help with the binary visitation of a proto AST. I will shout then ;)
Thanks!

On 7/28/10 4:06 AM, Thomas Heller wrote:
The functors in question didn't have a polymorphic return type. It was just a matter, that the non-const operator() overload was never called. Code in question looks something like this:
struct X { typedef void result_type;
void operator()() {} // (1) void operator()() const {} // (2) };
template<typename F> void g(F f) { F const& h(f);
h(); //<-- (2) was expected to be called here, but (1) gets called }
int main { using boost::phoenix::bind;
X x; bind(x); // binding x in some non-const context }
I think phoenix behaves correctly here. But I am not really sure, because it must have been some justification to end up us a Boost.Bind testcase.
2 other tests (bind_eq_test.cpp and bind_function_test.cpp) are only working because i left out some stuff which isn't implemented yet. bind_placeholder_test.cpp is not working as expected, because phoenix3 has no support for real costum placeholders (as in the purpose of this test).
You might want to re-post this with [bind] in the heading to solicit a reply from Peter Dimov; (maybe CC him too). It's best to fully understand the rationale behind the test. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman wrote:
You might want to re-post this with [bind] in the heading to solicit a reply from Peter Dimov; (maybe CC him too). It's best to fully understand the rationale behind the test.
The test tests whether the constness of the object returned by bind is properly propagated to the bound function object. In the simplest case, bind( f ) should return something like: struct bound_f { F f_; void operator()() { return f_(); } void operator()() const { return f_(); } }; In the first op(), called for non-const bound_f objects, the f_ member is non-const. In the second op(), called for const bound_f objects, the f_ member is const.

On Wed, Jul 28, 2010 at 9:26 AM, Peter Dimov <pdimov@pdimov.com> wrote:
Joel de Guzman wrote:
You might want to re-post this with [bind] in the heading to solicit a reply from Peter Dimov; (maybe CC him too). It's best to fully understand the rationale behind the test.
The test tests whether the constness of the object returned by bind is properly propagated to the bound function object. In the simplest case, bind( f ) should return something like:
struct bound_f { F f_;
void operator()() { return f_(); } void operator()() const { return f_(); } };
In the first op(), called for non-const bound_f objects, the f_ member is non-const. In the second op(), called for const bound_f objects, the f_ member is const.
Thanks for the clarification. I will try to reflect that in phoenix3, if there aren't any objections.

Hi, I think that a reasonable implementation of at_c for the new phoenix3 could be: #pragma once // boost headers #include <boost/fusion/include/at.hpp> #include <boost/phoenix/function.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_const.hpp> // std headers #include <algorithm> #include <iostream> namespace boost { namespace phoenix { template <int N> struct at_impl { template <class Signature> struct result; template <class This, class Arg> struct result<This(Arg)> { typedef typename boost::fusion::result_of::at_c< typename boost::remove_reference<Arg>::type , N >::type type; }; template <class Arg> typename boost::result_of<at_impl<N>(Arg &)>::type operator()(Arg &arg) const { return fusion::at_c<N>(arg); } }; } // namespace phoenix } // namespace boost If that piece of code is valid (I have tested but I'm not sure if that's the right way to do it) how would boost::phoenix::at_c be implemented? In phoenix2 at_impl was a eval so at_c was a template inline function. Best regards, Denis

On 7/29/10 3:51 AM, Denis Taniguchi wrote:
Hi,
I think that a reasonable implementation of at_c for the new phoenix3 could be:
#pragma once
// boost headers #include<boost/fusion/include/at.hpp> #include<boost/phoenix/function.hpp> #include<boost/type_traits/remove_reference.hpp> #include<boost/type_traits/remove_const.hpp>
// std headers #include<algorithm> #include<iostream>
namespace boost { namespace phoenix { template<int N> struct at_impl { template<class Signature> struct result;
template<class This, class Arg> struct result<This(Arg)> { typedef typename boost::fusion::result_of::at_c< typename boost::remove_reference<Arg>::type , N >::type type; };
template<class Arg> typename boost::result_of<at_impl<N>(Arg&)>::type operator()(Arg&arg) const { return fusion::at_c<N>(arg); } }; } // namespace phoenix } // namespace boost
If that piece of code is valid (I have tested but I'm not sure if that's the right way to do it) how would boost::phoenix::at_c be implemented? In phoenix2 at_impl was a eval so at_c was a template inline function. Best regards,
I'm not sure why phoenix2 implemented it using the extension mechanism instead of a plain phoenix function. In phoenix3, I suggest making it a phoenix function. Oh, and I also suggest dealing with const/non-consts and returning references as well. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On Thu, Jul 29, 2010 at 1:54 AM, Joel de Guzman <joel@boost-consulting.com> wrote:
On 7/29/10 3:51 AM, Denis Taniguchi wrote:
Hi,
I think that a reasonable implementation of at_c for the new phoenix3 could be:
#pragma once
// boost headers #include<boost/fusion/include/at.hpp> #include<boost/phoenix/function.hpp> #include<boost/type_traits/remove_reference.hpp> #include<boost/type_traits/remove_const.hpp>
// std headers #include<algorithm> #include<iostream>
namespace boost { namespace phoenix { template<int N> struct at_impl { template<class Signature> struct result;
template<class This, class Arg> struct result<This(Arg)> { typedef typename boost::fusion::result_of::at_c< typename boost::remove_reference<Arg>::type , N >::type type; };
template<class Arg> typename boost::result_of<at_impl<N>(Arg&)>::type operator()(Arg&arg) const { return fusion::at_c<N>(arg); } }; } // namespace phoenix } // namespace boost
If that piece of code is valid (I have tested but I'm not sure if that's the right way to do it) how would boost::phoenix::at_c be implemented? In phoenix2 at_impl was a eval so at_c was a template inline function. Best regards,
I'm not sure why phoenix2 implemented it using the extension mechanism instead of a plain phoenix function. In phoenix3, I suggest making it a phoenix function. Oh, and I also suggest dealing with const/non-consts and returning references as well.
I implemented phoenix::at_c the same way as it was done with phoenix2. Have a look here: https://svn.boost.org/trac/boost/browser/sandbox/SOC/2010/phoenix3/boost/pho... I think the reason why it was (and is done) this way, is to supply N as a template parameter, not a parameter to the lazy function.

On Thu, 2010-07-29 at 09:34 +0200, Thomas Heller wrote:
On Thu, Jul 29, 2010 at 1:54 AM, Joel de Guzman <joel@boost-consulting.com> wrote:
On 7/29/10 3:51 AM, Denis Taniguchi wrote:
Hi,
I think that a reasonable implementation of at_c for the new phoenix3 could be:
#pragma once
// boost headers #include<boost/fusion/include/at.hpp> #include<boost/phoenix/function.hpp> #include<boost/type_traits/remove_reference.hpp> #include<boost/type_traits/remove_const.hpp>
// std headers #include<algorithm> #include<iostream>
namespace boost { namespace phoenix { template<int N> struct at_impl { template<class Signature> struct result;
template<class This, class Arg> struct result<This(Arg)> { typedef typename boost::fusion::result_of::at_c< typename boost::remove_reference<Arg>::type , N >::type type; };
template<class Arg> typename boost::result_of<at_impl<N>(Arg&)>::type operator()(Arg&arg) const { return fusion::at_c<N>(arg); } }; } // namespace phoenix } // namespace boost
If that piece of code is valid (I have tested but I'm not sure if that's the right way to do it) how would boost::phoenix::at_c be implemented? In phoenix2 at_impl was a eval so at_c was a template inline function. Best regards,
I'm not sure why phoenix2 implemented it using the extension mechanism instead of a plain phoenix function. In phoenix3, I suggest making it a phoenix function. Oh, and I also suggest dealing with const/non-consts and returning references as well.
I implemented phoenix::at_c the same way as it was done with phoenix2. Have a look here: https://svn.boost.org/trac/boost/browser/sandbox/SOC/2010/phoenix3/boost/pho...
That's exactly what I needed. Thanks again Thomas.
I think the reason why it was (and is done) this way, is to supply N as a template parameter, not a parameter to the lazy function. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 7/29/10 3:34 PM, Thomas Heller wrote:
I'm not sure why phoenix2 implemented it using the extension mechanism instead of a plain phoenix function. In phoenix3, I suggest making it a phoenix function. Oh, and I also suggest dealing with const/non-consts and returning references as well.
I implemented phoenix::at_c the same way as it was done with phoenix2. Have a look here: https://svn.boost.org/trac/boost/browser/sandbox/SOC/2010/phoenix3/boost/pho...
I think the reason why it was (and is done) this way, is to supply N as a template parameter, not a parameter to the lazy function.
Makes perfect sense. Thanks for reminding me. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
participants (16)
-
Ahmed Charles
-
Daniel James
-
Daniel Walker
-
David Abrahams
-
Denis Taniguchi
-
Doug Gregor
-
Edward Diener
-
Eric Niebler
-
Giovanni Piero Deretta
-
Joel de Guzman
-
joel falcou
-
Mathias Gaunard
-
Peter Dimov
-
Robert Jones
-
Sohail Somani
-
Thomas Heller