11 ms·
Java 8 Lambdas
- Avalaxy 14y agoCongratulations to the Java-programmers for getting a feature that virtually every other OOP language has had for about 10 years.
- deleted 14y ago[deleted]
- alinajaf 14y agoCare to elaborate? Ruby had them from day 1, PHP has only had them since 5.3, not sure what the deal is with python.
- X6MW3aQrZU5VKkz 14y agoC# has had them for a little while now.
- kmontrose 14y agoC# has had a notion of delegates since day one, and anonymous methods (like delegate(string foo) { ... } ) for 7-ish years. C# lambda expression syntax (the =>) are about 4 years old now.
- Estragon 14y agoOT, but all this language comparison got me wondering: has anyone implemented C# on the JVM? :-)
- zbowling 14y agoyes, Mainsoft Grasshopper. But given that the CLR is superset of JVM features, you can't easily convert .NET MSIL to Javabyte code (a few research projects tried but it's not pratical). Grasshopper did it at a language level and wrote a C# to Java bytecode compiler. However going the other direction is really easy and straight forward. IKVM.NET has been running Java on top of .NET for years.
- Xion 14y agoPython has lambdas and functions as first-order values since the beginning.
- krunaldo 14y agoYou can't have statements in pythons gimped versions of anon functions :/
- btilly 14y agoI call BS. def return_closure (value): def closure (): return value return closure foo = return_closure(5) print foo() # prints 5 If you look closely, foo is an anonymous function, and it could have anything you bloody well please inside of it. What you can't do is put statements in an anonymous function that you are declaring inline. But the full syntax I just demonstrated is only marginally longer. UPDATE Modify the end like this to see that the functions really are anonymous. foo = return_closure(1) bar = return_closure(2) baz = return_closure(3) print foo() print bar() print baz() You will see that the three functions returned are completely independent. They are not associated with any name or each other. They are, in fact, anonymous. (Admittedly at the moment they are called foo, bar and baz. But you could have put them into an array, and they really would have no unique name.)
- julian37 14y agoIf you look closely, foo is an anonymous function No, "foo" is a variable holding a reference to a named function--the function named "closure". You seem to be confused as to what an anonymous function is. (It doesn't per se have anything to do with closures.) GP is right, Python's lambdas are crippled, unfortunately. And I'm saying that as someone who loves Python.
- btilly 14y agoAt that point it is not a named function. The name was only associated with the function in a scope that is now exited. Call the outer function 3 times. You'll wind up with 3 functions. They will be independent, even though you think they are all named the same thing. There is literally nothing you could want to do with anonymous functions that you cannot do with this technique. (Of course if you want to update an enclosed variable, you have to store it in a mutable data structure. But that is true for any Python function that wants to mutate data in its surrounding environment.)
- yati 14y agoC++, too has fine support for functional programming(since C++11)
- Peaker 14y agoDidn't Ruby have dynamic scoping in day 1? Dynamically scoped lambdas are different lambdas, and much less useful.
- alinajaf 14y agoIf I'm understanding you correctly, I believe it has both. Blocks act as closures and lambdas are dynamically scoped, though you can convert between the two and change the scoping in either case.
- brown9-2 14y agoAnd? Everyone agrees it would have been nice to have this a long time ago. It's still nice to get these features added now rather than never.
- qznc 14y agoThe feature has been in Java for a long time. This is just nice syntax for anonymous inner classes.
- spullara 14y agoThough the current implementation does use anonymous inner classes under the covers the intent was to specify them such that other implementations that are more efficient could be used. The likely final implementation will be simple methods invoked with invokedynamic that don't need a separate class and instance per call site.
- Peaker 14y agoThe feature has not been in Java for a long time, because the feature is the nice syntax.
- batista 14y agoYes, and C doesn't have most things other languages have. That doesn't mean I will use Ruby for my next real time embedded project.
- skippy81 14y agoAnd what difference has the lack of lambda's really made? I cant stand these "my language is better than your language" debates. Use whatever one makes sense for the job (or, in the case of the enterprise, you can hire enough of).
- bickfordb 14y agoThe difference is readability and developer efficiency. the non-lambda version in the example is four times the size of the lambda version. I don't know about you, but I can only fit about thirty lines of source code in my brain at once. Virtually every other modern programming language has a lambda, it's good to see Java catch up. This isn't about Java versus any particular language.
- majormajor 14y agoWhen it comes to how much code you can keep in your head, do you really keep the boilerplate there? Whenever I've used Java and had to attach an ActionListener or whatever, I don't think of it as being an anonymous class with a single method, I think of it as just the logic in the method when I'm reasoning about the program. It is a pain to write if you don't like having to let the IDE do everything for you, though.
- alinajaf 14y agoDo you mean to say that one language can't be objectively better than another?
- zbowling 14y agoI don't know how I feel about interface defaults. Why is that more important than say declared properties or unsigned types?
- spullara 14y agoThey are hugely important for introducing new behavior on existing interfaces without breaking compability. They are at the core of what is going to allow you to use all the new functional-style collection methods on your old collections without changing your implementation code at all. Declared properties and unsigned types are relatively small changes. BTW, in JDK8 they have provided limited support for unsigned types, just not at the language level: https://blogs.oracle.com/darcy/entry/unsigned_api https://blogs.oracle.com/darcy/entry/unsigned_api
- gouranga 14y agoAgreed and it's an order of magnitude better than extension methods which .Net uses for the same functionality!
- kmontrose 14y agoC# extension methods are used for considerably more than adding new methods to existing interfaces, though that is a valid use of them. They also don't require you have access to the source (anybody can write an extension method on System.Collections.IEnumerable, not just the BCL team). That they work on any type (not just interfaces) also makes them considerably more general than default implementations. I also find the idea of an interface carrying implementation a little weird, the abstract class/interface line gets a lot blurrier. That said, lambda support that only worked on new code would be pretty lackluster; so it's good some thought has gone into getting them into legacy code.
- gouranga 14y agoThe problem I have with extension methods is semantics and determinism, particularly in the collections framework (if you can call it that - it's a mess). Great example: Look at System.Core's Count() inside reflector. Using pseudo code: def count(ref): if ref is ICollection: return (ref As ICollection).Count else n = 0 for each item in ref: n++ return n That hurts badly if you are not careful. Enumerables will be iterated and collections will return length so when you call it you don't know for certain if it's O(N) or O(1). If someone has downcast ICollection<T> to IEnumerable<T> then you really don't know where you stand. It's shit like that which is hard to debug and brings your system to its knees.
- asmala 14y agoI'm curious to see what the implications are for other JVM languages given the promise of more efficient byte code.
- spullara 14y agoThat is already released in JDK7: the invokedyanmic bytecode -- JRuby is probably on the forefront of taking advantage of it.
- ohhmaagawd 14y agoWould have been a big deal - if they introduced 10 years ago
- flatline3 14y agoJava is still widely used. I'm looking forward to this -- there are some projects we can't take to Scala due to client concerns around a less mainstream language.
- diego_moita 14y ago> Java is still widely used. I'm looking forward to this -- there are some projects we can't take to Scala due to client concerns around a less mainstream language. I hope I am wrong but I smell a trap here. Some time ago I implemented a solution (for .Net, that is) that employed some more modern techniques ( reflection, recursive lambdas, etc). Unfortunately many of the programmers in charge of maintaining my code were either interns from a local technical school or an outsourced company in India. They couldn't get their heads around the techniques I used. They thrashed my code, I ended with a bad reputation and lost the client. Not something I regret, anyway.
- yread 14y agoPerhaps they didn't approve of your use of reflection? Your post sounds a bit like you would use it because you can create awesome looking code. It should be used rather seldom http://stackoverflow.com/questions/429962/when-do-you-use-reflection-patterns-anti-patterns http://stackoverflow.com/questions/429962/when-do-you-use-re...
- jmcqk6 14y agoAre you kidding? Reflection is one of the most powerful parts of the .NET framework. Hell, the page you link to contains many examples of the different possibilities, but they're just a start. The only knock I know of against reflection is that it's a performance hit. If that's really the issue, write the code using reflection (it's going to be better code, most likely), and then see if performance is an issue. If it is, refactor out the reflection. Reflection makes things possible that simply aren't possible without it. It can get rid of layers upon layers of complexity. It can shrink thousands of lines of code to fractions of that. There is no reason to say that 'it should be used seldom.' It's a powerful tool and should be wielded along with every other tool in the toolbox.
- barrkel 14y ago'sorted()' doesn't really act like that, does it - taking in a comparator function? It's much better to have comparator functions for the most common types baked in, and use projection to select a list of fields to use to compare with. Comparator functions are very easy to get wrong. The example given here - ".sorted((a, b) -> a.getValue() - b.getValue())" - won't work properly when the calculation wraps around.
- masklinn 14y ago> It's much better to have comparator functions for the most common types baked in, and use projection to select a list of fields to use to compare with. Except that requires a sorting key for the result. Trivial for dynamically typed languages, but how do you handle the type of that key in a statically typed language? Mandate that the key be a string? Build a limited set of overloads against a dedicated type? And even then, how do you specify the relative constraints of the different values within that key, especially within the limitations of java's type system? > The example given here - ".sorted((a, b) -> a.getValue() - b.getValue())" - won't work properly when the calculation wraps around. But that's less an issue of "comparator functions [being] very easy to get wrong" and more an issue of "integer is an asinine type to use as ordering result". Even more so in a statically typed language. Haskell uses a dedicated enumerated type[0] which does not have this issue. [0] http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Ord.html#t:Ordering http://hackage.haskell.org/packages/archive/base/latest/doc/...
- barrkel 14y agoI don't know what you mean by "sorting key" in this context. The idiom I have in mind is how .Net implements "SortBy", "ThenBy" and friends. Overloads can be used for a comparator function based approach, but it should not be the first choice. And I'll stand by comparators being easy to get wrong, particularly when values may be null, polymorphic, etc.
- batista 14y ago>I don't know what you mean by "sorting key" in this context. He means the item by which you sort. The "by" in your "SortBy" example.
- CookWithMe 14y agoFinally... and they even infer the type! Positively surprised. I will stick to Scala, though.
- joegaudet 14y agoThey can't _really_ infer the type. You just have to have one less set of pizzas. It doesn't work like scala's type inference.
- rabbitfang 14y agoyeah. Nice addition, should make Guava etc. much nicer to use, but I'm also sticking to Scala.
- bsb 14y agoLooks like they took a page from the Groovy language
- lipponlabang 14y agoWhy Groovy over anything other language with a lambda abstraction syntax?
- mbel 14y agoThe idea of 'default methods' looks quite disturbing. It seems to allow implementation of some methods inside interfaces. Which is against the basic idea of interface, isn't it? Correct me if I'm wrong, but multiple inheritance problems form C++ are now going to be a brand new feature in Java.
- mccoyst 14y agoThere's no difference between implementing method dispatch with multiple inheritance versus multiple interfaces. What do you think C++'s multiple inheritance problems are? As long as Oracle doesn't add data members to interfaces, Java won't get any new problems.
- mbel 14y agoI might be missing something, but what I see as a problem is a situation where: class C implements interfaces IA and IB, which both contain method doSomething() with default implementations, class C doesn't overrides this method, so which implementation is going to be called when method doSomething() will be invoked on instance of C? Will it behave the same way if it is called as instance of C and as instance of IA or IB? Clearly, there are rules in C++ to handle such situations, one may argue that they are problematic.
- spullara 14y agoIf there is no way to break the ambiguity the compilation will fail and you will have to override that method (in 8.4.8.4 of the spec). You can use IA.super or IB.super to call one of the default methods if one of them works for you and you don't need your own bespoke implementation.
- mbel 14y agoThanks for clarifying; although I don't really like this feature, compilation failure seems to be the best solution (and well I guess I should have RTFM to begin with, sorry).
- 14y ago
- anarchotroll 14y agoIt kinda sucks that you still have to declare an interface in order to pass functions around.
- goggles99 14y agoNice - only 5 years late though.
- Sandman 14y agoI was recently at a Java conference where Juergen Hoeller (of Spring fame) was a keynote speaker. In one of his talks he said something like "Once again, Java is solving yesterday's problems". The moment he said that, I thought to myself "Yes! So true!". The day before, Angelika Langer gave a talk on Lambdas in Java 8. I watched as the other developers listened with half-opened mouths (and some of them, with confused expressions on their faces) and wondered why, instead of bolting features other languages have had for decades onto Java (potentially leading to another fiasco like generics), Oracle doesn't instead continue to work on the JVM to give an even better support for languages that already do have these concepts (by, for example, providing support for TCO).
- Mavrik 14y agoBecause in environments where Java is used "switch language your're using" just isn't such a viable option. Especially in the light of an option of just upgrading the language. There's nothing seriously wrong with Java that couldn't be fixed by incremental language updates - like the ones C# has received in last couple of versions.
- gurkendoktor 14y ago> Because in environments where Java is used "switch language your're using" just isn't such a viable option. I hope this excludes the education sector. Nobody should ever learn lambdas as being "implementations of a compiler-guessed interface with one non-defaulted method".
- sreque 14y agoI don't understand or agree with your logic at all. Oracle shouldn't waste time on Java because it is already so far behind as to be hopeless? That notion seems silly at best, especially as 99% of code written on the JVM is still done in Java. Also, generics fiasco? Generics may not be perfect, but I haven't met a single person who isn't glad that they are in the language. Who has done generics better? C#? Because C#'s type system is baked so heavily into the run time, the CLR actually has a harder time supporting languages with more powerful type systems than does the JVM. See, for instance, this post: http://olabini.com/blog/2010/07/questioning-the-reality-of-generics/ http://olabini.com/blog/2010/07/questioning-the-reality-of-g.... Both Ola, a JRuby developer, and Martin Oderskey, the creatir of Scala, prefer the JVM's type erasure to the reified generics of the CLR.
- chubbard 14y agoI do not understand how this really any different that what we already have with anonymous classes/interfaces. If we have to continue to define interfaces for our lambdas then we might as well continue to use anonymous classes and remove the final restriction (that's completely backward compatible). The final restriction wasn't required in the original design of anonymous classes before the community freaked out over memory allocation of primitives. The reason closures are a pain in Java is having to meet the static typing declarations using interfaces for our anonymous classes. The whole point to this was to create a compact syntax for declaring methods that take lamdas as parameters without resorting to interfaces. I also wish that default mechanism could be extended to existing classes as well so we could add methods to classes because the real question is what are the API changes to collection, File, etc with respect to the addition of lambdas. The places where Java has fallen short in the past is the API (Collection.join? Collection.map, Collection.reduce, new File( String... paths), etc).
- shasty 14y agoHopefully no one with any sense will use these features.
- deleted 14y ago[deleted]
- drostie 14y agoWill you be able to return lambdas or just create them as function inputs? (I guess you can write a method which takes an object of interface X and returns it, but do you have to do this for every interface you want to use, or would there be a universal reify() method? Is there a universal interface which would allow these to be proper first-level functions?) If there are competing lambda interfaces, does the system fail at compile-time?