Jump to content

  • Log In with Google      Sign In   
  • Create Account

Anonymous/lamda functions: curse or blessing?


Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
19 replies to this topic

#1 doeme   Members   -  Reputation: 1127

Like
0Likes
Like

Posted 17 November 2011 - 02:17 AM

As C++0x includes support for lambda-functions[1] this sparked some discussion at my workplace about if they are a 'do' or a 'dont'. Of course this is a pretty complex matter and the pros and cons depend on a lot of circumstances, but I would like to hear some opinions about the use of anonymous functions.

Do they make the code unreadable and hard to maintain?
Are they the perfect way to create spaghetti-code? (one of our developers actually thinks they are as bad as a goto)
Are they a problem with code-stabilty?
Is the use of lambda-functions the perfect way to soft-code things? [2]

What are your experiences and opinions with them?

* [1] Using Microsofts definition of 'lambda-function'
"A lambda expression is a function or subroutine without a name that can be used wherever a delegate is valid. Lambda expressions can be functions or subroutines and can be single-line or multi-line. You can pass values from the current scope to a lambda expression. (from http://msdn.microsof...y/bb531253.aspx)"

* [2] http://thedailywtf.c...oft_Coding.aspx

Sponsor:

#2 wqking   Members   -  Reputation: 756

Like
-1Likes
Like

Posted 17 November 2011 - 02:41 AM

I didn't use any lambda feature in C++. (It's too new)
But I used a lot closure (a little same as lambda) in ActionScript.

Here are my opinions,

1, Treat lambda as expression rather than function.
That implies that lambda should be quite simple (1~several, maybe 5 lines of code).
If it goes complicated, it worths a well named function or functor object.
With this rule, lambda won't break readability because every one can read what it does in its simple code.

2, I don't know what other usage of lambda, but I only used it (AS closure) as callbacks.

My 2 cents

http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.


#3 L. Spiro   Crossbones+   -  Reputation: 22677

Like
1Likes
Like

Posted 17 November 2011 - 02:43 AM

#2: Spaghetti is up to so much more than just a feature of a language. My code won't become spaghetti because I used lambda functions. It would be because I have poor organizational skills.
If some at your office are that way, perhaps they should have some restrictions in place, and not just in regards to lambda.

#3: I don't see how they could make your code unstable.

#1: Hard to read? Contrarily I find it handy having the function definition right there so I can see how the short stub of delegate code is working.
Since I only use them for very short segments of code, such as with sort functions, they don't clutter up my functions much.
Additionally, they really tend not to need maintaining. I only use them for very specific purposes that, once implemented, have a very very low chance of ever needing to change in the future.


I wouldn't worry about these issues unless you actually start to see them happening.
And if you do, you may want to consider other things besides just the use of lambda functions as contributors to that mess.
If you do find lambdas to be the problem, focus on what caused that problem and revise your policy on when and where you use them.
That doesn't mean ban them, but make a note that they are not suitable for that type of task and just don't use them for that.


L. Spiro

#4 Triangles-PCT   Members   -  Reputation: 513

Like
0Likes
Like

Posted 17 November 2011 - 02:45 AM

They are great, probably the best feature in C++0x.

Makes code more readable since it can be placed where it is used.

Also easier to read since less boilerplate nonsense(C++03 functors).



#5 doeme   Members   -  Reputation: 1127

Like
0Likes
Like

Posted 17 November 2011 - 04:03 AM

I quite like the way to add small code snippets with lambda expressions.

What really sparked the discussion was that the syntax of the lambda-indroducer ([], [=], [&]) and the definition of return types with -> may look confusing at first sight. This is as well the main argument to making them "unreadable".

Concerning code stability this was more an issue in conjunction with the signal/slot mechanism, where we registered a lambda-expression to a signal and then deleted the object around it which left the expression dangling around.

#6 Neilo   Members   -  Reputation: 290

Like
2Likes
Like

Posted 17 November 2011 - 05:43 AM

Lambdas and asynchronous code go so well together and make that sort of code more readable and maintainable in my opinion.

