
On Wed, Feb 2, 2011 at 2:00 AM, Thomas Heller <thom.heller@googlemail.com> wrote:
Gregory Crosswhite wrote:
Hey everyone,
The purpose of this e-mail is to rave about Lorenzo's proposed Boost.Local library in the hopes of inspiring people to start the review process for it. :-)
I have been experimenting with using this library in my own code, and it has been a godsend for me. In one of the projects I have been working on I ran into many situations where I needed to call a higher-order function with a closure, and the closure was just complicated enough that I couldn't use Boost.Lambda. Before using this library I frequently found myself either writing a lot of extra code to work-around the need for a higher-order function, or writing a lot of boilerplate to create classes that would only be used by a single function in order to create a function object. This library has let me write the closures that I need in a fairly painless fashion and so has made my life a lot easier!
I would be interested in what limitations you ran into using Boost.Lambda and if you are aware of the recent efforts that were put into Boost.Phoenix?
To my mind this example looks a lot clearer if you reformat it as follows:
BOOST_LOCAL_FUNCTION( (void) (add)( (double)(num) (const bind)((factor)) (bind)((&sum)) ) ) { sum += factor * num; std::clog<< "Summed: "<< sum<< std::endl; } BOOST_LOCAL_FUNCTION_END(add) add(100.0);
As far is a am concerned, I still find this syntax overly verbose. I do realize though that this is just a toy example. For better comparison, Here is how the same thing would like in Boost.Phoenix:
boost::function<void(double)> add =( ref(sum) += factor * _1, std::clog << var("Summed: ") << sum << std::endl ) ; add(100.0);
Can you make factor constant within add() body using Boost.Phoenix? If not, then I could not use Boost.Phoenix for my original use case* that motived Boost.Local (local constant blocks). And that's why C++0x lambdas are also not useful for me because they do not support constant binding -- why don't they?? :(( -- plus I use an oldish gcc-based tool chain for an embedded system and there is no plan to get a C++0x release for it at the moment... (*) My original use case required (1) to write the body is normal C++ syntax (so I could not use Boost.Phoenix) and (2) to use constant binding (I am not sure but I don't think Boost.Phoenix can do constant binding, I know C++0x lambdas cannot) to check assertions in a constant correct context: void f(int& zero) { BLOCK_INVARIANT( (const (zero) (zero == 0)) ) // Compiler error if programmers mistake `==` with `=`. ... } I can do this with Boost.Local: void f(int& zero) { BOOST_LOCAL_BLOCK( (const bind)(&zero) ) { assert(zero == 0); } BOOST_LOCAL_BLOCK_END } How can I do this in Boost.Phoenix? How can I do this in C++0x lambdas? (Note requirements (1) and (2).) Maybe this use case is not very interesting to other people but it was important for me.
Despite the Local Blocks and Local Exits feature, I can't see much difference to the already existing lambda libraries. I just looked through the Boost.Local documentation and immediately navigated to the "Alternatives" section and its not really correct regarding the features of Boost.Lambda and Boost.Phoenix. I am specifically talking about the "Bind variables in scope" and "Program body using usual C++
The Alternatives section is based on this previous Boost discussion http://permalink.gmane.org/gmane.comp.lib.boost.devel/212255 . I also think it is not a complete comparison. For example, I wanted to add the add() example -- add add() ;) -- reworked in Boost.Phoenix, Boost.Lambda, C++0x lambdas, and C++ local classes but I didn't have time yet... Thanks a lot of the above code in Boost.Phoenix, I'll add it to Boost.Local doc :)
syntax" part. The last is debatable, but how are the above examples (both of Boost.Local and Boost.Phoenix) not C++ syntax? Can you highlight the advantages/disadvantages again?
Yes, this is debatable and at the end it's of course all C++. But the Boost.Local function body defined within `{ ... }` it's the normal C++ syntax for function definitions. For example, Boost.Phoenix uses `,` where C++ and Boost.Local use `;` to terminate and instruction, Boost.Phoenix uses `var("Summed:")` where C++ and Boost.Local use `"Summed:"`, etc. Plus, how would local variables and local classes look in Boost.Pheenix? In Boost.Local it's like in normal C++: BOOST_LOCAL_FUNCTION( (void) (add)( (double)(num) (const bind)((factor)) (bind)((&sum)) ) ) { const std::string msg = "Summed: "; // A const local var. struct text { std::string say; } // A local struct. test t; // A local var. t.say = msg; sum += factor * num; std::clog<< t.say << sum<< std::endl; } BOOST_LOCAL_FUNCTION_END(add) add(100.0); How would this look in Boost.Phoenix? I wish I knew Phoenix better :) so I could provide the answers myself... -- Lorenzo