Boost logo

Boost :

Subject: Re: [boost] New libraries implementing C++11 features in C++03
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-11-25 03:11:31


> From: mikhailberis_at_[hidden]
>
> 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.

Who ever said the point of Boost.Local was to be able to leverage these
libraries? The point of Boost.Local is to be able define functions locally,
close to where they are used, with C++ statement syntax.

> >> 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.

They *are* one-or-two-liners, and it would be overkill to define them
out of line.

> >> >> 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.

Right, so now you're introducing a new construct (impl_A) just for this
purpose, because you can't do the natural thing which is to just define
the functions where they are used, i.e. inside A.

What if you were defining A inline in the class definition? How far
would impl_A be from A?

> > 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?

Well that is precisely why we are proposing a library, and not a language
feature - we already have the language feature, some people just can't use
it yet!

> > 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?

I'm sorry, I don't. While compiler-specific language extensions go against
the spirit of having a language standard, libraries that emulate a language
feature and work in standard C++ across platforms, such as Boost.Local,
are very much in line with that spirit. This is what Boost has been doing
with Foreach, Typeof, Lambda, etc.

> >> 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.

How often do you write code that is right the first time around? Even for
an experienced programmer, and especially with a new library, more often
than not your code will initially be broken. To fix it, you need to
understand the problem, and you need the library's help to do so.

So, since writing wrong code is just as much a reality of programming
as writing working code, having a library that helps you fix your code
when it's broken is just as important as having a library that runs
your working code (OK, maybe not "just as important" - but quite
important).

Regards,
Nate
                                               


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