#7 phantom   Members   -  Reputation: 9557

Like
2Likes
Like

Posted 17 November 2011 - 02:06 PM

What really sparked the discussion was that the syntax of the lambda-indroducer ([], [=], [&]) and the definition of return types with -> may look confusing at first sight. This is as well the main argument to making them "unreadable".


Meh, I'd consider that more a case of 'being new' rather than 'unreadable'. I dare say the first time your co-workers looked at C or C++ they felt it was 'unreadable' but soon got use to it. Personally I took to it right away and for places where it makes sense I find combining it with the various C++ algorthims it makes code considerably more readable.

Concerning code stability this was more an issue in conjunction with the signal/slot mechanism, where we registered a lambda-expression to a signal and then deleted the object around it which left the expression dangling around.


While a problem it's not a problem unique to lambda functions; anything where you can pass a reference/pointer around in your code can hit that problem too.

As for the original questions;

1) Once you grok the syntax I'd say no. If anything they make code easier to maintain as the functionality is right there in front of you rather than shuffled off into some function or functor object requiring a scroll about to see what is going on.

2) Again; no. You can hardly 'spagetti code' thing as the defintions are right in front of you. You can't go jumping about the place and is probably less spagetti inducing than a normal function.

3) No more so than any other feature and as I'd argue their locality to usage for things like registering call backs you'll gain better code stability. Problems such as 'we registered a call back and now it is left dangling!' can be done just as well with a pointer.

4) Scripting languages and config files are perfect for soft coding. Lambda's bring nothing new to the table here.


Lambdas + std::function + std::bind allow for some pretty cool things to be done much easier; granted, I don't use these at work due to the need to be compatible with 3 consoles and the PC, but at home I'm all VS2010's and lambda'd up :)

#8 Telastyn   Crossbones+   -  Reputation: 3771

Like
0Likes
Like

Posted 17 November 2011 - 02:38 PM

I don't know much about C++0x's implementation, so I'm going to assume it's reasonable to other languages' and not broken.

Do they make the code unreadable and hard to maintain?


They can. C++0x's syntax is a bit verbose which might be problematic, but it's got to be better than functors or a mush of binding hoops right?

Are they the perfect way to create spaghetti-code? (one of our developers actually thinks they are as bad as a goto)


They can easily be abused, but they tend not to just slide naturally toward abuse.

Are they a problem with code-stabilty?


No. Localizing little expressions into lambdas as opposed to functors or helper functions like you have to do now can only help code stability from a bit-rot standpoint.

Is the use of lambda-functions the perfect way to soft-code things? [2]


Enh. When you use lambdas it's because you're passing them somewhere. If what consumes them is uncoupled/configurable enough to take a lambda in the first place, it's easier to un-hard/soft-code the problem bits.

What are your experiences and opinions with them?


Without them, it becomes difficult to write properly generic code. Any sort of case where you need variable behavior becomes awkward to use, either at the call site or in maintenance when you're trying to figure out what this magic enum means you should do...

I like the code-locality of them. I don't have to skip through files to find out exactly what this or that helper function does. The predicate (or other plugged behavior) is right there.

The auto-magical scope closure behavior I've found is increasingly important to create 'lazy' behavior that detects changes to a variable without the headaches of alternatives like polling or event proliferation or improper knowledge of observers.


In general, this sort of thing is good and will become more good and vital as functional and parallel computing continue their inroads into general purpose programming.

#9 jwezorek   Crossbones+   -  Reputation: 2337

Like
1Likes
Like

Posted 18 November 2011 - 05:09 PM

C++ lambdas make the STL work the way it was always supposed to work. Without them you had to bend over backwards to use STL algorithms unless you didn't mind your code sprinkled with many one or two line free or static functions. I mean don't get me wrong, you could do a lot with boost::bind and so forth it's just that it required a lot more thought than [&](const Foo& foo) -> Bar { return foo.bar(); } etc .

Although I do find it a little sad that boost::bind, et. al., have basically been deprecated now -- that stuff was amazing.

