Live data from Hacker News

Lambda expression comparison between C++11, C++14 and C++17

maitesin.github.io

61–70 of 87 posts

Re: Lambda expression comparison between C++11, C++14 and C++17

#61
post #44

Earlier quoted context omitted.

The syntax is not the prettiest, but it is legible once you understand what [](){} means. In C#, there is no such thing, but there is a part of me that wishes we had such a thing. I like the ability explicitly state what variables are being captured.

I'm not 100% sure, but C#'s compiler should automatically capture what you need (and leave out the rest). I think the primary need for manual declaration is because in C++ you need to differentiate between pass by copy semantics and pass by reference semantics.

> I think the primary need for manual declaration is because in C++ you need to differentiate between pass by copy semantics and pass by reference semantics.

That's not actually a need, C++ includes [=] and [&] (capture everything by value or by reference). You can get a mix by creating references outside the body then capturing the environment by value (capturing the references by value and thus getting references).

On the one hand it has a bit more syntactic overhead (you have to take and declare a bunch of references before creating the closure), on the other hand there's less irregularity to the language, and bindings mean the same thing in and out of the closure.

FWIW that's what Rust does[0], though it may help that Rust's blocks are "statement expressions", some constructs would probably be unwieldy without that.

[0] the default corresponds to C++'s [&] (capture by ref), and a "move closure" switches to [=] instead

Re: Lambda expression comparison between C++11, C++14 and C++17

#62

I love lambdas, but a lot of commenters are throwing around the word "closure" here, and c++ lambdas are definitely not closures. You can capture outside variables by value or by reference, but that value can expire before the lambda runs if the reference no longer exists; in which case, you are in trouble. Unlike a true closure (as in lisp or other languages), where the closed-over value stays around. If we talk onl…

I'm not familiar with closures from other languages. What about capturing a shared_ptr by value?

Re: Lambda expression comparison between C++11, C++14 and C++17

#63
post #10

Taking a concept such as a lambda function and making it look this ugly...this is why I hate C++. I wish I wasn't forced to program it every day.

Agreed. From the template library on down, it seems like the C++ community is hellbent on making the syntax for what should be clean, common operations seem like arcane Sanskrit. I dont know what their problem is.

Refusing to break backwards compatibility is their problem. I respect them for that; if you do want to break it make another language that plays nicely with C++ instead.

Re: Lambda expression comparison between C++11, C++14 and C++17

#64
post #10

Taking a concept such as a lambda function and making it look this ugly...this is why I hate C++. I wish I wasn't forced to program it every day.

Agreed. From the template library on down, it seems like the C++ community is hellbent on making the syntax for what should be clean, common operations seem like arcane Sanskrit. I dont know what their problem is.

Often, the problem is that the clean simple syntax you might want to use already means something else in C++, and the bias against breaking existing code is very strong.

Re: Lambda expression comparison between C++11, C++14 and C++17

#65
post #10

Taking a concept such as a lambda function and making it look this ugly...this is why I hate C++. I wish I wasn't forced to program it every day.

For historical interest, compare an early proposal: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n195...

Re: Lambda expression comparison between C++11, C++14 and C++17

#66

Earlier quoted context omitted.

The syntax is not the prettiest, but it is legible once you understand what [](){} means. In C#, there is no such thing, but there is a part of me that wishes we had such a thing. I like the ability explicitly state what variables are being captured.

> I like the ability explicitly state what variables are being captured. Why? You state what variables are being captured by just using them in the lambda body.

> You state what variables are being captured by just using them in the lambda body.

Wow, have you never spent a week debugging a JavaScript memory leak?

Re: Lambda expression comparison between C++11, C++14 and C++17

#67

I love lambdas, but a lot of commenters are throwing around the word "closure" here, and c++ lambdas are definitely not closures. You can capture outside variables by value or by reference, but that value can expire before the lambda runs if the reference no longer exists; in which case, you are in trouble. Unlike a true closure (as in lisp or other languages), where the closed-over value stays around. If we talk onl…

I find that pointlessly pedantic. By the same measure, languages that don't offer bignums don't offer integers. Even Lisps need to implement closures in one way or another, and you may be surprised to see how they actually do it.

Re: Lambda expression comparison between C++11, C++14 and C++17

#68

Earlier quoted context omitted.

It was enough of a problem in Scala to warrant this though http://docs.scala-lang.org/sips/pending/spores.html

Spores seem like an interesting solution. The language designer in me has a distaste for it, though :p For case 1 (capture of mutable references), an explicit copy operator might be better (as in, "I want whatever value this variable is bound to, rather than the storage location") (or even vice versa, where value is the default and there's an operator for location). In a way, spores accomplish this by forcing you to…

Agree on the copy operator, not only for spores, have wanted it more than one time in other languages too.

Not sure how the this binding should work though. If calling a method you need to a) dispatch on the runtime type and b) provide the instance to the method when called.

Re: Lambda expression comparison between C++11, C++14 and C++17

#69
post #67

I love lambdas, but a lot of commenters are throwing around the word "closure" here, and c++ lambdas are definitely not closures. You can capture outside variables by value or by reference, but that value can expire before the lambda runs if the reference no longer exists; in which case, you are in trouble. Unlike a true closure (as in lisp or other languages), where the closed-over value stays around. If we talk onl…

I find that pointlessly pedantic. By the same measure, languages that don't offer bignums don't offer integers. Even Lisps need to implement closures in one way or another, and you may be surprised to see how they actually do it.

I think you miss the point, the OP was mentioning the property that in most languages, closures whose outer variables they are bringing into scope stay in scope (even if the outer function ends). In C++ they expire (is what I got from his comment, anyway).

Re: Lambda expression comparison between C++11, C++14 and C++17

#70
post #23

Another mildly obscure feature of lambdas is the ability to capture a variadic number of parameters. Example (slightly contrived): #include #include template void log(Args&&... args) { (std::cout std::future log_async(Args&&... args) { return std::async(std::launch::async, [args...] { log(args...); }); } int main() { auto f = log_async(1, 2, 3); f.wait(); }

Well, I feel like an old man telling kids to get off my lawn, but this syntax looks ridiculous. :/
Post reply on HN