7 ms·
What's Stopping Me Using Java8 Lambdas – Try Debugging Them
- phamilton 12y agoWith more of an FP background (erlang / haskell) I was a little confused regarding when you would need to inspect variables outside the lambda. Won't the external variables be the same as they were before you called forEach? Why do you want to check that each iteration? Then I realized that mutating variables is fairly common in a loop in procedural programming and that if you were to translate that to a forEach it would be useful to see what was going on. I think the introduction of FP concepts in Java 8 is going to be interesting when it is not accompanied by immutability and other foundations in the language (or at least idiomatic usage like in Scala). I can't tell if that will cripple them or make them more accessible.
- jeorgun 12y agoIt's not like Java's the first imperative language to include FP concepts. Whatever lessons it can teach us, we could probably learn them just as well from Ruby, Python, C++, Javasript, C#, and so forth.
- phamilton 12y agoTrue, but those languages have a strong set of idioms for coding. For example, even though Ruby supports mutable calls, they are generally the exception and denoted with a ! (eg map vs map!) Meanwhile, Python is idiomatically opposed to map (to the point of intentionally crippling lambdas) in favor of list comprehensions. My concern is whether Java8 will spark a strong change in idiomatic usage or if it will just be another incremental change to the current status quo.
- cynicalkane 12y agoHis complaint isn't about not seeing mutating values each iteration, but that he can't see them at all. It's very common to want to know what's in the surrounding code, especially in the giant, incompletely specified and documented lumps of software characteristic of Java.
- douche 12y agoMy guess would be that lambdas in Java will look pretty much like lambdas in C#. Something like LINQ in Java would be quite nice.
- kristianp 12y agoThis reminds me of how spoilt I am, with features such as edit-and-continue in Visual Studio. Doing some work recently with a more modern project that uses lambdas, edit and continue is not supported for code in lambdas. I miss the more interactive mode of writing code while executing it in the debugger. A more modern version of a REPL if you will.
- deleted 12y ago[deleted]
- narrator 12y agoYou can do this with eclipse if you're just changing the body of the function. The JRebel plugin lets you change just about anything and continue.
- joshschreuder 12y agoVS2015 will have the ability to watch the result of lambdas in debug mode, not sure about edit and continue however. http://blogs.msdn.com/b/visualstudioalm/archive/2014/11/12/support-for-debugging-lambda-expressions-with-visual-studio-2015.aspx http://blogs.msdn.com/b/visualstudioalm/archive/2014/11/12/s...
- rjbwork 12y agoAnd let you use them in the immediate window. No more hacks to figure out what element of a list/array is blowing up your code!
- zak_mc_kracken 12y agoEclipse has had this feature for many years. Not only can you edit and continue, but you can actually restart a function from the beginning ("Drop to frame").
- rjbwork 12y agoYes, and visual studio lets you drag your current line pointer at any line within a certain scope, so if the first part of your function does some set-up calculations, no need to rerun after changing, just set your current line pointer at the line below and voila!
- franzwong 12y agoIf you cannot distinguish it is java or IDE problem, should you update your title?
- iwince 12y agoPerhaps you should downgrade your title from human to arse.
- hnriot 12y agoit's hardly java's fault he's looking at a stack frame and not seeing the variables that belong to a different stack. This is simply a matter of selecting a frame prior to the forEach.
- chris_wot 12y agoI disagree. The lambda expression allows him to use variables outside of the stack frame, why shouldn't the debugger also be able to show those same variables?
- jdmichal 12y agoThe single example does not show a lambda that requires variable capture.
- iwince 12y agoEclipse's debugger can be configured to show a refined output. The controls are in the upper right in the Debug Perspective. Programmers who make applications are not programmers who write IDE's. If I'd noticed this I don't know if I'd recognized it or dug into it more to understand it but a snarky comment like the one I replied to is not appropriate or helpful.
- nkhodyunya 12y agoWhy don't you use simply System.out::println instead of letter -> System.out.println(letter)?
- Bjartr 12y agoI know eclipse lets you jump up and down stack frames during debugging, I assume IDEA lets you do the same. So, while inconvenient, couldn't you jump up to the calling frame and inspect the variable in question from its scope?
- alex_duf 12y agoYep, I confirm, intelliJ does know how to do that. I don't understand the rant either, so I'm going to assume he doesn't know how to use the stack on the bottom left of the debugger.
- ts4z 12y agoThere's no guarantee the method that created the lambda is still on the stack. If a method returns a callback, the method that created the lambda has returned before the lambda is called.
- organsnyder 12y agoBut wouldn't the stacktrace still include the file and line number where the lambda was created? Yes, you can't easily trace the code path between the creation of the lambda to its execution, but that strikes me as no different than debugging any other issue with bad data.
- lmm 12y agoIronically using Scala lambdas - which are much more of a hack, being compiled to an $1 object with the captured variables as fields and the implementation as a method - I can see the variables when debugging just fine.
- danielshaya 12y agoI'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.
- mike_hearn 12y agoI'm not sure this is a great argument. Lambdas are great for many things. Replacing old fashioned for loops isn't one of them. You get something harder to read, harder to debug and which is less efficient so why would you do that? If you aren't parallelising things there is little point. Lambdas are a nice way to reduce the boilerplate associated with anonymous inner classes, and that's about the limit of how I use them.
- bakhy 12y agoAs I commented there, it should be very simple to switch the stack frame you are currently inspecting in the debugger. At least it's a piece of cake in C#, both in MonoDevelop and Visual Studio. OTOH, putting everything into every lambda's closure is inefficient. In the example in the article, the lambda did not close over anything in the outer scope, and can be compiled into a faster static method.
- JackFr 12y agoI've stopped using functions for just the same reason.
- hrjet 12y agoIn Java, you can think of lambdas as sugar for anonymous classes. All problems and benefits that are present with anon classes should manifest with lambdas as well. However, one clear advantage of lambdas is that they reduce verbosity of anon classes.
- iwince 12y agoI like the verbosity of anon classes, they make sense. They look right in the debugger. Lambdas do not look clear they look like vodoo, I very much dislike them and wish they'd never been introduced.
- ninjakeyboard 12y agoThis is a weak argument. It's like saying we should avoid concurrency because it's harder to debug. Lambdas are a step forward and nothing short than that. I've been working with Java8 professionally for about 8 months and have trained about 5 teams on the new tooling. I've never seen anyone raise debugging their code as a reason to use an anonymous object instead of a lambda.
- iwince 12y agoThey are a step backward. They try to make a complicated thing look simple. That is always a mistake.
- mekaj 12y agoIt's not always a mistake. Abstraction has a purpose. The key is using abstractions that are helpful. Some people find the concision of lambdas helpful, so it's not necessarily a mistake.
- phamilton 12y agoI think that is true in the case of forEach loops. However there are plenty of other situations in which the lack of lambdas has made something simple far more complicated. One example is the Strategy Pattern. With lambdas it's a fairly simple thing. Without lambdas there are a bunch of hoops you have to jump through. Additionally, I feel that lambdas enable constructs that are much clearer and easier to reason about. Consider the case where you want to transform ever element in a list and produce a new list. Without the map function (which depends on lambdas) the logic wouldn't be that bad, you would create an empty list and append each element ad they are processed in a for loop. However, the intent of your code is less clear. Add in filtering and the intention of the code in your for loop ends up quite a bit harder to understand compared to a fairly straightforward select and map.
- kabdib 12y agoThis is a failure of available tools, not a bad language feature. Your tools folks should be all over this. If they're not, switch tools.