Boost logo

Boost :

Subject: Re: [boost] New libraries implementing C++11 features in C++03
From: Dean Michael Berris (mikhailberis_at_[hidden])
Date: 2011-11-25 02:35:46


On Fri, Nov 25, 2011 at 6:06 PM, Nathan Ridge <zeratul976_at_[hidden]> wrote:
>
>> From: mikhailberis_at_[hidden]
>> Subject: Re: [boost] New libraries implementing C++11 features in C++03
>>
>> On Fri, Nov 25, 2011 at 3:38 PM, Nathan Ridge <zeratul976_at_[hidden]> wrote:
>>
>> >> Stuff I (mikhailberis_at_[hidden]) said...
>> >>
>> >> Huh? This is a matter of the rules of the programming language and
>> >> (dare I say) sane engineering practices.
>> >
>> > Are you saying it's sane engineering practice to avoid local functions?
>> > If so, why don't you avoid C++11 lambdas equally?
>> >
>>
>> Because C++11 lambdas are function objects I can define in-line where
>> I need function objects -- which is what modern C++ prefers over
>> function pointers. The STL and every other sanely engineered C++
>> library that requires function object callbacks will support function
>> objects whether they're defined in-line with C++11 lambdas or as
>> hand-rolled function objects using operator() overloading.
>
> And they won't support Boost.Local functions?
>

If Boost.Local functions are just function objects then sure. My point
is that I don't see the need for Boost.Local for me to be able to
leverage these libraries in C++03 or C++11.

>> Also, I personally do not see a need for a construct like this:
>>
>> auto f = []() { /* do something here */ }
>>
>> I say this because there's absolutely 0 point in doing this if I can
>> drop the lambda in where I need f *anyway*.
>
> I use this construct frequently in my C++11 projects. It can serve to
> make the code more readable. Here's an example of a line of code I
> wrote recently. It makes use of Boost.Range in addition to C++11 lambdas:
>
> vector<message> messages;
> push_back(messages, message_ids | transformed(lookup_message_by_id)
>                                 | filtered(newer_than_one_year)
>                                 | filtered(not_hidden)
>                                 | filtered(satisfies_user_preference));
>
> The arguments to the transformed and filtered adaptors are all C++11
> lambdas defined immediately above these lines. How do you think this
> code would look if I instead dropped the lambda definitions inline?
> Or would you have wasted extra lines and time defining these little
> one-or-two-liner functions that are not used anywhere else, out of line?
>

I think You're Doing It Wrong (tm). If I was doing this, all these
function objects would be types themselves, they would be testable
outside this context, and they can even be just forward declared and
linked statically later on.

I don't see why they need or have to be C++11 lambdas at all if
they're not just a one-or-two liner and if they have names that do
make sense as types.

>> >> Did you really mean that C++ shouldn't stand in your way when you want
>> >> to write Pascal code?
>> >
>> > I don't know Pascal so I can't comment on that. I am saying that C++
>> > shouldn't stand in my way when I want to make design choices like making
>> > one function local to another versus making them "equals" by putting them
>> > in the same scope.
>> >
>>
>> What's the problem with making them equals? They're just functions.
>
> Suppose you have a namespace N, with two classes N::A and N::B. Suppose you
> have a function f() that is used only in the implementation of A, and has
> nothing to do with B. Is it better to put this function inside namespace N,
> where it is visible by both A and B, or inside the class A, where it is
> only visible by A?

I'd make it private in A.

>
> Now repeat this argument, substituting a class for namespace N, and two
> methods for A and B, and you have a use case for local functions.
>

No, I would create nested namespaces specific to the requirements of
functions A and B (maybe call them impl_A and impl_B). There's no
*need* for local functions in this case you're proposing.

>>
>> Then propose/implement it as a language extension, or keep the current
>> implementation and use it -- nobody's stopping you or anybody from
>> doing that. Putting it in Boost is what I object to "just because".
>
> Perhaps I'm not understanding what you mean by a "language extension".

Like what Microsoft does with their language extensions.

>
> Are you suggesting I propose it for the next standard of C++? That would
> be silly, as C++11 already has a solution (lambdas), and the whole point
> is to make the feature accessible to people who can't use C++11 yet.
>

See my point now?

> Or are you suggesting that I propose a compiler-specific language
> extension for my compiler? That will not fly in an environment where
> one's code has to run of many different compilers, and in any case
> it goes completely against the spirit of having a language standard
> in the first place.
>

Right, so you see why I don't think Boost.Local even makes sense?

>>
>> No, sorry -- just having "prettier error messages" isn't a good
>> measure for inclusion in Boost. You're going to have to try harder
>> than that to make a case for a library.
>
> So you admit that bad errors messages are a problem that users run into
> frequently, and that we're not likely to see a solution from the compiler side
> any time soon... but you say a library that solves this problem is not
> important enough for Boost?

Yes, they're not important enough for Boost if what it provides isn't
compelling enough to be provided by Boost. If the only thing a library
has is "prettier error messages when things are broken" then it's a
great library for broken code -- which makes that advantage null and
void because IT'S NOT AN ADVANTAGE BECAUSE YOUR CODE DOESN'T COMPILE.

Am I not getting through here?

Whoever loved a library that looked great when your code fails to
compile? This is CRAZY TALK.

Cheers

-- 
Dean Michael Berris
http://goo.gl/CKCJX

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