Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm in a situation where I need to explain lambda expressions to a colleague. He's well-educated, with some programming experience, and my first time showing him lambda expressions seemed to go well. What I'm not explaining well to him is the idea that you can nest lambda expressions inside each other.

I use lambdas all the time, and feel like this should be easy to explain to him, but I'm having trouble coming up with an example on the spot, so I'll just pass his question on to all of you:

Why would anyone ever need to nest lambda expressions?

I'm looking for an example sort of like this:

x.f(y => y.g(z => y+z))

where one lambda expression is nested inside another, where the innermost bit of code (y+z in this example) makes use of both lambda input parameters.

We're using C#, but the language isn't what matters, just a situation where you'd want nested lambdas in a language that isn't mostly lambda calculus.

share|improve this question
3  
Any time you have a closure, only you don't write the outer function as lambda because it's messy ;) Less practically, I don't see why it shouldn't be possible. Any expression may be inside a lambda, otherwise they'd be needlessly limited, right? And lambdas are also just expressions. –  delnan May 8 '12 at 19:31
2  
Our resident expert, Jon Skeet, has a great blog entry on combining as such: msmvps.com/blogs/jon_skeet/archive/2012/01/30/… –  Jesse C. Slicer May 8 '12 at 19:31
    
@delnan, can you give an example? –  Joe May 8 '12 at 19:43
    
@JesseC.Slicer, that article gives a great explanation of what partial application and currying are, I'm looking for an explanation of why someone would ever nest lambda expressions. –  Joe May 8 '12 at 19:44
    
I suppose if you were using lambda functions for event handlers, then somewhere in your event handler you had to set an event handler on something else... but I don't recall ever having to do anything quite like that. –  FrustratedWithFormsDesigner May 8 '12 at 20:30
show 2 more comments

6 Answers

up vote 6 down vote accepted

Here's a completely contrived example of where they might come in handy. I have widgets. Each widget has parts. Both widgets and parts have a category.

I want to find all the widgets which contain a part with a category that matches the widget's category. Nested lambdas make this easy:

var matchingWidgets = widgets.Where(w => w.Parts.Any(p => w.Category == p.Category))

Although this particular example is just for demonstration purposes, I regularly use the 'find all x in y where x.something(z) is true' pattern.

share|improve this answer
    
Contrived is perfect, since this is for trying to get across the idea of where a nested lambda might come in handy. –  Joe May 9 '12 at 0:01
add comment

if you use RhinoMock, this could be a common example:

log.AssertWasCalled(o => o.LogError(Arg<Exception>.Matches(x => x.Message.Contains("BadNews"))));
share|improve this answer
add comment

an outer join

var barfooPairs = foos.SelectMany(foo => bars.Select(bar => new { Foo = foo, Bar = bar }));

an inner join

var barfooPairs = foos.SelectMany(foo => foo.Bars.Select(bar => new { Foo = foo, Bar = bar }));
share|improve this answer
add comment

In lambda calculus you need to 'nest' or chain functions whenever you want more than one input to an expression.

When would you want more than one input to a function? Well let's say you want to determine the cost of a train ticket. You'll need to know the passenger's age (they might be a age pensioner), their destination (varies the cost), and the date and time (tickets are cheaper on the weekends).

age -> (dest -> (time -> { calculate the ticket price based on age, dest, & time }))

Or perhaps you want to know how far you can drive on a tank of fuel

sizeOfTank -> (fuelConsumption -> (speed -> { calculate distance }))

Whenever you have multiple variables in your calculation you will need to chain functions. Any example you can think of that involves multiple parameters will demonstrate this.

share|improve this answer
    
while this is a good way of speaking of monads without actually saying their name, I don't think it is a good example since their are not really usefull in C# –  Simon May 9 '12 at 9:24
    
@Simon isn't linq a monad? i'd say linq is pretty useful in C# –  jk. May 9 '12 at 10:57
    
@jk. indeed. But I would rather use one lambda with multiple inputs instead of nested lambdas. –  Simon May 9 '12 at 11:39
add comment

Yes, lambda is the new "hotness", but are nested lambda not just the same thing as sql sub queries? - (me)

@Darknight, can you give an example? - Joe

Since its difficult to write an example in the comments, I'll put it here:

from the top of my head, just some made up example:

select header_title, header_meta, header_spec
from t_header where header_link_Id in
                 ( 
                   select       case when IsTrans = 1 then 
                                  Parent_Id
                               else then
                                  Child_Id
                               end as header_link_id
                   from        t_trans_log
                   where       status_Id in 
                                            (
                                             select status_Id 
                                             from t_status_codes where type_id = 457
                                            )
                  )
  and             tsamp between x and y
share|improve this answer
3  
Correlated subqueries generally go in reverse from inner to outer though, whereas lambdas go from outer to inner and can pass parameters. Since most programmers don't understand how SQL is implemented I don't think this example is going to help a beginner at lambdas understand their use. –  Jordan May 8 '12 at 21:52
    
ah, yes you are correct. –  Darknight May 9 '12 at 11:14
add comment

Think about what a lambda is for a moment. It's a simple construct representing a type of inline function, which means it can effectively be used for any purpose that a regular function can be.

The real value of the lambda is that it can allow you to create a simple one-time method that doesn't need to exist anywhere else except for the method where it is used, and therefore you can avoid littering a class with a lot of seemingly useless helper methods. On the other hand, lambdas might seem to make the code a little harder to read in some cases and could also make the code seem a little less clean, particularly if you want your lambda to do a lot of things, in which case, creating a method would probably be better. A risk is that lambdas can be used in the way that made method nesting a kind of a bad idea in Object Pascal, while one of the benefits is that lambdas are often used to provide a simple inline function that can act as a filter when searching lists or validating values.

As regards to how or why this might be useful, the example that you've provided shows this quite elegantly. An inner function performs a function which returns a result as a parameter to the outer function, which is in turn used to generate a result which is passed out to something else. You could explain that simple math isn't the only thing that you can do. You could for example use this form to perform some sort of validation of the "Z" value in your example, or you could use the form to invoke a method that requires some sort of variable input to create objects, or perhaps even to choose and pass about a method pointer.

share|improve this answer
    
That's a great explanation. At the end of it, my colleague is going to say, "So show me a time you'd use one of those." Can you show me an example? –  Joe May 9 '12 at 0:03
    
@joe See the excellent examples by either Kirk or Marty. –  S.Robins May 9 '12 at 7:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.