I'm the author of the article and very interested reading all the discussion.
Let me explain exactly what the issue is as there seems to have been a bit of confusion about my intentions.
I understand that by stepping into the lambda we are effectively stepping into a new frame analogous to 'stepping into a method' - therefore variables outside the frame will not be visible inside that frame.
But - if we are stepping into a for loop of sorts (or perhaps the lines() method of Files) - you do want to see the other variables in the enclosing method. And the point is that using the old constructs this is exactly what you were able to do.
Java is not functional enough (or at least the way I code isn't) that all the variables I need will be enclosed in the lambda.
In fact when you step into a lambda you retain the scope of the enclosing class (unlike an inner class), so for example when you call toString() you will be printing the toString() of the enclosing object. For this reason it makes sense that in the debugger you should not be considered to have stepped into a new frame when you drop into a lambda.
Ultimately this is all about usability and in real life I have found it extremely frustrating that I can't easily observe the values outside the lambda.
> therefore variables outside the frame will not be visible inside that frame.
You know that the debugger can traverse the stack and show variables for the outer frames (assuming the lambda is invoked down-stack, as in your example), right? This is just a visualization issue of the debugger you're using and not a problem with lambdas themselves.
Javascript debuggers had to deal with this (the scope chain) for much longer, that's why variable views of JS debuggers show the whole scope chain instead of just the local frame.
I'm not associated with them, but they asked me for an eclipse screenshot if I had one, when I reported this issue to them and suggested that they create a workaround in their UI. (FWIW it's an annoying issue, but not enough for _me_ to stop using lambdas.)
If you have time, could you make the lambda a multi line chunk of code, so that it's clear that the breakpoint is inside the lambda? I'll pass it on to them. Thanks!
Of course this only works for cases where the debugger can tie the lambda used as method argument to another stack frame, i.e. it doesn't help with async invocations. But in async cases one cannot expect the JVM to lug around the whole stack frame from the time it was created, that could lead to memory leaks.
And from what I've gathered the Jetbrains bug may not talking about the same thing as the blog postis discussing. Their case is about a captured variable that gets inlined in some way that makes debugging difficult, OP is about inspecting arbitrary, non-captured variables in the debugger.
The lambda effectively is an anonymous class implementing that interface / that single method. U resolves to ? super String. I.e. it expects a method that takes String or a superclass thereof as its first parameter.
That's what e is. It all gets automatically pieced together at compile time via type inference.
Looks like this is an IDE issue. When C# implemented lambdas almost 8 years ago, the initial debugging was a little confusing. But quickly VS was improved to support better integration. Just give some time for the IDEs to catch up.
I would love to be able to evaluate lambdas in the debugger watch window in Visual Studio. Something like list.First(i=>i.Value==someValue) requires using a temporary variable, at least in VS2013.
Let me explain exactly what the issue is as there seems to have been a bit of confusion about my intentions.
I understand that by stepping into the lambda we are effectively stepping into a new frame analogous to 'stepping into a method' - therefore variables outside the frame will not be visible inside that frame.
But - if we are stepping into a for loop of sorts (or perhaps the lines() method of Files) - you do want to see the other variables in the enclosing method. And the point is that using the old constructs this is exactly what you were able to do.
Java is not functional enough (or at least the way I code isn't) that all the variables I need will be enclosed in the lambda.
In fact when you step into a lambda you retain the scope of the enclosing class (unlike an inner class), so for example when you call toString() you will be printing the toString() of the enclosing object. For this reason it makes sense that in the debugger you should not be considered to have stepped into a new frame when you drop into a lambda.
Ultimately this is all about usability and in real life I have found it extremely frustrating that I can't easily observe the values outside the lambda.