
From: mikhailberis@gmail.com
On Fri, Nov 25, 2011 at 6:06 PM, Nathan Ridge <zeratul976@hotmail.com> wrote:
From: mikhailberis@gmail.com Subject: Re: [boost] New libraries implementing C++11 features in C++03
On Fri, Nov 25, 2011 at 3:38 PM, Nathan Ridge <zeratul976@hotmail.com> wrote:
Stuff I (mikhailberis@gmail.com) 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