Boost logo

Boost :

Subject: Re: [boost] New libraries implementing C++11 features in C++03
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-24 11:18:26


On Thu, Nov 24, 2011 at 5:57 AM, Dean Michael Berris
<mikhailberis_at_[hidden]> wrote:
> On Thu, Nov 24, 2011 at 8:16 PM, Lorenzo Caminiti <lorcaminiti_at_[hidden]> wrote:
>> On Wed, Nov 23, 2011 at 8:11 PM, Joel de Guzman
>> <joel_at_[hidden]> 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_kit/lazy_functions.html
>>
>> // 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.

1) I don't think I have to convince anyone. Following Boost process, I
have first asked for interest in the library about ~1year ago plus all
the reviewers have answered the question:
> - What is your evaluation of the potential usefulness of the library?
With that information I am confident that the review manager will be
able to assess the library usefulness taking into consideration the
opinion of /all/ the people that reviewed the library.

2) As for local functions, namespace, or global structs see N2511. If
you disagree with N2511 arguments, it's truly OK because IMO everyone
is free to use whatever idiom they see fit for themselves and their
problem domain. I am sure the library reviewers had namespaces and
global structs in mind when they assessed the "potential usefulness of
the library" (also because these are mentioned in the library docs).
So also in this case /all/ submitted reviews should allow the review
manager to come to a conclusion on this issue.

3) [MOST IMPORTANT OF ALL] This thread is about "should new libraries
implementing C++11 features in C++03" be considered for admission in
Boost or not. It's not about the usefulness of Local, namespace,
struct, Phoenix, etc. Let's all try to provide the review manager with
this piece of information about C++11, C++03, and Boost.

HTH,
--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk