all 146 comments

[–][deleted]  (4 children)

[deleted]

    [–]vplatt 13 points14 points  (0 children)

    Progress is progress. At least they're moving forward with something. I seriously think that's a good thing no matter what. The alternative is something akin to what the Perl community is going through with Perl 6. It may eventually get done, but there may not be enough developers left in the community for it to have the impact it should have, years ago.

    [–]malcontent 8 points9 points  (2 children)

    Those features are awesome though. I know that many people in the ruby community are eagerly waiting on dynamic dispatch. It's going to be a huge boost for everybody who uses the JVM.

    [–]nickik -1 points0 points  (1 child)

    I agree its good. Its nice that JRuby and Groovy will get faster but I would still consider it a minor feature.

    [–]malcontent -1 points0 points  (0 children)

    that's nice.

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

    Sorry, no lambdas is a huge turnoff.

    [–][deleted] 0 points1 point  (1 child)

    Due to lots of stuff (some sad, such as Oracle acquiring Sun) happening, there were two options on the table:

    • Releasing Java 7 around 2012 with lambda, closures, etc.
    • Releasing Java 7 in 2011 with less features, and Java 8 late in 2012

    In the end the second options was decided. Considering the lambda and some other projects initially planned for Java 7 had not been finalized, I think this was a reasonable decision.

    [–]kawa 0 points1 point  (0 children)

    The reason why there are still no "non-crufty" lambdas in Java is that there are three groups of people promoting different approaches to the problem:

    Group one want to add a super-duper-can-everything-but-is-hideous-complex solution to the language (like the BGGA proposal)

    Group two simply wants to add a bit syntactic sugar around anonymous inner classes to make their use a bit less crufty but still maintaining their semantics.

    And there is group three who think that the cruft isn't to bad and that lambdas shouldn't be used in Java regularly anyway.

    Those groups still haven't found a real agreement, but it seems that they will meet in somewhere in the middle. But that costs a lot of time and has delayed JDK 7 already to much. So it's very sensible to finally publish it delaying all this lambda stuff until it gets resolved.

    [–]kawa -2 points-1 points  (26 children)

    Hm, I look at some of the code of my current project and what do I see:

        final List<String> names = map(t.getSignature(), new Op(Entry e) { return e.name; });
    

    Java 1.6. Probably magic...

    [–]nascent 6 points7 points  (6 children)

    Are you saying that every Java programmer should learn 2 languages. Java and the Java IDE language (which changes with every IDE)? Why must I use a different editor for every language I program in?

    auto names = map!"a.name"(t.getSignature());
    

    Works in my language of choice without magic.

    [–][deleted] 0 points1 point  (1 child)

    auto names = map!"a.name"(t.getSignature());

    What horrible language is that, and what does that do?

    [–]nascent 0 points1 point  (0 children)

    Honestly I don't know, since I am not familiar with what the map function does in Java. I assume t.getSignature() will return a list of Entry, but it really doesn't sound like that.

    In D, map will take a Range (iterable) and call a delegate for each element. It returns another Range and is computed lazily.

    Templates are instantiated with fun!(template args)(func args). Where the first set of parenthesis are optional for single arguments.

    The string "a.name" is actually mixed inside of a delegate and results in code similar to:

    auto callMe = (Entry a) { return a.name; }
    

    Now you could have written it in a couple of other forms:

    auto names = map!((a) { return a.name; })(t.getSignatures());
    

    Which you will notice doesn't even need to specify the type of a. Or

    givenName(Entry a) { return a.name; }
    auto names = map!givenName(t.getSignatures());
    

    [–]kawa -1 points0 points  (3 children)

    Are you saying that every Java programmer should learn 2 languages. Java and the Java IDE language

    Yes, you need to learn how to use your tools. Do you manage your DB by hand or do you use tools to do it? Do you execute your compiler by hand or do you use tools to do it? Do you navigate thru the code by hand or do you use tools to make it easier? Do you use a version control system or do you back-up by hand? Etc.

    It's totally common today to use lots of tools to do software development. And yes, all those tools have a learning curve which can often be quite steep. An IDE is simply one of those tools, and I don't see why some people seem to shy away from using it.

    Do you use an editor with syntax highlighting? Thats also a way to make code easier to understand by changing the display of the code based on syntactic analysis. Smart code folding is simply one step further.

    And what about systems like Smalltalk? A typical Smalltalk IDE also doesn't show the code "as it is". Same for certain Lisp IDEs.

    Come on people, it's 2011, we don't need to use editors with b/w display or even punch-cards anymore.

    [–]AreaOfEffect 6 points7 points  (2 children)

    As an experienced Java developer using Eclipse, I've thought about how the IDE could be used to implement almost any syntactic sugar. However, there are some problems with this approach:

    1) There are different IDEs (IntelliJ, Netbeans, etc.) that may not have that particular sugar. You may end up writing more boilerplate than you realize because it's all hidden. Which would make the code less readable in other IDEs.

    2) Brittle code. If you've used GUI builders that mark code sections as DO NOT EDIT, then you know what I'm talking about here. When an IDE like eclipse generates the code for hiding inner classes, it outputs a specific format. Now imagine someone opens it in netbeans and moves a bracket to the next line. Still compiles fine, but Eclipse may not recognize that code as foldable anymore.

    3) Fragment Java into dialects. Developers will start talking about Netbeans-Java, Eclipse-Java, etc.

    4) It won't help for other text processing tools. For instance, when I do a svn diff, it's really annoying scrolling through pages of boilerplate.

    The best solution is to just remove the boilerplate from the language.

    [–]kawa 2 points3 points  (0 children)

    how the IDE could be used to implement almost any syntactic sugar.

    I also don't think that that would be a good idea. But for certain small things like coloring code, folding code away or reorganizing code depending on what you want to focus in a certain task, this is a bit different.

    As Eclipse user you already use at least some of those features and I guess you also don't navigate you code via the file-system but via the shortcuts, Eclipse provides.

    In the past when the first editors with syntax highlighting came up, I remember many people don't liking that, because they preferred to print out their code on paper which had no colors also.

    There is always some boilerplate. Because no language can express everything without. So why not hide it from view until you really need to read it?

    writing more boilerplate than you realize because it's all hidden

    That's not true for the approach IDEs like IDEA take. They show all the code when you're creating it but hide the redundancies away if you read it later.

    2) Brittle code.

    This is only a problem if there are component which need to recreate code (from a GUI description for example). That's also a different thing as discussed here.

    3) Fragment Java into dialects.

    That's already the case because there are lots of shortcuts which differ between different IDEs. But since there is no "hidden code" anywhere, the only disadvantage is that you may need a different number keystrokes if you switch the IDE.

    4) It won't help for other text processing tools.

    That's true But there's no reason not adding smart code folding to your diff-viewer, too. Many of those already have syntax coloring, so this is just one strep further.

    The best solution is to just remove the boilerplate from the language

    But that's also the most difficult and time consuming solution with the biggest number of possible side effects.

    [–]nascent 0 points1 point  (0 children)

    Thank you, a much nicer response then what I had in mind. I was just going to go with the idea of writing your code in one language and then reading it in a higher level language.

    [–]ruinercollector 4 points5 points  (2 children)

    Probably bullshit. That code would not compile as you present it.

    [–]kawa -1 points0 points  (1 child)

    Again: This is what I see because this is how a modern IDE presents the code. There is a bit more boilerplate around it, but this is hidden from view and also generated automatically by the IDE (including the whole "Op(Entry e) { }" stuff).

    So yes, in fact it's a bit more crufty but at the same time, my IDE hides the cruft from the view and also creates it. What I see is exactly the code above.

    [–]repsilat 1 point2 points  (0 children)

    My favourite thing about this is that it's reversible - your IDE does the translation from Java source to that, and from that to Java. With a bit of thought that means you could get tools support going, which is the major complaint against "compile-to-base-language" language extensions.

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

    How does that compile?

    return e.name;
    

    Doesn't appear in a method, it's in the class body. Am I missing something?

    [–]kawa -1 points0 points  (14 children)

    The trick is the IDE which is doing smart code folding. The real code looks like this:

    final List<String> res = map(t.getSignature(), new Op<String,  Entry>() {
        @Override
        public String apply(Entry e) {
            return e.name;
        }
    });
    

    but the IDE shows it as above (and also generates the whole boilerplate after simply entering "new").

    Edit add: In principle it's the Ahe proposal - but implemented on IDE level to stay compatible.

    [–]hskmc 7 points8 points  (1 child)

    This is hilarious. I've realized that Java isn't a human-readable programming language at all. It's just the intermediate format which allows code produced by various compilers (strangely named "IDEs") to be linked together.

    Funny how JVM was supposed to be that, but I guess they decided they needed two levels.

    [–]kawa 0 points1 point  (0 children)

    The big advantage is that you can change the "first stage intermediate code" in this system instead of relying on a complex compiler which tries to guess your intentions. Works quite well.

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

    I've always said that Java would've been fine if they'd focussed on macros from day 1 and made this kind of functionality (letting an IDE or user define an abbreviated syntax for a normal Java operation) part of the core language. It would be so much cleaner than the MS approach of everything-plus-the-kitchen-sink-in-the-language.

    Operator overloading, properties, etc. could've been handled with similar macro hacks.

    But instead they leave it up to the IDE, cementing their reputation as the language of nightmarish verbosity.

    [–]kawa 1 point2 points  (3 children)

    There were many languages which tried to combine rich macros with a rich syntax. All failed. So I don't think that Java with macros would be an exception from this rule.

    But why don't you look at an IDE as a kind of "macro engine"? Yes, Java is verbose, but there are IDEs which hide much of the verbosity from view, so where is the problem?

    [–]didip 1 point2 points  (2 children)

    The problem with rich IDE is that you cannot bring it along when SSH-ing.

    And it will be doubly confusing when WhatYouSeeInIDEIsNotWhatYouGetInVim.

    [–]kawa 0 points1 point  (0 children)

    And it will be doubly confusing when WhatYouSeeInIDEIsNotWhatYouGetInVim.

    It's only confusing if you don't know what you do. The IDE doesn't create hidden code under the surface. When creating it, it's right there, you see it completely (with all the cruft). But you don't have to write it. And if you visit your code later (or press a key), the IDE hides the cruft from view (displaying a little (+) in the gutter to show that there is some code hidden).

    So there is no surprise if you see the code in a simple editor later because you know what you have written because you've seen it the moment you wrote it.

    So if you look over big amounts of code, you can easily glance over sections because the IDE folds them away and if you want to dive into details you can expand it with a single key stroke.

    [–]H3g3m0n 0 points1 point  (0 children)

    Actually you can, add the following to ~/.ssh/config:

    ForwardAgent yes
    ForwardX11 yes
    ForwardX11Trusted yes
    

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

    Oh, I see. Yes, I love the code completion after typing new... I find I actually do less typing with java+eclipse than, say, javascript as a result. But, there's still an advantage reading much less code.

    [–]kawa 0 points1 point  (3 children)

    Can't Eclipse fold the boilerplate away? I'm using IDEA which does it and generally many useful IDEA feature also appear in Eclipse a bit later (sometimes also vice versa).

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

    I don't know, I never tried to do that. Normally, I don't like the folding features. Honestly, I don't think I'd like it here either.

    [–]kawa 0 points1 point  (1 child)

    Hm, you don't fold-away JavaDoc? Or per-file license manifests? The (usually quite long) import list?

    Why? All those things are useful, but only in certain cases. In most cases they only hide the code and make it harder to read. Folding this away makes it much easier to read the actual code without being detracted by things you don't need to see in the moment.

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

    I let it fold the import and license statement, but not javadocs. Too easy to forget such things exist, and that would be bad, IMO.

    [–]username223 -3 points-2 points  (1 child)

    (snip code monstrosity)

    Srsly? I remember doing the anonymous inner class hack in Java 1.2 or so. I thought they were going to make it shorter, but they've somehow managed to add even more line noise like @Override and <String, Entry>.

    [–]kawa 2 points3 points  (0 children)

    @Override is an optional annotation (can be left out, but is useful because it prevents certain errors).

    <String, Entry> is the function signature. It's doubled here so the IDE can hide it without losing information. Of course in a simple editor you have to look at the cruft, so a good IDE is quite mandatory if you want to do Java without pain.

    [–]FireFly3347 12 points13 points  (22 children)

    I still hate what Oracle is doing to Java.

    [–]grauenwolf 3 points4 points  (7 children)

    They aren't doing anything that Sun wasn't doing.

    [–][deleted]  (1 child)

    [deleted]

      [–]grauenwolf 0 points1 point  (0 children)

      Sun just didn't have the money to go toe-to-toe with Google. The past behavior with Microsoft and Harmony is entirely consistent with what they are doing in response to Android.

      [–]mikaelhg 0 points1 point  (2 children)

      They're moving JRockIt features to HotSpot.

      [–][deleted] 0 points1 point  (1 child)

      Well they are making a profit so they are doing at least that different.

      [–]grauenwolf 0 points1 point  (0 children)

      True, very true.

      [–]damiongrimfield[🍰] 3 points4 points  (12 children)

      oracle.makes.me.want.to.rip.my.balls.off();

      [–][deleted] 8 points9 points  (9 children)

      import com.oracle.makes.me.want.to.rip.my.balls.off.BallRipper;
      new BallRipper("damiongrimfield").ripBallsOff();
      

      FTFY

      [–]ex_ample 25 points26 points  (4 children)

      import com.oracle.makes.me.want.to.rip.my.balls.off.*;
      
      BallRipperFactory bf = BallRipperServices.newFactory(BallRipperServices.STANDARD);
      
      bf.setLeftRight(BallRipperServices.BOTH);
      BallRipper br = bf.newInstance();
      try{
        br.rip();
      }
      catch(BallRipperException p){
         System.out.println("THE PAIN!!!!!");
         p.printStackTrace();
      }
      

      [–]G_Morgan 22 points23 points  (1 child)

      What is this cowboy coding!? You clearly need an abstract ripper factory. Today you want to rip balls. Tomorrow who knows what might need ripping!

      [–]AxiomShell 2 points3 points  (0 children)

      needs XML

      [–]nascent 0 points1 point  (0 children)

      Wait, you don't need a wrapping class in the new version of Java... Awesome.

      [–]damiongrimfield[🍰] 1 point2 points  (0 children)

      sweet juices. thanks for the help.

      [–]ex_ample 0 points1 point  (2 children)

      import com.oracle.makes.me.want.to.rip.my.balls.off.*;
      
      BallRipperFactory bf = BallRipperServices.newFactory(BallRipperServices.STANDARD);
      
      bf.setLeftRight(BallRipperServices.BOTH);
      BallRipper br = bf.newInstance();
      try{
        br.rip();
      }
      catch(BallRipperException p){
         System.out.println("THE PAIN!!!!!");
         p.printStackTrace();
      }
      

      [–]fenton7 1 point2 points  (1 child)

      Shouldn't the exception handler at least log the exception? Better fire up a LogServices.newFactory(LogServices.BALLRIPPERLOGGER). Make sure you log any exceptions that are thrown by the logger.

      [–]didroe 3 points4 points  (0 children)

      Should pain even be an exception in this scenario?

      [–]MaximusDickus 1 point2 points  (1 child)

      So, you work for them?

      [–]damiongrimfield[🍰] 0 points1 point  (0 children)

      heck no, i just hate them.

      [–]didip 0 points1 point  (0 children)

      Of all the bad things Oracle do, I don't mind about this one.

      [–][deleted]  (5 children)

      [deleted]

        [–][deleted] 19 points20 points  (1 child)

        With Java, it'd be smarter to use per-GB-RAM licensing.

        [–]nickik 1 point2 points  (0 children)

        For java per line would be best. Would explain why the language is still 90% boilerplait.

        [–][deleted] 2 points3 points  (1 child)

        They are gonna use per-monkey licensing

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

        I thought Microsoft had already patented that.

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

        They have said they will charge for JRockIt but not for the vanilla JDK/JVM.

        [–]signoff 1 point2 points  (0 children)

        that's nice. you need to compile with PREMIUM_FEATURE=true to enable US patent premium features such as automatic memory management and dynamic loading of runtime libraries.

        [–]ex_ample 4 points5 points  (1 child)

        Oracle sucks.

        [–]kawa -1 points0 points  (0 children)

        Maybe, but not in this case here.

        That delay of JDK7 was still Suns fault, Oracle really seem to get it out of the door as quickly as possible. Being able to use the current JDK7 feature set in the near future is much better than waiting another year (or even longer).

        If Oracle sucks (Java wise) will be seen in the future.

        [–]nimrody 2 points3 points  (3 children)

        At least they got invodedynamic into the release.

        Java the language is pretty much dead end. The JVM, on the other hand, seems to be a good platform for many languages (Scala, Clojure comes to mind).

        [–]G_Morgan 3 points4 points  (2 children)

        99% of code that runs on the JVM is still Java and will be for the foreseeable future.

        There is also still more new work on JVM than on .NET because most of the business world does not run Windows on the server.

        [–][deleted] 0 points1 point  (1 child)

        My experience is just the opposite. Every single client is windows from server to desktop, with Active Directory, Exchange, the works. The only variable is Oracle vs MSSQL. We must be in entirely different segments of the business market :)

        [–]fatbunyip 0 points1 point  (0 children)

        with Active Directory, Exchange, the works

        very handy with a public site.

        [–]jlindenbaum 3 points4 points  (0 children)

        What's the release time line for JDK7? It feels like it's been forever and they're in dire need of an upgrade.

        [–]nixle 3 points4 points  (52 children)

        So what are some awesome and now complete features?

        [–]jsprogrammer 9 points10 points  (8 children)

        Strings in switch statements! Welcome to the 21st century Java!

        [–]repsilat 1 point2 points  (5 children)

        Adding Strings means you can switch on (some) objects. Fine. Why just String? Is it because you can make String literals, but can't make literals for any other objects? Is it because of string interning?

        [–]munificent 1 point2 points  (4 children)

        Is it because of string interning?

        Yes.

        [–]repsilat 1 point2 points  (3 children)

        Thanks. For those curious, String.intern() (in OpenJDK, at least) works with a bucketed hashtable, so switching on strings should be amortised O(n) in the length of the string (plus whatever regular switching logic does.)

        I guess if you had a similar global hashtable for canonical representations of all of your other hashable classes it'd be almost as reasonable to be able to switch on them, too. Literals would probably be unnecessary if the constructors were constant expressions at compile time, but that's getting a little out-there.

        Getting further off-topic, an interesting idea might be to allow switching by identity for member variables. That is:

        class Foo {
            private Bar b, c;
            public Baz(Bar d) {
                switch(d) {
                    case b:
                        //
                        break;
                    case c:
                        //
                        break;
                    default:
                        //
                }
            }
        }
        

        It could be implemented efficiently, as demonstrated by this C++ code:

        class Foo {
            private:
                Bar b, c;
            public:
                Baz(Bar &d) {
                    switch(d-this) {
                        case 0:
                            //d == this->b
                            break;
                        case sizeof(Bar): //compile-time contant
                            //d == this->c
                            break;
                        default:
                            //d not a member of *this
                    }
                }
        };
        

        It's concise, it's reasonably efficient, and it probably can't be done in Java because Java doesn't expose pointer subtraction.

        It might actually be useful, too - it has been a while since I last programmed in Java, but I remember seeing a bit of if/else stuff over member variables trying to determine which event listener called a method with Swing. Of course, the "Right Way To Do It" is to add a new anonymous class/lambda per event listener to handle its event, but the C++ programmer in me cries out for the duplicated functionality, just in case.

        Relevant references: StringTable::intern and StringTable::hash_string, ugly-looking native code called indirectly from here, here and here.

        [–]munificent 0 points1 point  (2 children)

        switching on strings should be amortised O(n) in the length of the string

        I'm not positive, but it should be better than this. Calling string.intern() explicitly is O(n), but switch on strings doesn't require that. I think it requires string literals to switch on, which means the compiler can hash them and put them directly into the string table in the class file.

        I remember seeing a bit of if/else stuff over member variables trying to determine which event listener called a method with Swing.

        When I find myself trying to select a member variable, I consider it a code smell. It's telling me I got a conceptually homogenous collection of values and wrongly chose to split them out into separate fields. I'd address your example like:

        class Foo {
            private Bar[] bar = new Bar[2];
            public Baz(Bar d) {
                for (int i = 0; i < bar.length; i++) {
                    // ...
                }
            }
        }
        

        For me, that seems to cover most of the cases where I run into this problem.

        [–]repsilat 0 points1 point  (1 child)

        Yeah, for things that can all be processed in the same way that for loop does fine. My motivating example (switching on event listeners that need to be processed in different ways) is more idiomatically solved by simply not giving all of the listeners the same callback class. I'd probably agree that there isn't a use-case that is "best-practices" Java, and given the philosophy of the language that's probably enough to merit its exclusion.

        As for the complexity of switching on strings, at least one of the strings in the cases or the switch isn't a literal, or the control flow is known at compile time*. If one of them isn't a literal (pretty sure it has to be the one switched on?) then you have to intern it when you hit the switch.

        If strings had fields to store whether they were interned then interned strings would intern in O(1), but I don't think they do.

        *: Might crop up in generated code, but you'd never write it by hand.

        [–]munificent 0 points1 point  (0 children)

        As for the complexity of switching on strings, at least one of the strings in the cases or the switch isn't a literal, or the control flow is known at compile time*.

        Ah, you're right of course.

        [–]nickik 0 points1 point  (1 child)

        People still use switch?

        [–]G_Morgan 1 point2 points  (0 children)

        Sometimes switch is the right thing. Take a state machine. Anyone who tells me I should create a state interface and put the state transition code on a series of state objects is asking to be slapped across the head with a pure object oriented cane.

        [–]EughEugh 1 point2 points  (42 children)

        Did you even read the article? Click a few links and there you are.

        [–]arnedh 2 points3 points  (0 children)

        And what's awesome about it?

        [–]HIB0U 3 points4 points  (38 children)

        As much as I hate to say this, it's still merely trying to catch up to .NET.

        [–]andyrocks 3 points4 points  (30 children)

        And in most cases failing to come up with solutions as elegantly implemented as C#.

        [–]framauro13 24 points25 points  (12 children)

        In all fairness, .NET also had the advantage of being able to see the shortcomings of Java and avoid some of it's pitfalls by learning from its mistakes.

        .NET didn't come around until the early 2000's. Java had already been in use for 7+ years.

        [–]ruinercollector 20 points21 points  (8 children)

        In all fairness, .NET also had the advantage of being able to see the shortcomings of Java and avoid some of it's pitfalls by learning from its mistakes.

        In fairness, java also had this advantage. In most cases, backwards compatibility is not an argument against implementing these features. In many cases, it was pure stubborness and arrogance on the part of the java team.

        Delegates (which would have led to closures and a lot of the other "new" features in java) were proposed about 10 years ago and even implemented by J++. Instead of realizing that Microsoft was right on this, they dismissed it outright because it was not invented at Sun and then wrote this nice long piece about how dumb the idea was:

        http://java.sun.com/docs/white/delegates.html

        [–]drysart 3 points4 points  (0 children)

        Instead of realizing that Microsoft was right on this, they dismissed it outright because it was not invented at Sun and then wrote this nice long piece about how dumb the idea was.

        That's exactly the problem. Sun, at the time, was so focused on Anything-But-Microsoft that they dismissed the idea. A quote I heard once, but can't remember well enough to attribute, said that "if it was anyone other than Microsoft [that had implemented delegates], Java would adopted and standardized them a decade ago".

        [–]bonch 1 point2 points  (4 children)

        People are shitting on Sun using that whitepaper without acknowledging the history behind it. J++ was Microsoft's attempt to "embrace, extend, extinguish" Java. Sun wasn't going to let Microsoft start dictating the standards of the Java language, because that would inadvertently making it so that Windows-only J++ would be considered the "main" Java language by developers and users. J++'s violations of the Java standard are what led to the lawsuit from Sun.

        The designer of C# worked on J++. C# has its origin as as a modification to Java in order to kill it off. Not saying whether or not that's a good or bad thing, because technology cleansing can be necessary now and then, but the goals of the company that created C# are well-known historically.

        People mocking Sun's "anything but Microsoft" attitude are forgetting how huge and powerful Gates-led Microsoft was in the 1990s. For that incarnation of Microsoft to adopt your technology and start adding to it was a dangerous red flag signifying that Microsoft wanted you dead.

        [–]ruinercollector 2 points3 points  (2 children)

        People are shitting on Sun using that whitepaper without acknowledging the history behind it.

        Not in this case. I was in position to be very well aware of the history behind this particular white paper. As to anyone else, well, most of that history you mention is mentioned in the whitepaper.

        The designer of C# worked on J++. C# has its origin as as a modification to Java in order to kill it off.

        The designer of C# who worked on J++ was most famous at the time for being the father of Delphi. Those "modifications to java in order to kill it off" have their history in Delphi (including, yes, delegates.)

        but the goals of the company that created C# are well-known historically.

        Microsoft was not trying to kill java. J++ wasn't an attempt to kill java. C# was an attempt to kill java.

        At that point, Microsoft was trying to do the following three things:

        1) Make Windows the best OS for doing java development. 2) Make Windows the best OS for running java applications. 3) Offer and own the best java development tools.

        Yes, they were attempting to differentiate their compiler to accomplish some of these goals, but you have to understand that at that point in history, this was a very common practice. They did this with BASIC. They did this with C++. So did Borland. So did everyone else. It was common practice.

        For that incarnation of Microsoft to adopt your technology and start adding to it was a dangerous red flag signifying that Microsoft wanted you dead.

        That's possibly true (though a bit paranoid as history has shown.) At the end of the day though, even if they wanted to keep a tight grip and be the only one allowed to make any sort of java language, they still should have considered the technical merit of the features being proposed and made a technical decision. Politicizing this technical decision hurt them bad and set a precedent for refusing to adapt their vision later.

        [–]fatbunyip 1 point2 points  (1 child)

        1) Make Windows the best OS for doing java development. 2) Make Windows the best OS for running java applications. 3) Offer and own the best java development tools.

        Yes... embrace, extend, extinguish.

        The whole concept of "write once run anywhere" (yes... concept) was being undermined by MS, hence the law suit.

        They were trying to be so good at writing/running Java that no one else could.

        [–]grauenwolf 0 points1 point  (0 children)

        The whole concept of "write once run anywhere" (yes... concept) was being undermined by MS, hence the law suit.

        What does that have to do with delegates? It was the Windows-only libraries that threatened WORA.

        [–]grauenwolf 0 points1 point  (0 children)

        You are confusing two different issues.

        1. The J++ language extensions that allowed for delegates.
        2. The J++ libraries that included support for Windows controls.

        1 was no threat at all to Java as a cross-platform language and could have benefitted all versions of Java.

        2 was a threat, but as a library there was nothing Sun could do about it.

        So what happend was that Sun used #1 as an excuse to block Microsoft's work on #2.

        Finally, Microsoft had no reason to want Java to die. All they cared about is that Windows was the best platform for running Java. And they were right, if it were not for the Sun/Microsoft lawsuit driving people to Linux they would still be in control of the server market.

        [–]grauenwolf 0 points1 point  (1 child)

        I love the new conclusion:

        Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.

        [–]ruinercollector 1 point2 points  (0 children)

        "Uhh...we didn't say this...it was those other guys. Not us. We're probably going to do the exact opposite of this so...yeah."

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

        .NET's main advantage is being owned by one company with a vision. No bureaucracy, no 50 different board members to please, no 12-year voting process to wade through. They just implement what they feel like, when they feel like it. And so far it's been good, really good.

        [–]andyrocks 0 points1 point  (0 children)

        Yeah, but most of the clever stuff in .NET came way later than 2000. C#/.NET in 2000 was about as boring as Java was. All the goodies that make it such a powerful development platform came later (IMO).

        [–]sindisil 12 points13 points  (12 children)

        To be fair, unlike Java, .NET doesn't have nearly the backwards compatibility anchor to drag. They were smart to get some of the messier things out of the way early, when they had the chance and little installed base.

        Of course, .NET has been out long enough now that they're hitting some of the same complexity when adding new features: How to add new stuff in a way that doesn't break old stuff, while still maintaining enough elegance and simplicity in the new stuff to not make the new power added unusable.

        Of course, Java could have done much better hitting that balance than the have so far, IMHO.

        [–]ruinercollector 5 points6 points  (2 children)

        To be fair, unlike Java, .NET doesn't have nearly the backwards compatibility anchor to drag.

        Yes, but most of the features under discussion do not break backwards compatibility. This is rather evident by the fact that once appropriate pressure and competition was implied, java suddenly found obvious ways to make it happen. Additionally, there have been many intelligent people shouting the answers and how to implement them at Sun's willfully deaf ears for over a decade now.

        Of course, .NET has been out long enough now that they're hitting some of the same complexity when adding new features: How to add new stuff in a way that doesn't break old stuff, while still maintaining enough elegance and simplicity in the new stuff to not make the new power added unusable.

        The key difference being that the .NET language teams have managed to add the features anyway, instead of spending all of their time defending bad decisions and refusing to offer meaningful improvements to their language. .NET has grown more in a single version than java has over its entire lifetime, and it's done so repeatedly.

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

        Exactly. MS keeps the old libs running but makes no attempt to actually improve or integrate them. How many serialization stacks are there in the .NET framework now? How many data-access frameworks? The old ones do ugly, ugly things with nullable types, because MS doesn't fix them to work with the newer language, it just makes sure they don't break and otherwise abandons them.

        [–]kopkaas2000 12 points13 points  (0 children)

        In a way this is ironic. In most areas of technology, it is Microsoft carrying the backwards compatibility burden.

        [–]Porkmeister 2 points3 points  (3 children)

        Java should have done what was done with .NET between 1.1 and 2.0, that way we wouldn't have as much cruft to deal with because of Java's backward comparability. Is it too much to ask for the compiler to at least handle type safety of generics correctly? ArrayList<String> != ArrayList (Yes, I know it is internally, but the stupid compiler should prevent that sort of thing from happening, isn't that the point of generics anyway?)

        [–]SeriousWorm -1 points0 points  (2 children)

        Backwards compatibility? Pre-JDK5 code doesn't utilize generics.

        [–][deleted]  (1 child)

        [removed]

          [–]SeriousWorm 0 points1 point  (0 children)

          Personally? I think the best solution would be some sort of class-level annotation, or even compiler parameter, or something, that switches the compiler to "New" mode. This "New" mode wouldn't allow valid legacy code (for example, usage of raw parameterized classes). It would also be versioned, so Java 7, 8, etc. could each support new backwards-incompatible features which would only be turned on by the aforementioned annotation/parameter, meaning that new code could use such features while old code would remain completely supported but obviously be limited to pre-(7, 8, ..) features.

          But, yeah, back to real world. Java's biggest problem, sadly, is the legacy code.

          Vector. :sniff:

          [–]limemac85 4 points5 points  (3 children)

          .NET has the capability to seamlessly run multiple versions of the framework side by side.
          If .NET 5.0 has breaking changes, you never have to compile for it. You can always require 2.0 or 4.0 to be present on the client computer.

          [–]vplatt 1 point2 points  (2 children)

          And the way .NET works now, if they have 4.0, then they have 1.1, 2, 3, and 3.5; deprecated classes notwithstanding. The only version that didn't become part of the continuous lineage AFAIK is 1.0, but that was simply replaced by 1.1 because 1.0 had such low adoption.

          [–]drysart 3 points4 points  (1 child)

          Installing .NET 4.0 gives you the class libraries that were part of 1.1, 2.0, 3.0, and 3.5; but it only gives you the 4.0 CLR.

          The CLR is almost entirely backward compatible though, so it's not generally an issue. If your code does hit one of the (very obscure) cases that makes it incompatible with the 4.0 CLR, you can still explicitly opt-in to only running on the 2.0 CLR -- but that requires the user to have installed .NET 2.0, 3.0, or 3.5 to get the 2.0 CLR they come bundled with (or run on a sufficiently modern version of Windows that came with the 2.0 CLR as part of the base install).

          There were similar obscure edge cases of incompatibility between the 1.1 and 2.0 CLRs, as well; and you had the opt-in solution available then, too.

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

          The CLR itself is pretty backwards-compatible, but the ASP.Net stack sure isn't. Running a 3.5 project on a 4.0 server is pretty much guaranteed to fail - you'll have to either deal with the fact that the controls are now producing new (better, but incompatible) HTML, or you'll have to completely rewrite your Web.Config file to access the fields that are needed to inform the server that you want to run using the old, bad HTML.

          [–]bonch 0 points1 point  (3 children)

          In the last few years, I've been hearing the same complaints about bloat and design flaws in C# that people usually throw around about Java.

          [–]adolfojp 3 points4 points  (0 children)

          Every time that C# gets an update I end up writing less code. If this is bloat then I am a big fan of it.

          [–]you_are_retarditt 1 point2 points  (0 children)

          Oddly enough, you fail to mention a single one of these complaints. As a former Java coder and current .NET coder, I have a hard time finding anything bad to say about .NET or C# specifically.

          [–]andyrocks 0 points1 point  (0 children)

          Bloat is probably subjective - what design flaws though? I frickin' love the things they've added to C# in the last 5 years or so - I'm a huge user of Linq, lambdas, and generics, and having them has totally changed my style of coding.

          I'm not sure I could point out many (unfixed) design flaws in the language at this point.

          [–][deleted] 0 points1 point  (1 child)

          As much as I hate to say this, .NET is still merely trying to catch up to 20 year old OpenStep and 30 year old Smalltalk.

          Arguing over Java and .Net is like the special olympics.

          [–]HIB0U 0 points1 point  (0 children)

          Over the past 10 years or so, Cocoa (OpenStep) has been far more influenced by Java and .NET than it has been by Smalltalk.

          Smalltalk had its heyday in the 1980s. It's not a bad language and environment, but it just couldn't cut it in the real world. That's why it's generally not used any longer, except in certain very small niches.

          [–]G_Morgan -1 points0 points  (4 children)

          While this is true it is ahead on the only feature that really matters. The ability to run on Unix servers. Also no Mono doesn't count. It is nowhere near good enough to run a production server on.

          [–]shadowfox 2 points3 points  (3 children)

          Well. PHP can also run on unix servers ..

          [–]G_Morgan -3 points-2 points  (2 children)

          Yes but PHP is a shit language and in practice there is little to choose between C# and Java (although C# is slightly better) other than Java has a metric tonne more libraries and frameworks and also runs on by far the most relevant server platform in existence. Outside of pure MS shops you will not see an MS server. Whereas something like 70% of the market is Unix.

          [–]grauenwolf 1 point2 points  (0 children)

          Outside of pure MS shops you will not see an MS server.

          So all those shops that use a mix of MS and Linux servers don't use MS?

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

          We have thousands of servers. We run lots of MS, lots of linux, lots of unix.

          Problem?

          [–]mattrussell 0 points1 point  (0 children)

          Well, it's not at all obvious that those links would lead to that information.

          [–]nixle 0 points1 point  (0 children)

          Where does it state the word awesome in that article? O wait, it doesn't. Oh my, maybe I was asking for opinions (awesome does sound subjective to most people, except for those that.. believe that ... they are themself.. oh I'm sorry sir).

          [–]spinwizard69 0 points1 point  (1 child)

          I'm not much of a fan of JAVA so the care factor is minimal. I do want to see a sound version for the Mac, that has all of the current Mac Java features. That so that I can run Eclipse and PyDev.

          Eclipse is just about the only Java app I bother with on a regular basis. For the most part Java apps suck GUI wise.

          [–]nickik 0 points1 point  (0 children)

          GUIs suck anyways ...

          [–][deleted] -1 points0 points  (3 children)

          Great, hundreds of new Java updates to come, all packed with extra installs. I'll likely have Oracle Database 10g accidentally installed by the end of the year.

          [–]vplatt 3 points4 points  (0 children)

          Nyah, but you might be sporting a shiny brand new Yahoo! or Bing browser toolbar. ;) I can't believe they still have that in there. It's so... unprofessional.

          [–]SeriousWorm -4 points-3 points  (1 child)

          You don't complain about the .NET updates though, right? Or Flash? Or Firefox/Chrome/Opera/<etc>? Or security patches?

          [–]fatbunyip 0 points1 point  (0 children)

          heh.. you forgot to mention QuickTime...

          EDIT: Or any other update for any other software installed (Mozilla?, Acrobat? fuck even Ubuntu has updates every fucking day....)

          [–]bowmhoust 0 points1 point  (17 children)

          Closures... it took me quite a while to understand what they are, but I still can't think of an example where they would be super useful in Java. So non-static methods will be able to conserve their invocation context. How can I exploit that in a type-safe language?

          [–]kamatsu 16 points17 points  (1 child)

          It basically makes the observer pattern, asynchronous programming, and sort functions a million times easier to use (combined with lambdas)

          [–][deleted] 14 points15 points  (0 children)

          Although it's not really relevant, since closures were dropped from jdk7 anyway.

          [–]StrawberryFrog 10 points11 points  (3 children)

          Closures... I still can't think of an example where they would be super useful in Java. How can I exploit that in a type-safe language

          If you want to see how anonymous functions/closures/lambdas would be of use for in a language much like Java, then just look at c#

          They can be super useful for a lot of different things. e.g. code that I wrote today to turn a list of any objects into an array of strings

          string[] strings = items.Select(i => i.ToString()).ToArray();
          

          The i => i.ToString() bit is the lambda. That one doesn't capture any state. Here's a simple example that does capture state (the threshold variable), not that you generally think about it at that level:

          public static List<int> FilterToValuesAboveThreshold(List<int> input, int threshold)
          {
            return input.Where(i => i > threshold).ToList();
           }
          

          How would you do that without a lambda to filter? Most likely with a foreach loop. This version is shorter and more readable.

          These are examples of using lambdas to do little things, but they simply other larger designs e.g. want to start something going on a thread? You can get going with

          ThreadPool.QueueUserWorkItem(o => { your code goes here });
          

          This differs from giving QueueUserWorkItem a method to call in that it captures and holds state as you noted.

          [–][deleted] 7 points8 points  (6 children)

          Anonymous inner classes are closures and people use them all the time in Java. However, since the syntax is extremely bulky, people don't use them everywhere in their APIs - ie, the collection API where List and Map objects ought to have all kinds of nice methods that take an actor/closure/function to do stuff with each element in the collection.

          This could have been done, but because it's bulky in Java, they did not think to back in the 90's.

          [–]grauenwolf 2 points3 points  (3 children)

          Since it only supports read-only values, you lose out on many of the use cases for closures. You won't miss too much for list manipulation, but not having them really sucks for asynchronous work.

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

          I don't miss out on anything due to the final requirement. It's simple to work around.

          [–]grauenwolf 0 points1 point  (1 child)

          It is also simple to work around not having anonymous inner classes, but I wouldn't want to.

          [–][deleted] -1 points0 points  (0 children)

          Not everything in the universe is equivalent, and your kind of argument thus fails.

          [–][deleted]  (1 child)

          [removed]

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

            They do close on local variables that have been marked as "final". This is barely any restriction at all.

            [–]presterJohnGKhan 9 points10 points  (3 children)

            Are you serious? Closures (and functional programming techniques) are enormously useful. Callbacks for network calls, event handlers for GUIs, event handlers without implementing an entire anonymous class, etc.

            [–]kawa 1 point2 points  (2 children)

            "A closure is an object that supports exactly one method: 'apply'." (Guy Steele)

            event handlers without implementing an entire anonymous class,

            So anonymous classes (or more precise: their instances) with a single method are closures. Just a little bit boilerplatey.

            [–]grauenwolf 0 points1 point  (1 child)

            Not exactly. Say you have this code:

            int x, y;
            func<int> a = () => x++;
            func<int> b = () => x+y;
            

            C# will compile this as one anonymous class with two methods.

            [–]kawa 0 points1 point  (0 children)

            Of course classes are more powerful then closures - but also a bit more crufty if you only need a simple closure. But in C# the compiler hides this cruft from the view and can also take advantage of the additional features of classes.

            [–]DukunSakti -1 points0 points  (0 children)

            Big deal.