#10 Wooh   Members   -  Reputation: 1019

Like
0Likes
Like

Posted 18 November 2011 - 05:36 PM

Although I do find it a little sad that boost::bind, et. al., have basically been deprecated now -- that stuff was amazing.

If it's deprecated why was it added to C++11 then?

#11 Ravyne   GDNet+   -  Reputation: 12253

Like
1Likes
Like

Posted 18 November 2011 - 05:38 PM

All C++0x lambdas are is a nice syntax for function objects (delegates) -- literally.

I had to back port a bunch of code that was written using early support for lambdas because the static analysis tool I was using on the code didn't yet support them. The translation was mechanical; I could have trained a monkey to do it. My understanding is that this is essentially the same as what the compiler does -- so there's no worries about them doing scary stuff behind your back. The code is a lot more readable with lambdas because a) the body of the function is right where you need it, and b) you loose all the function-object overhead you'd need otherwise -- a minimal function object is probably around a dozen lines of code, vs many minimal lambdas that fit in just a portion of a single line.

Think about it this way -- How many times have you *not* used function objects in your design when you wanted to because the overhead was a pain to deal with? Or, how many hours have you wasted writing, refactoring and debugging function objects where you did use them? These are basically the problems that C++0x lambdas solve -- They make the barrier to entry for writing robust, re-usable (composible) code incredibly low. This is probably why your co-worker is scared, function objects are painful, therefore something that makes them easier must be evil. Fortunately, the exact opposite is true.

As JWezorek points out, they make the C++ Standard Library work "like its supposed to" -- The Standard Library is built around this kind of compositional ability (using compile-time polymorphism implemented through template parameters -- things like comparison objects and custom allocators), and if lambda support had been around earlier the standard library would no doubt have used them instead.

Another thing is that they go hand-in-hand with asynchronous programming -- which is a huge and growing deal. Its great for UIs, great for long-running processes, IO, remote calls and much more. Asynchronous programming is going to be unavoidable from here on out, you best get ready for it.

Lambdas, 'auto' and move semantics are the three big things that will change the way we write C++ in the coming years. A lot of the template stuff (variadic templates) is arguably more game-changing, but its going to be a while before support for that is wide-spread, while lambdas, 'auto' and move semantics are here today pretty broadly, and furthermore template programming (and template meta-programming, more specifically) are still quite a dark art for many.

[EDIT: Thanks Zahlman for fixing the formatting. Sticking with the non-rich editor from now on; its more trouble than its worth.]

throw table_exception("(ノ ゜Д゜)ノ ︵ ┻━┻");


#12 Ravyne   GDNet+   -  Reputation: 12253

Like
0Likes
Like

Posted 18 November 2011 - 05:52 PM

Forgive the formatting and wall of text. I don't understand how they adopted third-party software that specializes in this sort of thing, yet is so freaking broken. Trying to fix it only makes it worse.

throw table_exception("(ノ ゜Д゜)ノ ︵ ┻━┻");


#13 Hodgman   Moderators   -  Reputation: 46553

Like
0Likes
Like

Posted 18 November 2011 - 08:24 PM

At work, the standard interview questions cover lambdas and closures.

If a prospective gameplay programmer can't answer these questions, they're probably not going to get the job, because they've just shown they're not familiar with modern programming. 'nuff said Posted Image

A prospective systems programmer might be more likely to get away with not knowing this stuff, because they're expected to be working in C++ (pre-0x) most of the time (though, they should still known the concept of a functor etc).

Regarding their use in C++, you'll find that most code-bases already use something analogous to them (functors etc). All this addition does is make the syntax for this existing technique nicer.

[edit] @Ravyne, You've got to kill it with fire: edit post->full editor->select all->remove formatting->insert all your newlines again...

#14 Bregma   Crossbones+   -  Reputation: 7055

Like
1Likes
Like

Posted 18 November 2011 - 09:35 PM

I've been using them quite a bit lately.

Their use requires getting up a bit of a learning curve and training your eye to recognize a new syntax. I'm not too old, I can do that, so can you and your cow orkers.

As long as their bodies are kept fairly short, they are scads better than the more traditional functor found elsewhere in the code: this is the code locality advantage others have mentioned.

After considerable experimentation, I determined that using a lambda with std::for_each is almost never worth it. A simple range-for or a for-loop with auto variables is clearer in both intent and typography. The flip side is lambdas are ideal for use as one-off predicates in other algorithms.

They are a useful tool and like most tools, have their ideal use and potential for abuse. Do not let timorous cow orkers fool you into thinking change is bad because change is bad. Find better cow orkers instead.
Stephen M. Webb
Professional Free Software Developer

#15 MaxDZ8   Crossbones+   -  Reputation: 4590

Like
0Likes
Like

Posted 19 November 2011 - 03:37 AM

Their use requires getting up a bit of a learning curve and training your eye to recognize a new syntax. I'm not too old, I can do that, so can you and your coworkers.

100% agreed. I have been looking forward to use them since C++0x was announced.

BTW, I currently assimilate them to "inlined function pointers". Any thoughts on that?

Edited by Krohm, 19 November 2011 - 03:38 AM.

Previously "Krohm"


#16 mrbastard   Members   -  Reputation: 1574

Like
0Likes
Like

Posted 19 November 2011 - 07:50 AM

After considerable experimentation, I determined that using a lambda with std::for_each is almost never worth it. A simple range-for or a for-loop with auto variables is clearer in both intent and typography. The flip side is lambdas are ideal for use as one-off predicates in other algorithms.


I think using a lambda as the body for for_each is still clearer than a plain for-loop - the normal for-loop body can break, return, and change the loop variable or size of the collection you're iterating over (ouch!). I think you're suggesting using range-for in that case, but unfortunately for me msvc doesn't yet support it.

Maybe I'm just weird though - I'm starting to prefer find_if with a lambda to a raw while loop, for example.

In a fit of over-enthusiam for lambdas, I experimented with using a lazily evaluated integer range (i.e. boost::counting_iterator) with for_each and a lambda, instead of plain for-loop. Interestingly, it seemed to be only 10% slower than the plain for-loop, which only made a difference in my inner-most loops. I was also playing with concurrancy libraries though, so that 10% may not be generally applicable Posted Image


#17 Antheus   Members   -  Reputation: 2409

Like
0Likes
Like

Posted 19 November 2011 - 08:15 AM

Forgive the formatting and wall of text. I don't understand how they adopted third-party software that specializes in this sort of thing, yet is so freaking broken. Trying to fix it only makes it worse.


It's HTML5. You know, the future of the web, the computing, the holy grail that replaced Flash and other buggy technologies and crappy native apps.The technology which just works in every browser on every device for everything imaginable. People have ported Linux to it and the new era of rich web apps awaits us.

#18 iMalc   Crossbones+   -  Reputation: 2466

Like
0Likes
Like

Posted 19 November 2011 - 02:14 PM

No one has mentioned what it's like when it comes to debugging code that uses lamdas. What are other's experiences there?
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

#19 phantom   Members   -  Reputation: 9557

Like
0Likes
Like

Posted 19 November 2011 - 06:27 PM

I've so far only had to single step code which is a lambda for a std::for_each (or a function like it) at which point it does what you expect; simply step into the code much like it is a normal function/scope with no sillyness.

It might be different if you bind a lambda to a std::function and step in but as I've had no reason to debug that yet I couldn't say.

(All experiance with VS2010)

#20 Zahlman   Moderators   -  Reputation: 1682

Like
0Likes
Like

Posted 20 November 2011 - 11:46 PM

Forgive the formatting and wall of text. I don't understand how they adopted third-party software that specializes in this sort of thing, yet is so freaking broken. Trying to fix it only makes it worse.


I think I fixed it. My suggestion: go to "My Settings" and uncheck "Enable visual (RTE) editor?", and kick it old-school.




Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.




PARTNERS