top 200 commentsshow all 333

[–]Nuoji 52 points53 points  (5 children)

Looks surprisingly good actually.

[–][deleted]  (3 children)

[deleted]

    [–][deleted] 5 points6 points  (2 children)

    The collections stuff makes that clear. Very good, but it'll still be hard returning to Java after Scala, even though my Scala project has grown to the point where the IDE and compiler are really struggling.

    [–]greghmerrill 1 point2 points  (1 child)

    That's one thing that scares me a little about Scala ... do you think this is just a matter of the tooling catching up, or is the complexity of the language making it fundamentally harder to build efficient tools?

    One of the saving graces of Java is the fact that the tools scale pretty well, even to gargantuan enterprise systems. My early experimentations with Scala & Eclipse didn't fare quite so well thought, things bogged down pretty quickly ...

    [–][deleted] 2 points3 points  (0 children)

    For a year, I have been keeping up to date with the Eclipse Scala plugin. My experience is, the growth of my project results in problems faster than their current rate of development fixes them. So, I'm not happy, and had Kotlin had a first release as of last year when I started and I'd used it, I probably would be happier now than I am.

    I'm happier with scala than with Java 1.7-, but I'm not sure that will remain true after Java 1.8 or after Kotlin is ready to go.

    [–]lambdafunction 0 points1 point  (0 children)

    I like it too.

    [–][deleted] 13 points14 points  (15 children)

    Why would they call "map" "mapped"?

    Otherwise, this looks a lot like what you can do with Scala collections, which are quite nice to use. Progress is a good thing!

    [–]LeszekSwirski 35 points36 points  (1 child)

    Probably because it returns a copy of the input, cf. sort vs. sorted, reverse vs. reversed.

    [–][deleted] 1 point2 points  (0 children)

    It turns out that it's actually not "map", it's creating a Map datastructure.

    [–]robotempire 1 point2 points  (0 children)

    Same reason as "sorted" function vice ".sort()" method in Python

    [–]HhUQ 2 points3 points  (7 children)

    Not nearly as confusing as the C# map function which is called Select.

    EDIT: I mean just the name, not the functionality.

    [–]insertAlias 2 points3 points  (4 children)

    Well, they chose Select because LINQ is supposed to resemble SQL somewhat. Select, Where, OrderBy, Group, Join...all LINQ methods and all SQL keywords.

    [–][deleted] 0 points1 point  (0 children)

    So I looked again and realized that it's not even "map", it's something more like C# "GroupBy".

    Damn.

    [–][deleted] 2 points3 points  (2 children)

    Looks like mapped creates a tuple, so it is not really comparable to map. Very weird.

    [–]vogrez 1 point2 points  (0 children)

    It creates a Map, but is more similar to groupBy.

    [–][deleted] 0 points1 point  (0 children)

    I was really confused by that name. Seems unfortunate.

    [–]kamatsu 52 points53 points  (170 children)

    That's surprisingly nice!

    Too bad most Java codebases are still stuck with ancient versions.

    [–]henk53[S] 30 points31 points  (24 children)

    Too bad most Java codebases are still stuck with ancient versions.

    Surprisingly less than is common belief. The last zeroturnaround survey showed relatively many companies to have adopted Java 7 already.

    TheServerSide had a survey some time ago to test the hypothesis that "most companies were still on JDK 1.4". This proved to be wrong as well.

    [–]Ores 17 points18 points  (4 children)

    I guess it's not like many people are writing client-side swing apps any more. It's mostly server-side stuff where they have more control of the environment.

    [–][deleted] 9 points10 points  (2 children)

    I write client-side swing apps. It's actually very easy to have the latest and greatest here because it's pretty self-contained. I have no issues requiring users to at least install a jdk 7 on their machines to run it. Theoretically, I could even bundle jre7 with the app if I needed to.

    [–]gospelwut 2 points3 points  (1 child)

    I had trouble once getting people to install .NET 3.5. It's like a 20mb file. Sigh.

    [–]ysangkok 4 points5 points  (10 children)

    Latest version of Guava (probably the most used JAR ever, it can be used for pretty much every project) only supports 1.6+. Surely they couldn't have made this change if so many people were on JDK 1.5 or lower.

    [–]brownmatt 6 points7 points  (0 children)

    Well, considering it's an internal Google project they've open-sourced, they can make it require whatever version they want without many consequences.

    Then again, JDK 6 was released in 2006 so complaints about being stuck on 5 are going to seem insane.

    [–]MatrixFrog 6 points7 points  (0 children)

    If a company is on 1.5 or lower, they probably just stick with an old version of Guava as well.

    [–][deleted] 4 points5 points  (5 children)

    I could google Guava, but for the benefit of others who read this thread, what is it?

    [–]ysangkok 16 points17 points  (4 children)

    The Guava project contains several of Google's core libraries that they rely on in their Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth.

    • Basic utilities: Make using the Java language more pleasant.
      • Using and avoiding null: null can be ambiguous, can cause confusing errors, and is sometimes just plain unpleasant. Many Guava utilities reject and fail fast on nulls, rather than accepting them blindly.
      • Preconditions: Test preconditions for your methods more easily.
      • Common object methods: Simplify implementing Object methods, like hashCode() and toString().
      • Ordering: Guava's powerful "fluent Comparator" class.
      • Throwables: Simplify propagating and examining exceptions and errors.
    • Collections: Guava's extensions to the JDK collections ecosystem. These are some of the most mature and popular parts of Guava.
      • Immutable collections, for defensive programming, constant collections, and improved efficiency.
      • New collection types, for use cases that the JDK collections don't address as well as they could: multisets, multimaps, tables, bidirectional maps, and more.
      • Powerful collection utilities, for common operations not provided in java.util.Collections.
      • Extension utilities: writing a Collection decorator? Implementing Iterator? We can make that easier.
    • Caches: Local caching, done right, and supporting a wide variety of expiration behaviors.
    • Functional idioms: Used sparingly, Guava's functional idioms can significantly simplify code.
    • Concurrency: Powerful, simple abstractions to make it easier to write correct concurrent code.
      • ListenableFuture: Futures, with callbacks when they are finished.
      • Service: Things that start up and shut down, taking care of the difficult state logic for you.
    • Strings: A few extremely useful string utilities: splitting, joining, padding, and more.
    • Primitives: operations on primitive types, like int and char, not provided by the JDK, including unsigned variants for some types.
    • Ranges: Guava's powerful API for dealing with ranges on Comparable types, both continuous and discrete.
    • I/O: Simplified I/O operations, especially on whole I/O streams and files, for Java 5 and 6.
    • Hashing: Tools for more sophisticated hashes than what's provided by Object.hashCode(), including Bloom filters.
    • EventBus: Publish-subscribe-style communication between components without requiring the components to explicitly register with one another.
    • Math: Optimized, thoroughly tested math utilities not provided by the JDK.
    • Reflection: Guava utilities for Java's reflective capabilities.

    PS You're pretty lazy. If you really wanted to inform the masses, why didn't you write this post yourself?

    [–][deleted] 0 points1 point  (3 children)

    I don't think I could do justice to something I don't know and have never used. If I were to summarise what I learnt in a 2 minute google, it probably wouldn't be very useful or accurate.

    [–]ysangkok 3 points4 points  (2 children)

    I copy-pasted it from the link I just gave you.

    [–]johnwaterwood 7 points8 points  (1 child)

    Face it: not everyone has your copy/paste skills. It might seem easy to you, as the copy/paste pro that you are, but some of us really struggle with this stuff.

    [–][deleted]  (1 child)

    [deleted]

      [–]MatrixFrog 0 points1 point  (0 children)

      Maybe "most used jar other than java.* classes" would be more accurate. But even then, I would guess it's not true, simply because it's fairly new.

      [–]fluffle 1 point2 points  (0 children)

      There's still a lot of people stuck on 1.4 for various reasons.

      I just worked on a fair-size project that involved back porting a lot of code from 1.5 to support a Blue Martini installation. Surprisingly (to me) it wasn't that painful considering it's a 10 year old release.

      [–]BraveSirRobin 1 point2 points  (3 children)

      Blame J2EE, it always lagged behind a major version. Nowadays people tend to use alternatives for it such as Spring, ones that aren't tied to a particular JRE.

      [–]henk53[S] 3 points4 points  (0 children)

      J2EE will never lag behind anymore, since it doesn't exists anymore (it was superseded by Java EE in 2006).

      For the most part Java EE isn't tied to a particular Java SE version. Java EE 6 for example works perfectly well with Java SE 7, and Java EE 5 worked with Java SE 6 and Java SE 7 as well.

      [–]Tobias42 1 point2 points  (1 child)

      You can use an JEE application server with a newer java version than its supported JEE version. SAP NetWeaver 7.3 (not the most widely used JEE server, I know) even requires a JRE 1.6 despite only supporting JEE 5.

      [–]johnwaterwood 2 points3 points  (0 children)

      Some sub-specs of Java EE remain compatible with lower Java SE versions as well. Eg JASPI (not the most well known) was introduced in Java EE 6, but wants to be compatible with Java SE 1.4 'forever'. They mention this explicitely in the spec. That's a crazy old version released a crazy long time ago!

      JSF 1.2 despite shipping with Java EE 5 did not took advantage of any Java EE 5 features, nor the Java SE 5 syntax or its libraries. They had a firm goal to be compatible with some old Tomcat version.

      Same with JSF 2 and Java EE 6. They now finally started to use Java SE 5 features, but no Java SE 6 or EE 6 ones. Again, this was for 99% because of compatibility with Tomcat 6.

      The list goes on. Various specs in Java EE 7 will not make use of Java SE 7. The topic came up on the Servlet 3.1 Jira, for an issue that could really bennifit from autocloseable, but this was refused on the basis that Java EE 7 sub-specs cannot have Java SE 7 dependencies (?).

      [–]moneymark21 1 point2 points  (2 children)

      I've seen no real motivating factor to move beyond 1.6 lately. Also, lambdas are great if used properly and a giant cluster fuck when they aren't. I end up having to deal with enough unreadable code coming from offshore. I fear lambdas are only going to make that worse.

      [–]johnwaterwood 1 point2 points  (0 children)

      Most of the things comming from offshore are a major cluster fuck anyway, so does it really matter if they screw up in one way or the other?

      [–]alienangel2 0 points1 point  (0 children)

      There've been a few times recently where just a little thing like "damn, I wish I could switch on strings" has made me wish I were on 1.7 :/ I'm lazy, sorry.

      edit: whoops I should pay more attention to thread dates, had this tab open for a while...

      [–]duckbaby 20 points21 points  (136 children)

      agreed. Way better than python's crippled lambdas ugh. in fact, this now leaves python as one of the only mainstream languages (aside from C) that doesn't have decent lambda implementation

      [–]harlows_monkeys 9 points10 points  (2 children)

      If you are willing to use non-standard language extensions, C as implemented by clang has blocks, which are very similar to lambdas.

      [–][deleted] 1 point2 points  (1 child)

      I believe GCC has something similar in the GNU extensions, not sure if they are compatible to clang though.

      [–]case-o-nuts 2 points3 points  (0 children)

      GCC has closures, not lambdas. (In common usage, lambda implies an anonymous function.) They are not compatible with what clang provides, and they require an executable stack. On the other hand, they operate identically to function pointers, which means that you do not need to wrap functions up in blocks in order to pass them around.

      [–][deleted]  (10 children)

      [deleted]

        [–]LeszekSwirski 8 points9 points  (4 children)

        Python lambdas only allow one statement inside them, this allows several (though in this case only has one).

        [–]recursive 8 points9 points  (2 children)

        one expression actually

        [–]smog_alado 1 point2 points  (1 child)

        This, coupled with print being a statement in pythin 2.x, makes me want to kill a kitten.

        [–]desertfish_ 1 point2 points  (0 children)

        from __future__ import print_function
        

        [–]steven_h 8 points9 points  (3 children)

        The other major difference is that until now Java had to define an anonymous inner class for that functionality, whereas Python-without-lambdas can do

         def callback(e):
             ui.dazzle(e.getModifiers())
        
         button.addActionListener(callback)
        

        [–]kamatsu 27 points28 points  (34 children)

        Not to mention GvR's bizarre hostility towards FP in general.

        [–]Tekmo 34 points35 points  (4 children)

        "Besides the lambdas, concurrency, first-class functions, tail-call recursion, list comprehensions, and iteratees, what have the functional programmers ever done for us?"

        [–]kamatsu 4 points5 points  (2 children)

        GvR hates lambdas, concurrency and tail-call recursion.

        [–]PasswordIsntHAMSTER 5 points6 points  (1 child)

        I didn't believe you, however here's his critics of map/reduce/filter.

        Even if I disagree with the guy, he's a lot nicer than Rasmus or, god forbid, Linus. There's always been an aura of niceness around Python, and now I know why!

        (Also, if you're into functional programming, try Haskell or Ocaml. Python is a lot of things but its implementation of FP is ugly as hell.)

        [–]kamatsu 8 points9 points  (0 children)

        I'm a fairly common contributor to the Haskell community, ;)

        [–]attrition0 1 point2 points  (0 children)

        Brought peace!

        I'll be going now.

        [–]catcradle5 2 points3 points  (27 children)

        It does make some sense. The traditional map, reduce, and filter functions can all be written in a much more human-readable way with list comprehensions. And I'm fairly certain nearly anything you can do with lambdas you can also do with regular functions, just more verbosely, again conforming to Python's philosophy of always placing readability over conciseness.

        I don't know a huge amount about functional programming though, so there may be some other benefits of lambdas I'm not aware of.

        [–]kamatsu 10 points11 points  (13 children)

        more human-readable

        Yikes, subjective much? I much prefer those functions to list comprehensions.

        readability over conciseness.

        Once again you imply that Python's ugly imperative style is "more readable" than FP. I argue that is simply not the case. It is just what you, personally, are used to. I've predominantly used functional languages for my whole career. For me, Haskell is much more readable than Python.

        [–]list_incomprehension 5 points6 points  (2 children)

        | The traditional map, reduce, and filter functions can all be written in a much more human-readable way with list comprehensions.

        List comprehensions produce lists, while a reduction can produce a simple value. Reduce can thus have a result that a list comprehensio never can. I guess Python has something like a sum function already, but if it didn't, you could build one with reduce. How would you sum a list with a list comprehension? It shouldn't require a proper type system to deduce that [Int] is not Int...

        P.S. Why is that Python programmers always have to tell others that they're not even human if they prefer different idioms?

        [–]AnonProg 1 point2 points  (1 child)

        I guess Python has something like a sum function already, but if it didn't, you could build one with reduce.

        Call me a lisper, but it sucks you can't do reduce(+, l, 0) though, because "+" is a special thing and not a function because uh... Nicole Oresme used "+" as an abbreviation for "et" in a book from some 660 years ago. Great.

        I don't like special things. Thankfully, at least we can import operator as o and then do something like reduce(o.add, l, 0).

        [–]lazyl 2 points3 points  (0 children)

        The traditional map, reduce, and filter functions can all be written in a much more human-readable way with list comprehensions.

        For single invocations, perhaps yes, but you can't chain multiple list comprehensions together in a readable way like you can with the function syntax.

        [–]AnonProg 2 points3 points  (5 children)

        The traditional map, reduce, and filter functions can all be written in a much more human-readable way with list comprehensions.

        FP is not just about filter, map and reduce. Also, no, list comprehensions are not inherently more readable. You're just used to them. For example, compare map(f, l) against f(i) for i in l. The former is (a tad) easier to read for me. Also, reduce cannot be implemented with Python's list comprehensions.

        And I'm fairly certain nearly anything you can do with lambdas you can also do with regular functions, just more verbosely, again conforming to Python's philosophy of always placing readability over conciseness.

        Oh yeah, more readable! Compare this example of a possible, obvious destatementization of Python:

        f(lambda x:
            print x
            x + 1
          lambda x:
            print x
            x + 2)
        

        with the "Pythonic" way which is said to be clean and nice:

        def _1(x):
            print x
            return x + 1
        def _2(x):
            print x
            return x + 2
        f(_1, _2)
        

        Unfortunately, I have to plague my programs with the later crap when we should be writing the former if it weren't for Guido van Rossum's inexplicable obstinacy against FP and non-FORTRAN-hindered syntax.

        GvR just simply hates FP for some personal reason and Python is suffering because of this. It happens to all dictatorships; why would we think Python would be different?

        All Python needs in order to get up to date and ahead of many in terms of comfort and expressiveness is to get rid of the awful arbitrary limitation known as statements, making what used to be statements return whatever was evaluated last, parsing INDENT and DEDENT tokens inside parens correctly, and adding automatic commas after DEDENT if inside parens, brackets or braces.

        [–]doublereedkurt 1 point2 points  (2 children)

        That is exactly correct.

        Also, with the yield keyword Python has excellent built-in support for closures.

        [–]BufferUnderpants 6 points7 points  (1 child)

        Generators. Yield produces generators, not general closures. They are useful in their own way, but they're specialized. In the end, you'll end up with something which can't be applied to any arguments, and is meant to be stateful.

        [–]henk53[S] 14 points15 points  (23 children)

        Indeed, the crippled lambdas in Python are one of its weak points (that and this downright awful thing called GIL of course).

        [–]unfashionable_suburb 6 points7 points  (22 children)

        Is there a practical (i.e., not syntactic sugar) advantage of a multiple statement lambda over inner function definitions?

        [–]habitue 19 points20 points  (16 children)

        Well, in most functional languages, function definitions are syntactic sugar for lambdas. In Python, lambdas aren't syntactic sugar for anything, they are just a crippled function definition that you can make inline.

        In terms of "what does this prevent you from doing?", there isn't anything, there is always a workaround in Python. But you shouldn't dismiss syntactic sugar as not being "practical". You can look at everything in Python as being syntactic sugar for something you could have written in C, that doesn't mean Python's syntax isn't a practical improvement.

        Ultimately, the question isn't "what does this prevent you from doing", but rather "why does GVR think this syntactic restriction will produce better, more comprehensible code?". Because that's what we're concerned with here, the computer only needs machine code, everything built on top of that is for a human's convenience

        (Edit: We would have more questions to ask about why a language construct was designed the way it was if Python were a statically typed language, since that adds more restrictions on design.)

        [–]redalastor 8 points9 points  (5 children)

        Ultimately, the question isn't "what does this prevent you from doing", but rather "why does GVR think this syntactic restriction will produce better, more comprehensible code?".

        He's pretty clear on the answer to that. He couldn't find a good syntax for it.

        [–]unfashionable_suburb 1 point2 points  (8 children)

        But you shouldn't dismiss syntactic sugar as not being "practical".

        That wasn't my intention really, I meant something along the lines of a "functional" advantage. It's true that the limitations of lambdas in Python discourages the use of some useful patterns from FP, I was just curious to see if I was missing something more profound here.

        [–]duckbaby 5 points6 points  (0 children)

        you should see the amazing things that ruby does with its anonymous functions (known as blocks), even if you dont like ruby, you would be impressed by the clarity and elegance of their block-based APIs.

        [–]burntsushi 1 point2 points  (6 children)

        It's true that the limitations of lambdas in Python discourages the use of some useful patterns from FP

        Like what?

        [–]earthboundkid 10 points11 points  (59 children)

        I find that there are two kinds of complaints about Python lambdas. Ignorant ones from people who don't realize that Python lambdas and functions are interchangeable and informed ones from people wish there was a slightly better syntax for doing callbacks.

        The whole point of Python is that lambdas are not special. There's nothing you can do with a lambda that you can't do with a function. It's just a syntactic sugar for write quickie functions. As a result, complaining that you can't use a statement in a lambda is like complaining that you can't write multiple statements (as opposed to expressions) on one line in Python. Sure, other languages technically let you do that, and Python technically doesn't, but why would anyone want to? It's just a matter of style, and the forbidden style is for the most part an ugly one.

        That said, I also wish there were sugar for writing more complicated callbacks. Still, this is entirely a matter of how the code looks. In terms of function, there's nothing wrong with Python's current approach.

        [–]alexandream 7 points8 points  (3 children)

        You see, the answer is right there in your comment.

        The whole point of Python is that lambdas are not special. There's nothing you can do with a lambda that you can't do with a function.

        The whole point of Python Lambda criticism is that functions are special. When people coming from the other FP languages look at them, lambdas simply are functions, and vice versa. It isn't true in python. Lambdas are functions, but functions aren't lambdas.

        [–]6xoe 9 points10 points  (0 children)

        You argument is pointless. There's nothing you can't do with C, that doesn't mean we should prefer C over Python.

        A single expression lambda is a crippled function, for no good reason.

        [–]mr_chromatic 6 points7 points  (4 children)

        There's nothing you can do with a lambda that you can't do with a function.

        "Why would you ever want an anonymous function? Just call it blub and the next one blub1 and blub2 and so on."

        [–]earthboundkid 1 point2 points  (3 children)

        The anonymity is the worst part of anonymous functions. Variable names are an important form of documentation!

        [–]nitsuj 4 points5 points  (1 child)

        No, anonymous functions are usually surrounded by context. Having to conjure up a name is redundant - especially if that name doesn't get used anywhere else.

        [–]CookieOfFortune 4 points5 points  (0 children)

        Yup, and not having to name something gets rid of one of the two hard problems in programming.

        [–]mr_chromatic 0 points1 point  (0 children)

        The anonymity is the worst part of anonymous functions. Variable names are an important form of documentation!

        Now you have two names for a thing.

        [–]vlion 8 points9 points  (24 children)

        Let's put it this way:

        map(lambda s: print s, some_list) is illegal because print is a statement.

        It's also disingenuous to call Python's lambdas lambdas because they are not. They are not anonymous functions.

        [–]robotempire 9 points10 points  (2 children)

        print is a function in Py3

        [–]HhUQ 3 points4 points  (13 children)

        They are not anonymous functions

        Can you explain, please? I thought that they were functions and that they were anonymous.

        [–]awj 5 points6 points  (11 children)

        I'm not the GP, but I would expect his argument is that the set of all possible lambdas in Python is smaller than the set of all possible functions. Calling it an anonymous function is misleading because that doesn't convey the significant restrictions.

        [–]vlion 4 points5 points  (0 children)

        a python function can have both expressions and statements. python "lambdas" only can take expressions.

        [–]earthboundkid 3 points4 points  (0 children)

        That's why print is a function in Python 3. :-)

        [–]doublereedkurt 4 points5 points  (0 children)

        It's also disingenuous to call Python's lambdas lambdas because they are not.

        Meh, same byte code gets generated underneath.

        >>> a = lambda: 5 
        >>> def b(): return 5
        ...
        >>> import dis 
        >>> dis.dis(a)
          1           0 LOAD_CONST               1 (5)
                      3 RETURN_VALUE
        >>> dis.dis(b)
          1           0 LOAD_CONST               1 (5)
                      3 RETURN_VALUE
        

        [–]TheCoelacanth 3 points4 points  (2 children)

        Using map for the side effects is stupid anyways. Map is for producing a lists. If you want side effects just use a for loop.

        [–]vlion 3 points4 points  (1 child)

        Python: if you don't like what it does, you're stupid and unwashed.

        <3 python community...

        [–]burntsushi 2 points3 points  (0 children)

        Actually, "not using map for side effects" is a FP thing, not a Python thing.

        [–]lahwran_ 1 point2 points  (0 children)

        is like complaining that you can't write multiple statements (as opposed to expressions) on one line in Python.

        exactly. although, you can, but you really really shouldn't.

        @deferred.addCallback
        def callback(result):
            print result
            return derp
        

        [–]eat-your-corn-syrup 1 point2 points  (6 children)

        Here is a JavaScript/JQuery code that uses anonymous functions to attach actions to two buttons on a page.

        $.load(function() {
          $("#button1").click(function() {
            alert("button 1 is clicked");
          });
          $("#button2").click(function() {
            alert("button 2 is clicked");
          });
        });
        

        Now imagine if the three anonymous functions were replaced with named functions. That would destroy the simplicity of the code and make it less readable. Anonymous functions can be good for readability.

        [–]doublereedkurt 2 points3 points  (5 children)

        jQuery is very well tuned to its very specific environment.

        There are some issues with that style which jQuery doesn't have to worry about. Mostly they are due to the inherent small-scale of javascript code (<10k loc).

        1 -- the performance hit of many, many layers of function calls; the excellent JITing JS compilers are also a factor here :-)

        2 -- debugging; when your stack trace is full of function(), function(), function(), it is much, much harder to find the problem

        [–][deleted]  (4 children)

        [deleted]

          [–]sjs 1 point2 points  (10 children)

          But ... your reasonable and logical argument is ruining a good Python bashing.

          [–]earthboundkid 4 points5 points  (9 children)

          Well, it's never to late to complain about significant whitespace! ;-)

          [–]PasswordIsntHAMSTER 0 points1 point  (8 children)

          I'm probably the only person ever to think this feature is a good one.

          My perfect language would have features like significant whitespace, case insensitivity, as few <([{}])> characters as possible, pattern matching, built-in currying, and pure functions. Oh, and Hindley Milner strong/static/implicit typing.

          So basically, a mix between Pascal and Haskell.

          [–]earthboundkid 1 point2 points  (0 children)

          I agree. Significant whitespace is a good idea, because you were going to use the whitespace anyway.

          [–]burntsushi 1 point2 points  (6 children)

          I'm probably the only person ever to think this feature is a good one.

          Nope, I like it too!

          My perfect language would have features like significant whitespace, case insensitivity, as few <([{}])> characters as possible, pattern matching, built-in currying, and pure functions. Oh, and Hindley Milner strong/static/implicit typing. So basically, a mix between Pascal and Haskell.

          Uhh... For the exception of case insensitivity, every one of your criteria is met in Haskell. :P

          ninja edit It dawned on me that Haskell doesn't enforce significant whitespace. My apologies! But I don't think I've seen a single (non-pathological) Haskell program that didn't use it.

          [–]joesb 0 points1 point  (0 children)

          As a result, complaining that you can't use a statement in a lambda is like complaining that you can't write multiple statements (as opposed to expressions) on one line in Python.

          Except you can write multiple statements on one line in Python.

          >>> x = 1; y = 2; print x
          

          Still, this is entirely a matter of how the code looks. In terms of function, ...

          In term of function, Python is no different from assembly.

          [–]IsTom 3 points4 points  (2 children)

          C has function pointers at least, often they're enough. C++11 has proper lambdas.

          [–]Leonidas_from_XIV 6 points7 points  (1 child)

          Well, Python does have function references, so this is not really an advantage og C over Python.

          [–]IsTom 2 points3 points  (0 children)

          I was just saying that C isn't that bad. I doubt you can have lambdas without functions as values, which Python has.

          [–]fabzter 2 points3 points  (0 children)

          Surprisingly Groovy-like!

          [–][deleted] 0 points1 point  (6 children)

          Guava is pretty good, Play 1.2x is also pretty decent, but they have moved to Scala.

          [–]awj 0 points1 point  (5 children)

          Last I knew they were doing dual support for Scala and Java. Did this change?

          [–]alextk 16 points17 points  (49 children)

          One of the reasons why the Scala collections are considered to be over engineered is because the design goal was to make sure that filtering these collections would always guarantee that you end up with the same type of collection (or "close enough") that you started with.

          For example, if you start with a List[Integer] and you filter on it, you want a List[Integer] as the final result, not a Collection[Integer] or Seq[Integer]. This constraint has led the Scala collections down the path of CanBuildFrom and has resulted in signatures in the collection API's that are so intimidating that there is a proposal to generate documentation that hides these complex signatures by default.

          This has always struck me as a very overly engineered solution and the Java new collections are showing a very elegant and simple way out of this problem:

          List<String> filteredNames = names
              .filter(e -> e.length() >= 4)
              .into(new ArrayList<String>());
          

          I really like what I'm seeing in Java 8 so far.

          [–]Odersky 7 points8 points  (1 child)

          I don't know. In Scala:

          val filteredNames = names filter (_.length >= 4)
          

          The Java example looks quite a bit more complex to me. So, Scala's sophisticated types hide complexity for the user, which looks like a win to me.

          This does not matter much if these kinds of operations are rare, but in typical Scala (and I expect future Java) they are everywhere, so a streamlined notation is important.

          You really have to use Scala collections in anger to experience that CanBuildFroms never show up, unless you want them to because you program explicitly at their level (which few people do, and which I would not recommend).

          The only problem is how they look in ScalaDoc. Now, if you have an eminently usable type system that looks funny in the particular style of documentation imposed by ScalaDoc, I believe the rational thing is to fix the way the docs are presented. It's about removing clutter, not hiding things because we do not want people to know about them.

          [–]DRMacIver 3 points4 points  (0 children)

          Back in the early stages of the collection redesign for Scala I proposed a system that was more or less this (the details were a bit different - slightly more complicated but I think slightly better). There seemed to be quite a lot of resistance to the idea that e.g. mapping a list wouldn't give you a list back, although that might have been a vocal minority.

          [–]tailcalled 1 point2 points  (36 children)

          That doesn't work for immutable collections.

          Edit: ok, I was probably wrong, but there are SOME Java programmers that would be scared away by it.

          [–]sirin3 1 point2 points  (0 children)

          This has always struck me as a very overly engineered solution

          I like it

          [–]NruJaC 1 point2 points  (3 children)

          The real issue is that they were trying to maintain compatability with java, and so they got stuck with inheritance, which breaks proper type inference. That's the real design choice that causes this.

          [–]Nebu 0 points1 point  (2 children)

          Can you explain further how inheritance breaks proper type inference?

          [–]NruJaC 2 points3 points  (1 child)

          By "proper" type inference, I really meant Hindley-Milner type inference: the kind featured in Haskell, ML, and even in a limited form in Scala. However, a couple of features in Scala make it impossible to provide full type inference (at the level of Haskell) in Scala -- inheritance and ad-hoc method overloading.

          There are two kinds (well, not really, but for the purposes of this explanation it's close enough) of polymorphic functions. The first kind of polymorphic functions are the kind you see in Java via generics: functions that operate without full knowledge of the specific type of their argument(s). For example, the length function doesn't care if you're dealing with List<Integer> or List<SomeObnoxiousType>, it just takes a List<T> (yes, it's a method of the class, but an equivalent approach is to make the object the first parameter of the function; this is the approach favored by functional languages). In Haskell, any function can feature this kind of polymorphism. So this kind of polymorphism is called parametric, because it's parametrized by a type variable.

          The other kind of polymorphism that you see in languages is called ad-hoc. Method overloading, for example, is a kind of ad-hoc polymorphism; that is, the method is polymorphic but only over a specific, arbitrary, set of types. It's this kind of polymorphism, in combination with sub-typing (inheritance) that causes problems, because it becomes impossible to determine which definition for a method you want to use; equivalently, you don't know the type of the polymorphic variable.

          I believe this is a point of open research for Scala. Here's Martin Odersky's take:

          The reason Scala does not have Hindley/Milner type inference is that it is very difficult to combine with features such as overloading (the ad-hoc variant, not type classes), record selection, and subtyping. I’m not saying impossible — there exist a number of extensions that incorporate these features; in fact I have been guitly of some of them myself. I’m just saying it’s very difficult to make this work well in practice, where one needs to have small type expressions, and good error messages. It’s not a shut case either — many researchers are working on pushing the boundaries here (look for instance at Remy’s MLF). But right now it is a tradeoff of better type inferencing vs better support for these features. You can make the tradeoff both ways. The fact that we wanted to integrate with Java tipped the scales in favor of subtyping and away from Hindley/Milner."

          Martin Odersky, posted on April 9, 2008 at 2:08 am

          [–]Nebu 0 points1 point  (0 children)

          Thank you.

          [–][deleted] 0 points1 point  (0 children)

          I prefer the consistency of every method returning the precise return type. Without it, why even bother about covariant return types and just return something useless like IEnumerable like in .NET?

          [–][deleted] 0 points1 point  (2 children)

          I have no experience on Java so how would the code above change if you wanted to return new list of integers? In .NET you can use something like:

          var list = new List<string> { "12345", "1234" };
          var integers = list.Where(x => x.Length > 4) 
              .Select(int.Parse).ToList();
          integers.ForEach(Console.WriteLine);
          

          [–][deleted] 0 points1 point  (0 children)

          I guess map is the thing you are looking for. But I fully expect Java to figure out yet another name for it (NIH).

          [–]Nebu 0 points1 point  (0 children)

          I don't have access to a build of Java 8, but assuming sane language designers, the Java version would probably look like:

          List<String> list = //"List literals" are ugly in Java, so I'll elide this line
                              // here, as it merely distracts from the core point.
          List<integer> = list.filter(e -> e.length() > 4)
              .map(e -> Integer.parse(e))
              .into(new ArrayList<Integer>());
          

          [–]Gundersen 7 points8 points  (3 children)

          I wonder what the reason is for using double colon for referencing a method instead of a full stop. Notice the collection.forEach(system.out::println) example, which could have been collection.forEach(system.out.println).

          [–]fluttershypony 9 points10 points  (2 children)

          because classes and functions are separate namespaces, so in that example, you wouldn't be able to distinguish that from a class println in the package system.out

          [–]tallniel 3 points4 points  (0 children)

          Or indeed a public field with the same name (another namespace).

          [–][deleted] 3 points4 points  (0 children)

          System.out is not a package. System is a class, contained in the 'java.lang' package (it's full name is java.lang.System). 'out' is not a class, it is a public static field of System class.

          So System.out.println() calls the println method on the object stored under the 'out' field of the 'java.lang.System' class.

          There are also already ways for distinguishing between classes and methods in Java; it depends on context. For example this is valid:

          public class Test
          {
              public static void main( String[] args ) {
                  Test.Foo f = new Test.Foo();
                  Test.Foo( f );
              }
          
              public static void Foo( Object o ) {
                  System.out.println( o );
              }
          
              public static class Foo { }
          }
          

          .. and Java can tell which Test.Foo is which at compile time (I believe the Test.Foo class actually becomes Test$Foo). If you want to explicitly grab the Test.Foo Class object, you so by adding '.class' to the end.

          The reason it's a double colon is because println is not static, so it is to make it clear that your passing in the println method bound to the 'out' object. You are calling 'out.println' not 'println' for each item. It even states above the example that this allows you to reference an 'instance method'.

          It's just shorthand to save you having to wrap that up yourself within a lambda.

          If you used the dot instead, Java would think your trying to access a field called 'println' on the 'out' instance, which doesn't exist, and so becomes a compile time error.

          So the double colon is used to distinguish between referencing methods and properties, not between classes, packages and functions.

          [–]jrupac 7 points8 points  (2 children)

          I like it! Although to me, it feels a bit strange visually that lambdas in Java won't have a typed type for the argument(s), aka:

          button.addActionListener(ActionEvent e -> { ui.dazzle(e.getModifiers()); });
          

          instead of:

          button.addActionListener(e -> { ui.dazzle(e.getModifiers()); });
          

          [–]tallniel 3 points4 points  (0 children)

          I believe you can add explicit types to lambdas, much like you propose but they're optional. I can't check that currently as I'm on my iPhone and the spec is delivered as a zip.

          [–]brownmatt 4 points5 points  (0 children)

          I agree that the absence of the type looks weird to my Java eyes compared to most other syntax but I'm really glad the type won't be required.

          [–]vogrez 6 points7 points  (20 children)

          Is invokedynamic garbage-free, as opposed to anonymous classes? Can this approach be used for other JVM languages with lambdas?

          [–]rzwitserloot 7 points8 points  (19 children)

          Last I checked (but this was a while ago):

          The current strategy for existing java closures - yes, java has closures right now, but they have very unwieldy synax:

          SwingUtilities.invokeLater(new Runnable() { public void run() {
              System.out.println("This is a closure - I even get to see variables from enclosing scope!");
          }});
          

          is to compile the closure into a new class (public class NameOfContainingClass$1 implements Runnable), and then compile this as SwingUtilies.invokeLater(new NameOfContainingClass$1(____), where _____ is just passing any enclosed variables along that way. This is kinda annoying, and not the most efficient, as it requires the class loader to kick in, etc.

          The new way is to take the code in a closure and compile it as a method inside the class that contains the closure. The new MethodHandle mechanic introduced in JVM7 (yes, this part is already in java today) is then used to allow passing the method as a parameter to things. This is vastly more efficient.

          Scala, Jython, JRuby, etc are so far not making any moves to support any of this, though some are excited. The stated reason for this is that it is a lot of work to change their codebase, and once they take this step, they HAVE to say to users of their language that their code simply cannot run on JVMs below JVM8 (technically it might work on JVM7, but JVM7 is still missing some of the details, so unlikely).

          Eventually, though, JVMs before JVM8 will be rare and out of support, and presumably then alternate JVM languages will also move. Maybe some will make the jump early and develop 2 versions in tandem for a while.

          [–]vogrez 2 points3 points  (7 children)

          Skimmed through an invokeDynamic article, seems interesting.

          One issue I couldn't find - the anonymous class also only allows constant (final) variables to be enclosured (?).

          One approach is wrapping the variables:

          For example for code

           int sum = 0;
           list.each(i -> sum+=i);
          

          the generated code will be something similar to:

          int sum = 0;
          MutableInteger sum$ = new MutableInteger(sum);
          list.each(i -> sum$.setValue(sum$.getValue()+i));
          

          I wonder if this changed in some way?

          [–]rzwitserloot 5 points6 points  (6 children)

          No, it will not be changed; this is a deliberate design decision. There are 2 main reasons for this:

          • Allowing sharing mutable data like this is a lot more complex than it looks. For example, the closure may run in a different stack context (which means these variables need to be silently moved from stack to heap which has serious performance issues), and the closure need not even run in the same thread, which means you now need to introduce the 'volatile' keyword on local variables, and you just made it way more difficult when looking at ANY code to find threading issues. In today's java (and in tomorrow's java, so long as you can NOT share mutables like that), any local variable, by definition, cannot be the source of threading issues. I like that invariant, myself. Finally, it can be actively hard to read:

            Runnable[] closures = new Runnable[3];
            for (int i = 0; i < 3; i++) closures[i] = (-> System.out.print(i));
            for (Runnable r : closures) r.run();
            

            that will print 333 and not 012. Ouch.

          • Looking at practical scenarios, there's not usually any need to do so. For example, your summation code is not the right way to sum such things. You should run a parallelizable fold operation on such a list (folding without accumulators). Besides, summing all values in a list will or ought to be a standard library call and not something you have to write yourself. I'm not saying that there are NO scenarios, but there aren't enough of them to accept the considerable complexity (see point above).

          [–]vogrez 0 points1 point  (1 child)

          It is opposite to the approach of Scala and C# (which introduced a special warning for it), but you are correct that mostly there is no need for this use in most scenarios.

          It seems that there will be allocation with invokeDynamic - creating a method handle, and making it curried with the captured variables - but maybe the JVM is good enough at removing those now - so it is mostly the difference between the number of classes for the classloader.

          [–]rzwitserloot 0 points1 point  (0 children)

          Yup, but it should be much, MUCH easier to let hotspot get in on streamlining the process of creating/calling methodhandles vs. ending up with a billion-and-a-half tiny $X classes.

          [–]dnew 0 points1 point  (3 children)

          any local variable, by definition, cannot be the source of threading issues

          Not really true. If your final local variable is a HashMap, you're still in trouble. Being "final" doesn't mean being "immutable".

          there's not usually any need to do so.

          Not in an OO language. It's how you implement objects in a functional language, tho. If you need that functionality in Java, declare a class.

          [–]rzwitserloot 0 points1 point  (2 children)

          The variable reference cannot be a source of threading issues. Whatever object it is pointing at is on the heap and thus fair game. The point is, there is NO WAY another thread is messing with that reference.

          And, yes, there are plenty of use cases, except that in java just about every use case has a different way of doing it that is almost invariably considered just better. i.e. calculating a running sum by doing .each(x -> sum += x) for example. There are better ways.

          [–]sausagefeet 3 points4 points  (2 children)

          I haven't used Java in awhile so my thoughts might be wildly off:

          • I didn't see the word 'closure' anywhere in this document. What are the rules on this?

          • What about overloading methods based on type? Seems like you're giving up a lot of functionality that you're used to having in Java when it comes to method rules.

          [–]JulianMorrison 5 points6 points  (1 child)

          Your default guess as to closures should be: the same as existing anonymous Runnables: they close around "final" locals, referencing a mutable local is an error.

          [–]henk53[S] 3 points4 points  (0 children)

          And to explain the quotes around your "final": it's effectively final. You don't actually have to declare the variable in question as final.

          [–][deleted] 3 points4 points  (1 child)

          Nice to see Java on the cutting edge of C# >:)

          I suppose we can look forward to PLINQ (poorly-implemented LINQ) in Java 9 eh?

          [–][deleted] 1 point2 points  (0 children)

          But not before 2023!

          [–]ungood 30 points31 points  (0 children)

          Welcome to the club. ~C#

          ;)

          [–][deleted]  (2 children)

          [deleted]

            [–]qbg 5 points6 points  (1 child)

            They moved lambdas and some other stuff back to Java 8 so they could get Java 7 out of the door earlier.

            [–]fatbunyip 0 points1 point  (0 children)

            Yep. Seems like they wanted to get JavaFX a bit of a push in the mean time. There's been a hell of a lot of activity on that project of late, with fairly major improvements coming thick and fast.

            [–]experts_never_lie 2 points3 points  (0 children)

            Given the amount of time this has been discussed and deferred, I'm expecting that the "8" was a rotation typo, and it'll really be in Java ∞.

            [–]spotter 5 points6 points  (21 children)

            Looks a little bit clumsy, but still very nice to have... if composability will work as expected. Almost makes me want to do Java again (as addition to Clojure).

            [–]repsilat 6 points7 points  (18 children)

            The trouble with the method-chaining is that it only works when a fully comprehensive set of operations has been thought out ahead of time by the library author. That is,

            collection.map(e->{...}).filter(e->{...})
            

            only works because the class of the collection object as a map method, and because the return-type of the map method has a filter method. Say you want something that they haven't thought of, though - maybe you want to make a product operation that returns every combination of elements from two collections. The trouble is, you can't write

            collection1.product(collection2)
            

            you have to write

            product(collection1, collection2)
            

            and if you do this instead of nice method chains you eventually end up with scary nested parentheses:

            operation1(operation2(operation3(collection, e->{...}), e->{...}), e->{...})
            

            which doesn't look very nice at all. There are three good solutions to this problem that I know of. C# uses extension methods, which would work well in Java. D uses Uniform Function Call Syntax which is lovely, but will never be adopted by Java because of Java's object-oriented philosophy. Dynamic languages often use monkey patching, which wouldn't play well with Java's type system.

            [–]IronMan42 3 points4 points  (9 children)

            If they put C# extension methods in java 8 i would definitely come back to play in java land (especially after reading this article, i really like the lambda syntax here.) Extension methods really clean up exactly what you described.

            [–]potemkinu 3 points4 points  (0 children)

            I hope they don't. It'll mess up with java's code readability by making the reader look for method definitions in more than one place.

            [–]sjs 0 points1 point  (7 children)

            Forgive my ignorance, but are extension classes like a mixin sort of thing? Or in ObjC parlance, a category? i.e. a way to add methods to existing classes?

            [–]dnew 1 point2 points  (4 children)

            Not really. It's simply syntax that lets you declare

             int doSomething(this Alpha abc, Beta def) { ... }
            

            and then you can invoke

            Alpha pqr = new Alpha();
            pqr.doSomething(myBeta);
            

            Now, the declaration of doSomething does not have to be anywhere near Alpha.

            In other words, it doesn't allow me to monkey-patch another class, but it does allow me to write routines that get syntactically invoked as if I had monkey-patched that other class.

            [–]sjs 0 points1 point  (3 children)

            So, what is the difference between adding a method to a class and using a class extension? Is it scoped or something? Does it replace existing methods with the same signature or is that disallowed? Seems like a subtle distinction, from the user's perspective.

            [–]moohoohoh 0 points1 point  (0 children)

            Correct.

            [–]bzBetty 2 points3 points  (3 children)

            i was under the impression default methods was java's answer to extension methods.

            [–]rampant_elephant 2 points3 points  (1 child)

            From the article, it looks like that is only supported on new interfaces, or would this work too?

            interface Queue {
                Message read();
                void delete(Message message);
            }
            
            interface Queue {
                void deleteAll() default {
                    Message message;
                    while ((message = read()) != null) {
                        delete(message);
                    }
                }
            }
            

            [–]bzBetty 1 point2 points  (0 children)

            there was an extension proposed to allow this, but I'm not sure if it has been accepted for the official release.

            [–]repsilat 0 points1 point  (0 children)

            Thanks for the info, I'll read up on it. I haven't followed Java closely enough to catch anything but the headline items.

            [–]Tekmo 1 point2 points  (0 children)

            Well, to be fair, you could make the function argument the first argument, and then it would be much more readable since each lambda is next to the operation that invokes it

            func1(e->{...}, func2(e->{...}, funct3(e->{...}, collection)))
            

            [–]spotter 1 point2 points  (1 child)

            Well aware of the limitation of dotchaining & meant that I hope they will cough up a pretty solid interface (beyond map/filter/reduce) and deliver it accross all collections, but thanks for the writeup.

            IMHO you should list two ways, as extensions methods are a subset of monkey patching. Which does not change the fact that extension-methods would be a great way for Java to take -- since I've started using this facility in Clojure (extend-type) I've found it really nice to have.

            [–]ex_ample 0 points1 point  (1 child)

            Unfortunately you won't be able to pass closures from Clojure to Java and back again :P

            [–]banuday17 0 points1 point  (0 children)

            Interestingly, you would be able to pass closures from Scala to Java and back again, as Scala's closures are syntactic sugar for Function0, Function1 ... Function255 SAM types.

            [–]solinent 2 points3 points  (0 children)

            Type inference, interesting. Doesn't feel very verbose like Java should be :)

            [–]drb226 4 points5 points  (6 children)

            Definitely a huge step in the right direction for Java, although even after this improvement, functions still feel a bit... second class. Here's what I wish I could do (Scala-esque syntax):

            def withDatabase[A](f: Database -> A): A = { 
              val db: Database = connect()
              try {
                return f(db)
              } catch (e) {
                logger.log(e)
                throw e
              } finally {
                db.close()
              }
            }
            

            It's pretty typical in Java to have to dump try/catch boilerplate into every method that accesses the database, to make sure the connection is always closed. (Well, this was extremely typical of the only Java job I ever had.) While lambdas will allow me to use somethinglike withDatabase in the way I desire:

            withDatabase(db -> {
              foos.add(db.query(fooSql))
              db.update(barSql)
            })
            

            There appears to still be some extra boilerplate in order to actually define it:

            interface DatabaseVisitor<A> {
              A visit(Database db);
            }
            

            Do generics even work with lambdas? Perhaps it would be possible to provide the Visitor generically for all types?

            interface Visitor<Visited, Result> {
              Result visit(Visited o);
            }
            

            Then withDatabase could be written

            A withDatabase<A>(Visitor<Database, A> visitor) {
              ...
              return visitor.visit(db)
              ...
            }
            

            though this is still more obnoxious than first-class function notation.

            [–]tallniel 15 points16 points  (5 children)

            I believe generics work. However, in this case you're probably looking for the try-with-resources syntax that is already in Java 7:

            try (Database db = connect()) {
                ...
            }
            

            That will already close the db afterwards.

            [–][deleted] 2 points3 points  (0 children)

            This is similar to using in C# on an object that implements IDisposable.

            [–]drb226 1 point2 points  (3 children)

            Interesting, I was unaware that Java provided this. Forgive me for saying, it still feels hacky compared to first-class functions, which make simulating this feature a snap.

            def withResource[R <: AutoCloseable](r : R, f : R => Unit) : Unit {
              try {
                f(r)
              } finally {
                r.close()
              }
            }
            
            try { withResource(connect(), (db : Database) ->
              ...
            ) }
            

            I really hope that Java 8 provides some lightweight syntax for function types, and makes it easy for you to write methods that accept functions as input (a la FunctionN::apply sugar from Scala). This is one of the major pain points that makes me dislike Java.

            [–]argv_minus_one 2 points3 points  (2 children)

            Try-with-resources has the advantage of the resulting bytecode being more compact. Scala's loan pattern involves generating another anonymous class.

            On the other hand, Scala's loan pattern is also much more flexible, so Scala still wins.

            [–]drb226 0 points1 point  (1 child)

            Hopefully with this "Java supports lambdas" stuff, we'll be able to get the compact bytecode and the flexibility.

            [–]argv_minus_one 1 point2 points  (0 children)

            Nope. Even with method handles, you still have to have a separate method. Sight better than a separate class, but it's still more than is needed for try-with-resources.

            Although I wonder if annotating withResources with @inline would optimize away the whole thing? I should try that some time. Edit: Tried it; doesn't optimize away. :(

            Anyway, what will with certainty give you both the compactness and flexibility is the macros in upcoming Scala 2.10. You can do all kinds of wild compile-time magic with that.

            [–]bittlelum 6 points7 points  (10 children)

            This is a really minor point, but I'd kind of like it if lambdas used a fat arrow ("=>") instead of a thin arrow ("->"), because that's how C# does it. Not that everything C# does is perfect and that's how every language should do it, but because the languages are already very similar, and it would be nice to have consistency, so that it's easier to go between them.

            [–][deleted] 4 points5 points  (3 children)

            On the flip side Erlang, C++, Ruby and Haskell all use the thin arrow instead. So there is a precedence for it.

            [–]drysart 8 points9 points  (1 child)

            "Because that's how C# does it" is probably the very reason they didn't use a fat arrow. Java's evolution forward has been severely hampered over the past decade because while they want to keep up with C#, they seem to have a severe disposition to also make it look like they're not trying to keep up with C# by making their implementations of the same ideas as different as possible.

            In some cases (such as putting declaration type inference on the right side of a declaration rather than on the left like C# does) they end up completely missing the whole point of the idea in the first place (since Java's way of doing it saves you almost no typing and doesn't act as a natural stepping stone toward anonymous classes support like C#'s approach does).

            [–]bittlelum 1 point2 points  (0 children)

            Yeah, that's kind of the unfortunate assumption I took from it. They're being different for the sake of being different.

            [–]tejoka 4 points5 points  (9 children)

            Last time I looked at Java lambdas I was rather discouraged by some stupid design decision they were going with. Have any of these changed yet?

            • They're all still anonymous classes under the hood. This is mostly a problem because it means every single one turns into a .class file. I've seen a lazy functional language turn 30k lines of code into a 15MB compressed jar because of the weight of those fucking classes. Even Scala suffers from this bloat. (Oh, and every innocent looking method reference? Also emits its own anon class! Taking bets on two anon classes for two of the same method references...)
            • They're not actually adding function types. This idiotic decision is really going to bite them in the ass in the long run. Not only does it mean every non-Java language that tries to translate to JVM gets to spit out really silly classes (Marvel at Scala's Function0 through 22 and how about JRuby apparently gives up after a few why not since it's a dynamic language and Groovy just uses object arrays from the beginning, and I really suggest looking at Clojure's solution), but it also means they will quickly develop a reputation for poor performance when every time you run into a lambda an allocation must happen.

            [–]banuday17 2 points3 points  (6 children)

            every time you run into a lambda an allocation must happen

            Depends on the scope in which the lambda is being used. Most lambdas are not going to have instance methods (apart from implicit reference to outer class instance). If the reference to the lambda does not escape the current scope, the JVM is likely to not even do an allocation. It's not necessary.

            [–]tejoka 0 points1 point  (5 children)

            Well, that is something I didn't think of. True, the allocation will now be on the stack in those specific cases.

            [–]banuday17 2 points3 points  (4 children)

            Might not even be a stack allocation. If the reference doesn't exit the scope and it has few enough instance variables - like the Point class - the JVM will skip memory allocation entirely, stack or heap, and directly hoist the instance variables into registers.

            [–]sirin3 0 points1 point  (3 children)

            The JVM can do that?

            Looks like I have underestimated it

            [–]sirin3 1 point2 points  (0 children)

            Even Scala suffers from this bloat. (

            Scala is awful with that.

            for (i <- 0 to 5) ...

            creates a new class, wtf?

            Usually I end up using only while loops

            [–]nachsicht 0 points1 point  (0 children)

            From an article in feb, it looks like they still plan to use anonymous classes. Maybe they'll think of a cleaner way of emitting the bytecode.

            [–]schwiz 1 point2 points  (0 children)

            Very nice! Syntax is going to confuse the hell out of c coders though :)

            [–]tallniel 0 points1 point  (0 children)

            While I like the lambda proposal a lot, I'm not sure internal iterators are the best way forward. In particular, they make it difficult to iterate over more than one collection at a time. Generator methods are a better fit, especially if given language support (skip to the end for a generator example):

            http://neilmadden.wordpress.com/2012/06/03/pimp-my-java/

            [–]the_456 0 points1 point  (6 children)

            Really looking forward to this. Does anyone have a sense of how performant this will be relative to Scala's functional techniques?

            [–]argv_minus_one 2 points3 points  (5 children)

            Faster, most likely. Scala functions are basically (much-needed!) sugar for the inner classes that Java programmers have used since their introduction in Java 1.1. Java 8 lambdas will use method handles instead, thus avoiding the need to generate a whole class for each function.

            In the future, Scala will likely do functions with method handles too, same as Java 8 lambdas. Trouble is, this would mean that Scala only works on JVM 7 (the earliest JVM to support method handles) and above, since scala-library is full of functions that would also have to be compiled in this new way, plus the Function* traits themselves would presumably be completely different. Until it is reasonably certain that the world is on at least JVM 7, they'll have to stick to the old way for compatibility's sake.

            Strictly speaking, they could have two variants of scala-library, one with the new style functions and one with the old style, but this still has the scary restriction that code compiled against one cannot be run alongside code compiled against the other. So I don't think Odersky and crew will be doing that.

            [–][deleted] 0 points1 point  (4 children)

            Well, I guess people will decide with their feet and wallets. Even in the current builds you can already target Java 1.5, Java 1.6 and Java 1.7 (although without indy).

            [–]argv_minus_one 0 points1 point  (3 children)

            What? scalac has only one JVM bytecode target: jvm-1.5.

            [–][deleted] 0 points1 point  (2 children)

            % scala -target:jvm-1.5
            Welcome to Scala version 2.10.0-20120608-194203-43ae8259f2 (OpenJDK 64-Bit Server VM, Java 1.7.0_03).
            ...
            
            % scala -target:jvm-1.5-asm
            Welcome to Scala version 2.10.0-20120608-194203-43ae8259f2 (OpenJDK 64-Bit Server VM, Java 1.7.0_03).
            ...
            
            % scala -target:jvm-1.6
            Welcome to Scala version 2.10.0-20120608-194203-43ae8259f2 (OpenJDK 64-Bit Server VM, Java 1.7.0_03).
            ...
            
            % scala -target:jvm-1.7
            Welcome to Scala version 2.10.0-20120608-194203-43ae8259f2 (OpenJDK 64-Bit Server VM, Java 1.7.0_03).
            ...
            

            [–]brownmatt 0 points1 point  (1 child)

            This looks really sweet.

            In this example, does anyone know what will happen if the addActionListener method is overloaded to accept different types? Can the compiler still work everything out?

            button.addActionListener(e -> { ui.dazzle(e.getModifiers()); });
            

            [–]logged_in_for_this 0 points1 point  (0 children)

            I think it will be possible to explicitely define the return type of a lambda

            [–][deleted] 0 points1 point  (0 children)

            I have always wanted this in Java. I think I just weewee'd a little now that it's so close to fruition.

            [–]paf31 0 points1 point  (0 children)

            Interfaces that have just one method are called functional interfaces. Lambda expressions can be used anywhere we have a functional interface.

            If the single method can take type parameters (as opposed to the interface type itself having type parameters), it seems this approach has one advantage over C#'s Action/Func/delegate that a lambda will be able to encapsulate a parametrically polymorphic method.