
On Thu, Nov 24, 2011 at 8:16 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Wed, Nov 23, 2011 at 8:11 PM, Joel de Guzman <joel@boost-consulting.com> wrote:
If you've read the Spirit docs, you will know what that means.
Now having said that, and before I leave this thread, let me remind everyone that **you can also have statement syntax in Phoenix** if you have a complex statement and you fear writing complex phoenix lambda expressions. It's called phoenix::functions.
In fact here's what I advocate:
1) For simple 1-2-3 liners, use a phoenix lambda expression. It's hard to get them wrong. For example, you'll have to be absurdly dumb to get this wrong:
auto plus = _1 + _2;
2) For more complex expressions, especially those involving statements, use a phoenix function plus a simple lambda expression that forwards to the phoenix function. Example:
for_each(f, l, call_complex_function(_1));
IF (this is a big IF) I understand it correctly, Phoenix functions are non-local functors: http://www.boost.org/doc/libs/1_48_0/libs/phoenix/doc/html/phoenix/starter_k...
// non-local scope struct is_odd_impl { typedef bool result_type;
template <typename Arg> bool operator()(Arg arg1) const { return arg1 % 2 == 1; } };
// local scope function<is_odd_impl> is_odd;
A couple of people have argued that for complex task it is OK to push the code to non-local scope. That is their point of view but of course it goes fundamentally against local functions principles (e.g., N2511) and the fact that even local functions can be long in some programming style (as expressed by others commenting before).
Lorenzo, I think you've done a good job of implementing the currently proposed library for inclusion. I do not doubt that your solution works and in your eyes it's as close to perfect as you can make it. BUT (and this is a big BUT), even after reading your documentation, I'm still unconvinced that local functions are an elegant solution to the problem they're purportedly meant to solve. C++ (and if I know my C correctly, even C) has gone fine without local functions. What C++11 already has right now is much more powerful than just local functions in lambdas. The only difference between a local function and a non-local function is where it's located. If the function is named appropriately and is located in a convenient location (i.e. logically outside any given function) I and the hundreds and thousands of other C++ programmers don't see what the problem is with non-location functions. One thing I do see that is a problem with local functions the way you implement it are: 1. They're not real functions. That means I cannot refer to it inside a function pointer. Which means the myriad libraries that take function pointers out there won't be able to leverage whatever local function objects made with your library. 2. They clutter up my current function's scope. Instead of being defined in-line like C++11 lambdas, Boost.Phoenix lambda's, Boost.Lambda lambda's, and Boost.Bind lambda's, they're being defined outside the point of usage. The difference between the function being defined in-line (as in C++11 lambdas) and not in-line is *HUGE* (difference between 0 and at least one) while the difference between a function defined in a function's scope and outside the function's scope is marginal at best. 3. I cannot, no matter how I look at your examples and the "logic" behind the concept of local functions, comprehend why this is a good way to organize code. Aren't we all past the phase yet of functions that have more than 10 lines of code? The advantages of having a function (a logical piece of code that's meant to be used as a unit *anyway*) at namespace scope or class scope is that re-usability is something you get for free. On the other hand, defining a local function with Boost.Local that I'd want to define as an external function at some point (because oh I don't know I want to use the same function somewhere else all of a sudden) will be too much work with all the macro voodoo that I have to wade through. I (and maybe others as well who follow the same logic I follow) don't see a large enough gap between C++11 lambdas and Boost.Phoenix/Lambda/Bind function objects that merits being addressed by local functions. Until you can convince us that local functions are "absolutely necessary" and that C++ should have it because it makes certain programming paradigms/techniques possible, I'm afraid what you have is a solution that's looking for a problem.
IMO, our library users should be felt the opportunity to program as they see more fit to themselves and their problem domain (long/short local functions, long/short global Phoenix functions, long/short Phoenix lambdas ( yes, even long Phoenix lambdas if the users want to) ).
I agree 100%. I still don't think though for your library to succeed that it has to be in Boost. Cheers -- Dean Michael Berris http://goo.gl/CKCJX