Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 of February 2016 15:16:33 you wrote: > I am a great fanboy of algorithms and the STL, as should be clear by now You are excused ;-) But seriously I do not think there is anything wrong about it, STL is a bit obscure, but fast and sometimes a code needs to be fast. > But I find the inlined lambda worse than an explicit loop. This is > write-only code, imo. Esp. since we can't (yet) use auto in the parameter > list, but even then, I'd always give a lambda a name (cf. my mail in > response to Christian). Hmmm, In my opinion you do not like the most cool feature of lambdas :-) Each time I was forced to define a functor somewhere, in a completely different place then my code lived, I was sad and jealous of python lambda syntax. I value a code that can be read from top to down without major jumps. Naming lambdas causes my eyes to jump ("so for each element it calls a function FooBar... Ah which does that") and it also suggests that the lambda will be re-used ("ok, so now remember FooBar, as it will be used again..."). I would much prefer a simple inline comment before sequence of std::remove_if std::erase and others then named lambda. Anyway I guess we are again hitting a "C++11 syntax that we were not used to" issue. So please do not create any policy about that, at least not for now. Btw. when you are taking an address of a function you force a compiler to de- inline the function, I hope such de-optimization doesn't happen while naming lambdas. > > For a bigger code we would actually require named functions. What do you > > think? > > Named functions have two problems: a) that many compilers don't inline the > code. So at a minimum, you'd write a forwarding lambda, or the function > would be an auto variable holding a stateless lambda (the difference > between the two is almost non-existent, anyway). And b) that they cannot > carry state. Lambdas can. Sorry I used wrong wording, by named function I meant, assigned lambda, a functor or a declared function. In general a callable with a name, defined in a different place then used. A propos inline'ing of functions, have you tried anonymous namespaces? That should help. At least once I forced gcc to inline the code... Cheers, Jędrek ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 February 2016 13:34:05 Sergio Martins wrote: > I would write: > > removeIfFirstEquals(fields, name): because: > > 1) I could read it in English instead of very verbose C++ > 2) I would not need to read the implementation I tend to agree, but it only shifts the issue down one level of abstraction. And removeIfFirstEquals() isn't exactly clear, either. fields.removeIfFirstEquals(name) would be. Maybe when C++ lifts the distinction between a.f(b) and f(a, b)... It also doesn't help when you need to reuse the lambda, e.g. when sorting a range by some predicate and then merging the range into an existing one. > And for the implementation.. it doesn't matter, it's a named function, > only does one small thing and does it good. > > About the inlining, which compilers don't and does it make a difference ? Almost none do, unless they use/you switch on whole-program-optimisation. > A function call should negligible compared to erase + remove_if It's not just a function call, it's a function call though a function pointer. Costs like a virtual function call and turns C++ std::sort into C's qsort. http://stackoverflow.com/questions/4708105/performance-of-qsort-vs-stdsort Thanks, Marc -- Marc Mutz | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 February 2016 17:06:51 Thiago Macieira wrote: > On Monday 01 February 2016 11:08:54 Marc Mutz wrote: > > One way to have this with lambdas is to write a lambda that returns a > > lambda. We can do this, because auto return type deduction works for > > lambdas already in C++11, unlike for normal functions. With this, the > > above > > > > would become (hold tight): > > > > auto firstEquals = [](const auto &name) { > > Does parameter auto detection work in C++11? No, but you snipped the part of the mail where I explained that I used auto only to fit it to a single line. -- Marc Mutz | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 February 2016 11:08:54 Marc Mutz wrote: > One way to have this with lambdas is to write a lambda that returns a > lambda. We can do this, because auto return type deduction works for > lambdas already in C++11, unlike for normal functions. With this, the above > would become (hold tight): > > auto firstEquals = [](const auto &name) { Does parameter auto detection work in C++11? -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
Marc Mutz wrote: > But I find the inlined lambda worse than an explicit loop. This is > write-only code, imo. Esp. since we can't (yet) use auto in the parameter > list, but even then, I'd always give a lambda a name (cf. my mail in > response to Christian). But writing it inline and without a name is the whole point of a lambda. If you're giving it a name anyway, you may as well declare a named functor class. > Named functions have two problems: a) that many compilers don't inline the > code. So at a minimum, you'd write a forwarding lambda, or the function > would be an auto variable holding a stateless lambda (the difference > between the two is almost non-existent, anyway). And b) that they cannot > carry state. Lambdas can. Named functor classes can, too. And I actually like Sergio Martins's solution best: Write a removeIfFirstEquals(fields, name) wrapper that hides the lambda entirely. There, you can also inline the lambda because the name of the containing function (removeIfFirstEquals) makes it very clear what the lambda does. And the calling code does not have to care how the "if first equals" test is actually implemented. Kevin Kofler ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
Op 01/02/2016 om 15:16 schreef Marc Mutz: On Monday 01 February 2016 10:18:25 Jędrzej Nowacki wrote: So it would look like that: fields.erase(std::remove_if(fields.begin(), fields.end(), [&name](const QPair &header) { return qstricmp(name.constData(), header.first) == 0; }), fields.end()); // I hope that formating is still ok, and the code is not wrapped. I am a great fanboy of algorithms and the STL, as should be clear by now :) But I find the inlined lambda worse than an explicit loop. This is write-only code, imo. Esp. since we can't (yet) use auto in the parameter list, but even then, I'd always give a lambda a name (cf. my mail in response to Christian). While I applaud the naming of things, especiallly things non-trivial, I don't agree that an inlined lambda equates to write-only code. It can be, but doesn't need to be. The lambda-to-return a lambda looks more write-only than an inlined lambda does, IMHO. While self-documenting code is great, I don't think it should come at the price of outlandish constructs like lambdas-returning-lambdas. It cleans up the code at the place you call the code, I give you that, but it makes the lambda definition itself too complicated. I prefer a comment if you think that documenting what is captured at the call site is needed. auto firstEqualsName = [&name](const QPair &header) { return qstricmp(name.constData(), header.first) == 0; }; fields.erase(std::remove_if(fields.begin(), fields.end(), firstEqualsName /*captures &name*/), fields.end()); Though for this particular construct, I certainly prefer a special function. The erase + remove_if, both using the same end iterator always annoys me. So something like: removeWhereFirstEquals(container c, const QByteArray& name); André ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday, February 01, 2016 11:08:54 AM Marc Mutz wrote: > Hi, > > We're seeing increasing use of lambdas in dev, and I'm a bit unhappy about > the result. > > E.g. (not picking on Anton here, I have done the same before): > > auto firstEqualsName = [&name](const QPair &header) > { > return qstricmp(name.constData(), header.first) == 0; > }; > fields.erase(std::remove_if(fields.begin(), fields.end(), > firstEqualsName), > fields.end()); > > This is one way to write a unary predicate. But it hides the fact that the > predicate depends on the parameter 'name' (an argument to the function this > lambda is defined in). > > With classical function objects, one would have written - at the call site: > > fields.erase(std::remove_if(fields.begin(), fields.end(), > FirstEquals(name)), > fields.end()); > > See the difference? > > Now, we don't want to go back and write function objects for one-time use, > but it would be nice to have this explicit syntax, would it not? > > One way to have this with lambdas is to write a lambda that returns a > lambda. We can do this, because auto return type deduction works for > lambdas already in C++11, unlike for normal functions. With this, the above > would become (hold tight): > > auto firstEquals = [](const auto &name) { > return [&name](auto header) { return qstricmp(header.first, name) == 0; > }; } > > where I used auto and dropped the const-& argument passing only for > exposition, to get it onto a single line. > > fields.erase(std::remove_if(fields.begin(), fields.end(), > firstEquals(name)), > fields.end()); > > So, where to put the ugliness: on the definition of the lambda, or the call > site? (Note that "if you use this lambda more than once, then X" is not a > good answer, because you shouldn't use lambdas more than once. But with the > lambda- returning-lambda, you could actually reuse them: > > // at global scope: > > auto firstEquals = [](const auto &name) { > return [&name](auto header) { return qstricmp(header.first, name) == 0; > }; } > > // use in several functions - always the same type > > Whereas without the outer lambda, each use would create a new type, and > potentially duplicate code (same problem as QStringLiteral, and the same > soultion, really: wrap them in a function, except for lambdas, because of > the unnameable return type, we need to use another lambda instead of a > classical function). I would write: removeIfFirstEquals(fields, name): because: 1) I could read it in English instead of very verbose C++ 2) I would not need to read the implementation And for the implementation.. it doesn't matter, it's a named function, only does one small thing and does it good. About the inlining, which compilers don't and does it make a difference ? A function call should negligible compared to erase + remove_if Regards, -- Sérgio Martins | sergio.mart...@kdab.com | Software Engineer Klarälvdalens Datakonsult AB, a KDAB Group company Tel: Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322) KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 February 2016 14:16:57 Christian Kandeler wrote: > On 02/01/2016 03:10 PM, Marc Mutz wrote: > > The point of giving names to things (variable, functions, classes) in > > programming is so you don't need to look at the implementation all the > > time to see what it's doing. You only need to look when you want to see > > _how_ it's doing what it does. > > > > So if you think that this is not a problem, then it's not a problem for > > you, either, if local variables are named only a, b, c, ... > > Depending on the context, yes. For instance, I have never written this: > for (int thisIsACounterThatIsUsedForIteration = 0; > thisIsACounterThatIsUsedForIteration < arrayLen; > ++thisIsACounterThatIsUsedForIteration) { ... } > > Instead, I simply use the name "i". Inacceptable? No, perfectly ok. But only because by unwrit convention indexed for-loops use 'i', 'j', ... as the index variable, and iterator-based for-loops use 'it' as the iterator variable. As soon as you name an iterator 'i', say, it ceases to be acceptable. -- Marc Mutz | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On 02/01/2016 03:10 PM, Marc Mutz wrote: The point of giving names to things (variable, functions, classes) in programming is so you don't need to look at the implementation all the time to see what it's doing. You only need to look when you want to see _how_ it's doing what it does. So if you think that this is not a problem, then it's not a problem for you, either, if local variables are named only a, b, c, ... Depending on the context, yes. For instance, I have never written this: for (int thisIsACounterThatIsUsedForIteration = 0; thisIsACounterThatIsUsedForIteration < arrayLen; ++thisIsACounterThatIsUsedForIteration) { ... } Instead, I simply use the name "i". Inacceptable? Christian ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 February 2016 10:18:25 Jędrzej Nowacki wrote: > So it would look like that: > > fields.erase(std::remove_if(fields.begin(), > fields.end(), > [&name](const QPair > &header) > { > return qstricmp(name.constData(), > header.first) == 0; > }), >fields.end()); > > // I hope that formating is still ok, and the code is not wrapped. > I am a great fanboy of algorithms and the STL, as should be clear by now :) But I find the inlined lambda worse than an explicit loop. This is write-only code, imo. Esp. since we can't (yet) use auto in the parameter list, but even then, I'd always give a lambda a name (cf. my mail in response to Christian). > For a bigger code we would actually require named functions. What do you > think? Named functions have two problems: a) that many compilers don't inline the code. So at a minimum, you'd write a forwarding lambda, or the function would be an auto variable holding a stateless lambda (the difference between the two is almost non-existent, anyway). And b) that they cannot carry state. Lambdas can. Thanks, Marc -- Marc Mutz | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 February 2016 10:23:34 Christian Kandeler wrote: > On 02/01/2016 11:08 AM, Marc Mutz wrote: > > We're seeing increasing use of lambdas in dev, and I'm a bit unhappy > > about the result. > > > > E.g. (not picking on Anton here, I have done the same before): > > auto firstEqualsName = [&name](const QPair > > &header) { > > > >return qstricmp(name.constData(), header.first) == 0; > > > > }; > > fields.erase(std::remove_if(fields.begin(), fields.end(), > > > > firstEqualsName), > > > >fields.end()); > > > > This is one way to write a unary predicate. But it hides the fact that > > the predicate depends on the parameter 'name' (an argument to the > > function this lambda is defined in). > > > > With classical function objects, one would have written - at the call site: > > fields.erase(std::remove_if(fields.begin(), fields.end(), > > > > FirstEquals(name)), > > > >fields.end()); > > > > See the difference? > > Yes, but it is offset by another difference: As opposed to the function > object, the lambda is defined right above the call site (or at least > very close to it), so you can easily see that it captures an additional > variable. > I therefore think that this is not a problem. The point of giving names to things (variable, functions, classes) in programming is so you don't need to look at the implementation all the time to see what it's doing. You only need to look when you want to see _how_ it's doing what it does. So if you think that this is not a problem, then it's not a problem for you, either, if local variables are named only a, b, c, ... And I disagree. Thanks, Marc -- Marc Mutz | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On 02/01/2016 11:08 AM, Marc Mutz wrote: We're seeing increasing use of lambdas in dev, and I'm a bit unhappy about the result. E.g. (not picking on Anton here, I have done the same before): auto firstEqualsName = [&name](const QPair &header) { return qstricmp(name.constData(), header.first) == 0; }; fields.erase(std::remove_if(fields.begin(), fields.end(), firstEqualsName), fields.end()); This is one way to write a unary predicate. But it hides the fact that the predicate depends on the parameter 'name' (an argument to the function this lambda is defined in). With classical function objects, one would have written - at the call site: fields.erase(std::remove_if(fields.begin(), fields.end(), FirstEquals(name)), fields.end()); See the difference? Yes, but it is offset by another difference: As opposed to the function object, the lambda is defined right above the call site (or at least very close to it), so you can easily see that it captures an additional variable. I therefore think that this is not a problem. Christian ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: lambda or lambda return from lambda?
On Monday 01 of February 2016 11:08:54 Marc Mutz wrote: > Hi, > > We're seeing increasing use of lambdas in dev, and I'm a bit unhappy about > the result. > > E.g. (not picking on Anton here, I have done the same before): > > auto firstEqualsName = [&name](const QPair &header) > { > return qstricmp(name.constData(), header.first) == 0; > }; > fields.erase(std::remove_if(fields.begin(), fields.end(), > firstEqualsName), > fields.end()); > > This is one way to write a unary predicate. But it hides the fact that the > predicate depends on the parameter 'name' (an argument to the function this > lambda is defined in). > > With classical function objects, one would have written - at the call site: > > fields.erase(std::remove_if(fields.begin(), fields.end(), > FirstEquals(name)), > fields.end()); > > See the difference? > > Now, we don't want to go back and write function objects for one-time use, > but it would be nice to have this explicit syntax, would it not? > > One way to have this with lambdas is to write a lambda that returns a > lambda. We can do this, because auto return type deduction works for > lambdas already in C++11, unlike for normal functions. With this, the above > would become (hold tight): > > auto firstEquals = [](const auto &name) { > return [&name](auto header) { return qstricmp(header.first, name) == 0; > }; } > > where I used auto and dropped the const-& argument passing only for > exposition, to get it onto a single line. > > fields.erase(std::remove_if(fields.begin(), fields.end(), > firstEquals(name)), > fields.end()); > > So, where to put the ugliness: on the definition of the lambda, or the call > site? (Note that "if you use this lambda more than once, then X" is not a > good answer, because you shouldn't use lambdas more than once. But with the > lambda- returning-lambda, you could actually reuse them: > > // at global scope: > > auto firstEquals = [](const auto &name) { > return [&name](auto header) { return qstricmp(header.first, name) == 0; > }; } > > // use in several functions - always the same type > > Whereas without the outer lambda, each use would create a new type, and > potentially duplicate code (same problem as QStringLiteral, and the same > soultion, really: wrap them in a function, except for lambdas, because of > the unnameable return type, we need to use another lambda instead of a > classical function). > > So, which one to use? > > Thanks, > Marc Hi, I would just inline the lambda inside remove_if. That way "name" would be explicit in place in which it is used and you could avoid 2nd lambda. So it would look like that: fields.erase(std::remove_if(fields.begin(), fields.end(), [&name](const QPair &header) { return qstricmp(name.constData(), header.first) == 0; }), fields.end()); // I hope that formating is still ok, and the code is not wrapped. For a bigger code we would actually require named functions. What do you think? Cheers, Jędrek ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
[Development] RFC: lambda or lambda return from lambda?
Hi, We're seeing increasing use of lambdas in dev, and I'm a bit unhappy about the result. E.g. (not picking on Anton here, I have done the same before): auto firstEqualsName = [&name](const QPair &header) { return qstricmp(name.constData(), header.first) == 0; }; fields.erase(std::remove_if(fields.begin(), fields.end(), firstEqualsName), fields.end()); This is one way to write a unary predicate. But it hides the fact that the predicate depends on the parameter 'name' (an argument to the function this lambda is defined in). With classical function objects, one would have written - at the call site: fields.erase(std::remove_if(fields.begin(), fields.end(), FirstEquals(name)), fields.end()); See the difference? Now, we don't want to go back and write function objects for one-time use, but it would be nice to have this explicit syntax, would it not? One way to have this with lambdas is to write a lambda that returns a lambda. We can do this, because auto return type deduction works for lambdas already in C++11, unlike for normal functions. With this, the above would become (hold tight): auto firstEquals = [](const auto &name) { return [&name](auto header) { return qstricmp(header.first, name) == 0; }; } where I used auto and dropped the const-& argument passing only for exposition, to get it onto a single line. fields.erase(std::remove_if(fields.begin(), fields.end(), firstEquals(name)), fields.end()); So, where to put the ugliness: on the definition of the lambda, or the call site? (Note that "if you use this lambda more than once, then X" is not a good answer, because you shouldn't use lambdas more than once. But with the lambda- returning-lambda, you could actually reuse them: // at global scope: auto firstEquals = [](const auto &name) { return [&name](auto header) { return qstricmp(header.first, name) == 0; }; } // use in several functions - always the same type Whereas without the outer lambda, each use would create a new type, and potentially duplicate code (same problem as QStringLiteral, and the same soultion, really: wrap them in a function, except for lambdas, because of the unnameable return type, we need to use another lambda instead of a classical function). So, which one to use? Thanks, Marc -- Marc Mutz | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development