
On 02/02/2011 13:21, Thomas Heller wrote:
Point taken. OTOH the macros used to define the local functions are not even close to those of either C++0x lambdas or regular C++ functions.
I find them pretty close to both, except you need to explicitly enumerate variables you wish to bind. (C++0x lambdas do it do, but also have a mode where it captures everything)
The "fluff" and "obfuscated" syntax you find in Phoenix et al in the body of the expressions, was shifted in Boost.Local to the function decelerator.
Right, and that's a good thing. The body of a function is its important part; that's what you want to be lightweight, clear, expressive and debuggable. The syntax to declare a local (I think nested would be a better name) function is not much more different than the one to define a regular monomorphic function, except you have to take care of capturing scope manually. I can tell from experience that I often end up writing by hand the very function objects that Boost.Local can automatically generate.
2) Even though C++0x will support unnamed functions as a language feature, Boost.Phoenix will not become obsolete. Quite the opposite, Boost.Phoenix offers a lot of advantages over C++0x lambdas. (Forgive me if I won't go into detail here about that, this thread is about Boost.Local) Whereas Boost.Local are just a complicated way to express what can be done with C++0x lambdas, I see no real advantage of Boost.Local over C++0x lambdas.
As far as I can see, there are few restriction compared to the equivalent C++0x lambdas: - creating a local can only be done at statement scope. - locals may not automatically capture all context - size of a local function cannot be optimized to be two words. Let's compare Phoenix and that library and C++0x lambdas for a minute. Both C++0x lambdas and Boost.Local are better than Boost.Phoenix on several points. Doing anything non-trivial with Phoenix requires creating lazy functions beforehand (typically done at namespace scope). The fact that Phoenix itself bundles many lazy functions for any other container member and standard algorithm (for a total of 4,000 lines of code for that task alone) is testament to that; you can't really work with it otherwise. Bind and ->* can help to an extent (at the price of high verbosity), but if you want polymorphic behaviour (or don't want to specify manually all types involved) with template functions or members, you can't use those. This severely restricts Boost.Phoenix to being either used as a toy, or in a limited sub-world of C++ where naked classes, structures and functions don't exist, unless they've been adapted or wrapped to be used with it. On the other hand, C++0x lambdas can use arbitrary C++ syntax, and Boost.Local likewise, which means they can readily integrate in any source code. They cannot be polymorphic, but if that restriction were to be removed (through support for template member functions of local structures or otherwise), then the use for Phoenix would be even more limited. I see Boost.Local as merely an emulation for C++0x-like lambdas; it can be used to make code compatible with C++03. In truth, I believe Boost.Local is useful to a much broader audience than Phoenix, and is therefore as worthy of being a Boost library. There is also a lot of precedent in libraries that allow C++0x features in C++03.