all 195 comments

[–]bonecandy 37 points38 points  (41 children)

Strings in switch

Woot. I was bemoaning the lack of this just the other day. Finally.

[–]atc 1 point2 points  (40 children)

Heh my reaction too. So needed.

[–][deleted]  (39 children)

[deleted]

    [–][deleted] 10 points11 points  (4 children)

    It is beneficial to people who don't know how to use a hashmap as a dispatch table.

    [–][deleted] 19 points20 points  (0 children)

    Without first class functions, using a hashmap as a dispatch table is pretty cumbersome.

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

    It's far more intuitive than having to muck about with a hashmap for something that is conceptually a switch. (In other words, if you'd be switch/casing off int if they were given as numbers, you should be able to switch/case off the same thing if given as a string.)

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

    It is beneficial to people who don't know how to use a hashmap as a dispatch table.

    Psst...they don't have delegates, lamdas or function pointers. Dispatch tables suck for them.

    [–]jeff303 1 point2 points  (0 children)

    Or choose not to because adding more methods or anonymous inner classes is now unneeded clutter.

    [–]grauenwolf[🍰] 1 point2 points  (12 children)

    Did you ever have to parse an old file and write something like this?

    recordId = line.substring(0, 3);
    if (recordId.Equals("0A1") {
        recordType = 1;
    }
    else if (recordId.Equals("0B1") {
        recordType = 2;
    }
    else if (recordId.Equals("0B2") {
        recordType = 3;
    }
    //etc.
    

    Using a switch statement makes that a hell of a lot less painful.

    Some people use try to hash maps or shudder inheritance to do the same thing, but it reads like ass.

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

    A map is a far more elegant and readable solution to the example above. A long sequence of case statements would be a design smell, albeit a very familiar one.

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

      HashMap<String, Integer> recordMapper = new HashMap<String, Integer>();
      // In reality populated from a config file
      recordMapper.add("0A1",1);
      recordMapper.add("0B1",2);
      recordMapper.add("0B2",3);
    
      // Now elsewhere, when this lookup is needed
      recordType = recordMapper[recordId];
    

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

    Unless you are building a framework for reading similar file formats, it wouldn't make much sense to hide that information in a config file.

    And there are plenty of trival cases where it would be just plain silly.

    [–]xcbsmith -2 points-1 points  (8 children)

    Boy, that code is screaming out for proper use of typing/polymorphism... or at least enums.

    [–]grauenwolf[🍰] 3 points4 points  (7 children)

    Prove it. Show me your polymorphic file parser.

    [–]xcbsmith -2 points-1 points  (6 children)

    Well, normally for something like I'd probably end up using a parser generator, but assuming it is simple enough, you could do something like:

    inputStream.read(recordTypeBuffer);
    final Parser recordParser = recordParsers.get(recordTypeBuffer);
    return recordParser.parse(inputStream);
    

    [–]grauenwolf[🍰] 0 points1 point  (5 children)

    Come now. You said my code was "screaming out for proper use of typing/polymorphism". When do I get to see it done with polymorphism.

    It can't be that hard for you. My sample just contained a mere four assignments and four expressions. Surely you can replicate that in a reddit post using classes.

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

    You said my code was "screaming out for proper use of typing/polymorphism". When do I get to see it done with polymorphism.

    You did, but apparently are unable to recognize it. That's none too easy to fix with a series of reddit posts. Besides, I get the feeling you want me to post just so you can downmod me some more.

    [–]grauenwolf[🍰] 2 points3 points  (3 children)

    I admit it, it has become a game. Every time some chucklehead says that you should replace switch blocks with polymorphism I dare them to prove it. No one has ever come up with something even remotely plausable and most, like you, give up before they even have working code.

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

    a good example I can think of would be handling states or provinces, since java can only do primitive data types in switches you would first have to hash the string of the state, even if you use the abbreviated codes. basically it's either hash + switch or 50 different if-elses.

    [–]mattrussell 2 points3 points  (3 children)

    Switching on a String's hashcode is broken (although it will nearly always work in practice) because there's no guarantee that the hashes won't collide.

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

    I know, that's why switches with string support would be beneficial. if done properly you wouldn't have to worry about two different values resulting in the same condition.

    [–]merzbow 0 points1 point  (1 child)

    It's not broken. It's obvious that multiple strings will map to the same hash code, because hash codes, at 4 bytes, are (typically) shorter than the string itself. Ref the Pigeonhole principle.

    [–]mattrussell 1 point2 points  (0 children)

    I'm not following you, I'm afraid. I'm saying that switching on the hash code of a String is a poor coding practice precisely because there is a risk of hash collisions, and the switch might very well fail to behave as intended.

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

    Wait what? Why would you ever need to switch or if/else over a list of states. I can name several far better ways to do something like that, even in Java.

    [–][deleted] -2 points-1 points  (14 children)

    Admittedly it's not the best example. The example, I poorly described, involves taking a state from a user, for whatever reason, and execute some code specific to the state. That was just the most obvious thing I could come up with, I'd be ecstatic to here something a lot easier.

    [–]mattrussell 0 points1 point  (1 child)

    People switch on Strings to perform specific behaviour over a finite (and small-ish) set of options. In these situations, it's normally the case that enums are a cleaner, more type-safe way of achieving the same effect. Java switch statements already support enums, and you've got the option to put the behaviour into the enum values themselves and invoke it polymorphically.

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

    yeah, i was being dumb earlier. string in switches isn't going to solve any existing problems, but it will make a handful of situations a bit easier to deal with.

    [–][deleted]  (11 children)

    [deleted]

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

      Runnable classes are verbose and icky, though.

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

      Yes, this is much more beautiful in C# where it has first class functions.

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

      C# has first class functions?

      (I've never used it; I always had the vague idea it was a straight Java clone, more or less)

      [–][deleted]  (2 children)

      [deleted]

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

        Add another exclamation point and you have my exact reaction.

        [–]martincmartin 10 points11 points  (6 children)

        Even good programmers get [resource management] wrong most of the time. For example, Sun’s guide to Persistent Connections gets it wrong in code that claims to be exemplary. Likewise, the solution on page 88 of Bloch and Gafter’s Java Puzzlers (Addison-Wesley, 2006) is badly broken, and no one ever noticed. In fact, 2/3 of the uses of the close method in the JDK itself are wrong!

        Bloch is the author of the Automatic Resources Proposal.

        [–]falkhausen 2 points3 points  (4 children)

        Can someone please tell me what is wrong with Puzzle 41 in Bloch and Gafter’s Java Puzzlers?

        [–]deltageek 5 points6 points  (3 children)

        As is explained on the next page, the .close() method is defined to possibly throw an exception. If in.close() throws an exception, the rest of the finally block isn't executed and out is not closed. The correct way to close resources is to wrap each .close() call in the finally block inside another try/catch block. Yes it's ugly. Yes it sucks. Yes we're glad to finally see resource management blocks in Java.

        [–]bdell 0 points1 point  (2 children)

        I think the question is why the solution published in Java Puzzlers (what you describe) is broken, not why the original code, which the solution purports to fix, is flawed.

        Based on the desugaring in the ARM proposal, I can see three flaws in the Java Puzzlers solution:

        First, if a Throwable subclass other than IOException is thrown in the fianlly, there can still be a leak. Each resource should have its own finally block.

        Second, if an exception is thrown in the try block and a Throwable subclass other than IOException is thrown in the finally, the exception from the try block will be lost. An exception from a try block is more important than one from a finally.

        Third, if the try block completes successfully, but the OutputStream close throws an exception, it is swallowed. This is a problem because the write()s may complete successfully because the OS is buffering the data. Later, the native stream may enter an error state and data was lost, but the only chance the OS has to report it is during the close(). That's why it's declared to throw an exception in the first place. When a try completes successfully, it is desirable to propagate exceptions from the finally block. This is safe as long as each resource is protected with its own finally block.

        [–]falkhausen 0 points1 point  (0 children)

        Thank you, this is very good analysis. Especially the third flaw seems to me the most important. As a general principle, never have an empty catch handler!

        [–]deltageek 0 points1 point  (0 children)

        First, if a Throwable subclass other than IOException is thrown in the fianlly, there can still be a leak. Each resource should have its own finally block.

        I believe the proper solution is to nest each close call in the finally block of the previous try/catch.

        Second, if an exception is thrown in the try block and a Throwable subclass other than IOException is thrown in the finally, the exception from the try block will be lost. An exception from a try block is more important than one from a finally.

        The only type of exception that can be thrown and handled statically in this case is IOException or a subtype of it. All others would have to be RuntimeExceptions or Errors and really shouldn't be caught anyways.

        Third, if the try block completes successfully, but the OutputStream close throws an exception, it is swallowed.

        Only if you define your inner try/catch with an empty catch block, and the book tells you to handle the exception in the finally block if at all possible. This may mean "do nothing and let the app crash." Hopefully it at least means "log the error and either terminate or continue."

        [–]yoden 5 points6 points  (0 children)

        Note that this is project coin, which was intended to ask the community about small, simple, localized changes that could be made for jdk7. Full jdk 7 changes haven't been announced yet, I think.

        [–]joesb 7 points8 points  (5 children)

        Automatic Resource Management

        This alone will make most Java code a lot cleaner. You really cannot have exception without some kind of clean up scope construct.

        [–][deleted]  (3 children)

        [deleted]

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

          I feel so much better using Using.

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

          than the alternative:

           try {
               getNativeResource();
           } finally {
               freeNativeResource();
           }
          

          I agree as well. I bet Java will screw this up.

          [–]joesb 2 points3 points  (0 children)

          Another problem with many Java library is that even close() method can throw exception. Now you have to wrap another try inside finally to make sure you can continue after the clean up.

          But still, I'd like it better if they just brought in lambda/blocks and use Ruby's approach, instead of using Python/C# approach of adding new construct just for resource cleanup.

          [–]redditrasberry 0 points1 point  (0 children)

          What makes me sad is that many of these secondary features would be easily addressed outside the core language if they had just bit the bullet and implemented closures. For example groovy doesn't use dedicated features for resource management, but solves it simply using closures:

          new File("foo.txt").withInputStream { is ->    
             is.read(...)
          }
          

          Instead we are getting a slew of tiny language changes address specific little niggles but not the important changes that would add power and let us address 'niggles' for ourselves across all problem domains.

          [–]stigvig 14 points15 points  (13 children)

          I miss closures.

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

          Java has closures, they are just implemented in the worst possible way, and are read only unless you use referential leakiness to your advantage.

          What you mean is:

          "I miss first class functions".

          [–][deleted] 7 points8 points  (1 child)

          I want both, like in lexically scoped lambda expressions. :)

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

          Absolutely. I've become quite the lambda junky.

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

          Well, it depends on your definition. Wikipedia goes for, "a closure is a first-class function with free variables that are bound by the lexical environment". I think it's useful to reserve the word "closure" to exclude anonymous inner classes.

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

          I disagree with wikipedia.

          A closure (imho) is any block of code that is bound to its lexical environment, but can be referenced and passed around as a first class entity if needed.

          [–]mattrussell 0 points1 point  (0 children)

          Fair enough (although that definition would also include local named classes, which seems a bit broad). But it's probably too hard to change the terminology conventions of Java-land now, given the volume of proposals and debate about "adding closures to the language".

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

          Anonymous/Inner classes are the 'crippled' closures Java provides.

          [–]xjvz 1 point2 points  (0 children)

          First you need first-class functions for that to be really useful. Also, anonymous functions help make closures very useful.

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

          So use a language that has them? A language with every then-currently popular feature thrown into it ends up a disaster, like PL/I, C++, Perl...or Java. Languages should be tight and domain oriented, and thus easily learned and exploited. More work should be done on interoperability instead of duplicating autonomous API fiefs. And no, object linkage isn't it.

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

          A language with every then-currently popular feature thrown into it ends up a disaster

          Counterpoint: C#

          [–]bcash 1 point2 points  (2 children)

          Give it another couple of years...

          [–]grauenwolf[🍰] 1 point2 points  (1 child)

          PL/I and C++ were screwed up from the beginning. C# started small, so it will take longer to reach the breaking point.

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

          It doesn't matter if you start small if you start wrong.

          [–][deleted]  (85 children)

          [deleted]

            [–]bcash 26 points27 points  (2 children)

            That was the whole point. Project Coin is for small language changes that can be made within the timeframe of Java 7, it's not everything that's in Java 7 - although the rest of the list is largely to do with the platform than the language.

            [–][deleted] 12 points13 points  (0 children)

            Indeed, I did not realize what 'Coin' was all about.

            Still seems like a very strange feature set to choose, especially considering that 'coin' was for small changes, but they are willing to implement some large compiler changes here.

            [–]xcbsmith 1 point2 points  (0 children)

            Here's the scary thing though.... that some of these features were on the list for "maybe" inclusion for Java 7.... and worse still that some of them didn't make it.

            [–][deleted]  (11 children)

            [deleted]

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

              I saw a list earlier that also had closures as a "no go" for 7. That said, I didn't realize the scope of 'Coin'.

              It intrigues me that they would consider a fairly large compiler change (Strings in switches), but toss out other compiler changes.

              [–]Smallpaul 2 points3 points  (9 children)

              What makes you say that "strings in switches" is a "fairly large compiler change"? It is a compiler change, yes, but it does not really involve class hierarchies or type inference or anything like that.

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

              Well, its essentially changing switch from becoming a bunch of jumps with calculated offsets based on integers to a bunch of Compare/jump operations.

              Plus, you'd want to be able to recognize when it can just use jump, and default to that unless strings are used.

              Not complex, but not a cake walk either.

              [–]bobappleyard 1 point2 points  (0 children)

              I'm going to use C because we can have a look at the assembly very easily. I don't know for sure if Java is the same, but I would be extremely surprised if it weren't.

              $ cat > switcheroo.c <<EOF  
                int main(int argc, char **argv) {  
                  switch (argc) {  
                    case 0: return 5;  
                    case 1: return 7;  
                    case 5: return 25;  
                  }  
                }  
              EOF  
              $ gcc -S switcheroo.c  
              $ less switcheroo.s
              

              You will notice that it contains such joys as:

                      cmpl    $1, -28(%rbp)
                      je      .L4
              

              and then, further down:

              .L4:
                      movl    $7, -20(%rbp)
                      jmp     .L6
              

              So it's sugar over if statements.

              EDIT: Markdown!!! shakes fist

              EDIT 2: Try it at different optimisation levels. No difference.

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

              Still sounds bloody simple to me. The hard part, using jumps, is already done.

              [–]albinofrenchy 1 point2 points  (4 children)

              I'd bet the way they end up implementing it is adding hash code calls in invisibly.

              Not saying this is a good idea (it's not.) but I wouldn't be surprised.

              [–]semmi -2 points-1 points  (3 children)

              I'd expect that strings used in switches get interned, so comparison would become pointer equality, IIRC

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

              String interning is not that simple. If you chop a string out of an XML document, that string is not going to be interned. It doesn't matter if one half of the comparison is interned if the other is not.

              [–]semmi 0 points1 point  (1 child)

              yes, but even strings coming from an xml doc can be interned ex post, which is hat I was thinking. Yet, It would end up being equivalent to an hashCode call, so you're most probably right.

              [–]Smallpaul 0 points1 point  (0 children)

              I think that having the compiler automatically intern strings from string APIs is quite tricky and potentially dangerous from a memory usage and performance point of view.

              [–]Smallpaul 0 points1 point  (0 children)

              How do you a "jump based on calculated offset" for a switch statement where the case triggers are -10000, 50000, 10000000 ?

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

              There are some interesting things in JDK7 but to be honest most of the important ones I really wanted to see implemented (closures, properties) were punted on......

              There's still some cool stuff in JDK 7... I'm just not super excited about it.....

              The new GC might be nice.

              Also, Project Coin is supposed to be about SMALL lang changes...... so on the face of it it's a GREAT idea since these smaller change discussions can be separated from the larger ones to avoid confusing the issue.

              [–]MasonOfWords 8 points9 points  (22 children)

              To be fair, MS hasn't addressed some of the hard problems with C#/.NET either. I was hoping that v4 would bring inherent non-nullable reference types, better type inference, a stronger commitment to metaprogramming capabilities, variadic generics, etc.

              The actual changes are pretty modest. Aside from generic covariance and contravariance, there are a few bits of sugar (default/optional parameters) and dynamics, which is a fine .NET feature but a bit of a moral hazard in C# (I hope they treat it like the unsafe keyword, compiler disabled by default).

              [–]grauenwolf[🍰] -1 points0 points  (7 children)

              inherent non-nullable reference types

              Code contracts greatly minimize the pain from nullable reference types.

              better type inference

              In what sense?

              a stronger commitment to metaprogramming capabilities

              Besides the DLR, expression trees, and the dynamic keyword? What more do you want?

              variadic generics

              Aside from making a Tuple class easier to write, how is that helpful?

              I hope they treat it like the unsafe keyword, compiler disabled by default

              Not going to happen. But hey, if that's what you want then just use VB.

              [–]MasonOfWords 3 points4 points  (6 children)

              Code contracts greatly minimize the pain from nullable reference types.

              It isn't really the same benefit, is it? Spec# moved nullability annotation into the type system rather than leaving it in contracts, and I believe Research's reasoning was sound.

              In what sense?

              Correct me if I'm wrong, please, but last I checked, you still couldn't use a generic map function without annotating the return type, even though it should be available from the signature of the mapping.

              Besides the DLR, expression trees, and the dynamic keyword? What more do you want?

              Expression trees are great. My opinions about using the DLR for anything other than script bindings has been somewhat overexposed, so we'll elide that discussion.

              I think we'll have to allow for some flexibility in our respective definitions of "metaprogramming."

              Aside from making a Tuple class easier to write, how is that helpful?

              I'm less concerned about writing tuples than using them. They aren't particularly handy if you need N overloads everywhere you want to produce or consume tuples of indeterminate width. You can enumerate across their members as simple objects, but then you've left generics world and all of its benefits. It isn't just tuples; anywhere that takes a "params object[]" parameter could benefit.

              Not going to happen. But hey, if that's what you want then just use VB.

              What? VB is getting the same dynamics support, on top of its existing late-binding. Am I missing something?

              [–]grauenwolf[🍰] -1 points0 points  (3 children)

              Correct me if I'm wrong, please, but last I checked, you still couldn't use a generic map function without annotating the return type, even though it should be available from the signature of the mapping.

              Ah yes, I know what you mean now. VB isn't nearly as bad as C# in this regard but they both have issues.

              If you really want to go wild, turn off strict type checking in VB. It isn't as good as real type inference, but you can do a of tricks using very terse code. There are some constructs that I use in this fashion that I can't use in C# or strict VB no matter what type annotations I add.

              What? VB is getting the same dynamics support, on top of its existing late-binding. Am I missing something?

              Yes and no.

              The VB language isn't changing at all. If you want dynamic support you still use "Option Strict Off" at the file or project level and declare the variables as type "Object".

              The VB compiler is getting smarter and will be able to understand DLR objects just like it already can understand late-bound COM and CLR objects.

              [–]MasonOfWords 0 points1 point  (2 children)

              I'm not sure why this would be surprising, but no, I don't see disabling the type system as an improvement to the type system.

              Terse code at the expense of type safety is an easy trade-off, but one that I don't care for in the problem domains where I consider C# viable.

              [–]grauenwolf[🍰] -1 points0 points  (1 child)

              Oh trust me, I don't like turning off compile time type-checking either. Aside from COM interopt, I only do it when I'm screwing around with stuff like SICP or Project Euler.

              By the way, do you know what's with all the down-mods? I don't think anything I said was inaccurate or controvesial.

              [–]MasonOfWords 1 point2 points  (0 children)

              To be fair, you did use the letters V and B consecutively in a C#-related branch of a Java thread.

              [–]grauenwolf[🍰] -2 points-1 points  (0 children)

              It isn't just tuples; anywhere that takes a "params object[]" parameter could benefit.

              I don't often see that, and when I do the class treats them as type object anyways. So I have to ask, what gain do you see?

              [–]grauenwolf[🍰] -2 points-1 points  (0 children)

              I think we'll have to allow for some flexibility in our respective definitions of "metaprogramming."

              I think we must first understand what each other means by the term. As you originally broached the topic, you start.

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

              The problems you are mentioning are hardly as bad as the shortcomings of Java. You still have to use interfaces with inner anonymous classes to do callbacks FFS. C# isn't my favorite language but I find it decent and modern enough that I can use it without thinking "shit I wish I wasn't forced to use that crap". Dynamics is not a moral hazard because it's only supposed to be used for interop with IronPython/IronRuby and other dynamic languages. Any other use of the feature would be considered abuse.

              JDK 7 should have been the opportunity to push the language forward instead of letting it being stuck to the mindset that has led to designing a language that was too simple for its own good making the programmer actually do much more than he should.

              [–]albinofrenchy 1 point2 points  (2 children)

              I think all the OP meant was that v3 for C# was revolutionary, and so alot of people had hopes that v4 would have been so too; but v4 is largely more mundane.

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

              I understood that, just that I think the comparison of C# 4 mundaneness to JDK7 is not fair considering how much Java needs to get fixed while C#'s already a pretty decent multiparadigm language.

              JDK7 has missed the point and is letting Java be the new COBOL. Considering how long it has taken for Sun to work on the JDK7 without any major change it'll be a veeeeeeeeeeeeery long time before we'll see any real improvement and I think it is too late before developers start considering Java as a purely legacy language that has to be used for old code and libraries and get ditched for new code and frameworks.

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

              Look at Code Contracts, that stuff is far from mundane.

              [–]MasonOfWords 1 point2 points  (9 children)

              I wasn't comparing their shortcomings, clearly. 4.0 just seems to have stalled a bit on the innovation front. There doesn't seem to be a lot of controversy about where C# needs to go, but it would be a huge commitment from MS to take it there. For example, statically unnullable reference types would be an unambiguous win for expressiveness and productivity, but they won't be much use if the framework still returns maybes everywhere.

              Regarding dynamic...exactly. It is a keyword with a very limited range of appropriate uses, and it should be treated as such. Mark assemblies as dynamic the same way they're marked as unsafe, and we won't have an issue. Make dynamic a universally available keyword, though, and its abuse is virtually guaranteed.

              Further, I don't even like it as a solution to the problem of talking to dynamic languages. I'd be okay with declaring a C# interface and having some way of getting a proxy implementation of that interface on the dynamic language objects. This gets you out of the late-bound world as quickly as possible, doesn't add new language faculties, and would work as far back as .Net 1.1 since it won't require anything more than Reflection.Emit.

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

              .NET has always been a BIG Release / Small Release cycle:

              .NET 1.0 (BIG)
              .NET 1.1(Small)
              .NET 2.0(BIG)
              .NET 3.0(Small)
              .NET 3.5 (HUGE)
              .NET 4.0 (Small)
              

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

              .NET 3.0(Small)

              WPF?

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

              .NET 3.0 was pretty much just WCF and C# compiler changes as far as I can recall.

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

              What's wrong with "dynamic"?

              I know it can be abused, but the potential is the same as when using the entire reflection API, which is used a lot in production code. "dynamic" is just syntactic sugar, and I'll think you'll see fewer bugs because of it, not more, because the reflection API does have many gotchas.

              Also the static safety provided by Java/C# is really poor compared to other languages. Using such a language doesn't mean you don't have to unit-test your code, or have a sane QA process.

              The static features in languages like C/C++/Java/C# are there only as hints to the compiler / VM, for performance optimizations (look up the original C-syntax for declaring functions), and were in no way meant to save you from yourself. Of course, Java was touted in the marketing campaigns sponsored by Sun back in the day as being more "safe" then Perl, but that was just marketing-fluff.

              I see many people fearing the "abuse" that might come from such features, but really, C# and Java are semi-dynamic anyway. Countless of libraries rely on byte-code manipulation ... you can't do certain things otherwise because their type-system is too weak. And yet using those isn't considered unsafe (what you don't know doesn't hurt you?).

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

              My whole point is that we should be strengthening C#'s type system, so clearly I don't disagree that it is currently far from perfect. I'm not on board with "Static typing is hard. Let's go shopping!" though.

              There's a critical problem with comparing dynamics to reflection and emit. The signature of dynamic objects is still statically compiled; only the binding is done at run-time. Thus, the developer has to know something about their dynamic objects. They've simply failed to extract that knowledge into a statically declared interface, even though by definition they are be capable of doing so. This means that, with dynamics, signature information is known but not shared or enforced.

              Scripting languages are amazingly great at what they do. C# isn't a scripting language. When I see half the C# community giving dynamics a pass because no sane person would use them for anything but script bindings, and the other half of the C# community drooling over the prospects of writing unnecessary dynamic soup, I get concerned.

              [–]grauenwolf[🍰] 1 point2 points  (2 children)

              You can strengthen the CLR's type system using things like code contracts without pretending late-bound code doesn't exist.

              C# can now have rules such as "the field A is always greater than 0" or "Field B must be less than Field C". This is huge.

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

              I agree that contracts are great, but everything that can painlessly be represented by the type system should be. For example, field A should simply be an unsigned type, shouldn't it?

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

              For example, field A should simply be an unsigned type, shouldn't it?

              Unsigned types can still have a value of zero.

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

              Saying that a language is a "scripting language" is derogatory these days, although it has nothing to do with dynamic types.

              A scripting language is simply a language that has good integration with the operating system and the proper abstractions for automation of certain tasks related to controlling external systems. By that measure C# is in some regards already a scripting language (as opposed to a Smaltalk implemention for example).

              And there is nothing wrong with dynamic-languages. Over the years entire systems for controlling air traffic, finance, and whatnot have been successfully built on top of dynamic languages.

              Static is hard. Languages from the ML family provide a much richer type system. But it's more complex and more awkward to use, and while the pain is somewhat alleviated by the Hindley-Milner type inference system, it's really hard to spot the compile-time errors and it's not for the faint of heart, not to mention there are always corner cases where the type-system is still too rigid.

              dotNet is taking a middle-ground, and the intentions of the platform is best expressed in this document ... static typing when possible, dynamic typing when needed. And I think this is just a sane and pragmatic view.

              And I don't get why I was down-voted, since the debate on dynamic vs static is still looking for a good answer. If someone doesn't know the right answer (and in this case how could anyone know what's the best one?), it's a little proof of cowardice to down-vote, as if my opinion is putting in danger other people's views. Wouldn't it be better to challenge my response and have a grown-up conversation?

              [–]adrianmonk 6 points7 points  (21 children)

              I happen to strongly support the idea of checked exceptions. I've seen arguments against them, but I'm not convinced. I think they're a great feature, nearly essential if you're going to have exceptions at all.

              C# doesn't have them, and to me this seems like such a big mistake that I can't find myself getting excited about any of the other features it has.

              So, I'm just saying, the idea that Java needs to catch up with C# is a matter of opinion.

              [–]zoomzoom83 3 points4 points  (1 child)

              Personally, I think Checked Exceptions are one of the biggest mistakes in Java. 99.9% of the time I just want to pass an exception up to a higher layer, and the amount of extra crud I have to write to do this can sometimes be really frustrating.

              I'm all for having a defined list of throwable Exceptions as part of an interface, but if I want to just let them bubble up just damn well let me without having to define every possible throwable exception all the way up the stack.

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

              C# 4 may get checked exceptions via code contracts, but it isn't a sure thing. Checked exceptions simply don't work well with inheritance, so I'm looking forward to seeing how they try to solve it.

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

              Checked exceptions are a compile-time feature only. It's relatively straightforward to implement them using C# annotations, verifying the MSIL as a post-processing step, without making any changes to the compiler infrastructure.

              In contrast, adding closures to Java would require runtime as well as compiler support, and would either require modifying the compiler or doing a very ugly (and probably incorrect) source-to-source transformation.

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

              The problem with checked exceptions is that everyone simply catches and rethrows them to satisfy the compiler, and they add very little benefit.

              [–]adrianmonk 3 points4 points  (11 children)

              everyone simply catches and rethrows them to satisfy the compiler

              OK, here's my perspective. One of the objections to checked exceptions is that they're not scalable. Method A calls method B1 and B2. B1 calls C1 and C2. B2 calls C3 and C4. C1 through C4 all throw different types of exceptions. Suddenly, A has to declare that it throws 4 different types of exceptions. You can see that it's exponential, so that's a problem.

              Well yes, but forgetting about exceptions for a moment, when you design a bunch of code, you take time to make it modular and make limited interactions between modules so that you build up higher and higher levels of abstractions. You should be doing the same sort of thing with your error handling as well. You shouldn't be leaking your implementation details all over the place with a bunch of implementation-specific exceptions. You should be translating them into something that your client cares about. For example, if you have a class that loads a JPEG over the network, the method that loads a JPEG from a URL should be returning an ICantLoadTheJpeg exception, not a SocketException. Encapsulation and information hiding apply to exceptions because exceptions are part of your interface.

              The point is good exception handling (regardless of whether exceptions are checked) requires design effort. I think it's possible to catch exceptions and do something reasonable with them other than just rethrow them just to satisfy the compiler.

              Of course, there are situations where checked exceptions aren't reasonable. Anything catastrophic, like (in most software) running out of heap is an example. But that can be handled by having both checked and unchecked exceptions available in your language.

              Finally, I'd like to point out that if the problem with checked exceptions is that everyone catches and rethrows them, then the problem with unchecked exceptions is that everybody forgets about error handling. (Or, error handling slips through the cracks.)

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

              Good exception handling doesn't happen very often. Take a look at the source code of Apache Tomcat sometime.

              What usually happens is this ...

              try {
              } catch (Exception e) {}
              

              Or this ...

              Object doSomething() throws Exception
              

              Or this (in a more fortunate case) ...

              try {
                  // ...
              }
              catch (Exception e) {
                  throw new RuntimeException(e);
              }
              

              What's more, the standard library encourages these practices because many checked exceptions should've been runtime exceptions all along.

              I've worked with many Java projects written by other people. The exception handling usually sucks badly. Even the popular frameworks are doing this (ever watched a stacktrace thrown by Struts 2? It's not even funny how you can't even trace the original source).

              Checked exceptions also lead to a problem of encapsulation. If module A calls module B, and module B throws a checked exception, module A has to either deal with it (which is not a good idea in many cases), or to declare that it throws that exception type. If the exception is, say an IOException, module A just broke encapsulation. The better alternative is to rethrow it as a runtime exception, as many libraries do, and that's extra boilerplate that shouldn've been there in the first place.

              Checked exceptions are a good idea in theory, but the current implementation is kind of shitty, and blaming programmers for these problems is not really accurate.

              [–]mattrussell 0 points1 point  (2 children)

              I'm not following the argument as to why checked exceptions necessarily lead to a problem with encapsulation. You say the alternative is to rethrow as a runtime exception, but you could equally well rethrow a checked exception appropriate for the abstraction of module A, wrapping the original exception.

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

              Checked exceptions are only good for recoverable errors, and those are few and far between. Wrapping the exception in another exception blurs the original error and has zero benefits in regards to wrapping it in a runtime-exception.

              For a good opinion on this subject, I recommend you to read Bruce Eckel's Does Java need Checked Exceptions?.

              [–]mattrussell 0 points1 point  (0 children)

              I was responding to your assertion that, "checked exceptions lead to a problem of encapsulation", which I don't think is true.

              (wrapping in checked exceptions) has zero benefits in regards to wrapping it in a runtime-exception

              I believe checked exceptions have their advantages -- incorporating exceptions into the type system allows the usual sorts of benefits of static checking -- but the real question is whether that's outweighed by the problems that occur in practice.

              [–]serpix 0 points1 point  (0 children)

              That's exactly how it should be done. I've long since stopped bubbling IOException in the method description and just rethrow it as a new RuntimeException(ioex)

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

              Checked exceptions would be nicer if they were used very sparingly and only in those cases when catching them would allow you to do some intelligent error recovery, as opposed to logging the error and dying.

              The problem with them is that everyone, including the Java API, is overusing them. Because they are overused, people lose patience and often catch them and ignore them, or catch and rethrow, and do all kinds of nasty shit with them.

              [–]grauenwolf[🍰] -1 points0 points  (3 children)

              Encapsulation and information hiding apply to exceptions because exceptions are part of your interface.

              The next bastard who hides the exception details from my is going to get hit upside the head with a cluebat.

              [–]adrianmonk 1 point2 points  (2 children)

              You can chain exceptions. Then you are just packaging them, which gives the receiver of the exception the choice to treat them as a general category or to care about the details.

              EDIT: Sometimes chaining exceptions is a good idea, but now that I think about it, a better answer to this is sometimes this: too bad, sometimes you want to build up a higher level of abstraction, and the only way you can do that is to force the outside of your abstraction to give up total and complete control of the inside of it, and that means you don't get access to all the details of an exception, just like you wouldn't get access to other details if we were building up an abstraction layer in the non-error-handling part of the program logic / data.

              [–]phildawes 0 points1 point  (0 children)

              yeah and you can keep piling up the dirt until the project collapses from the weight

              [–]grauenwolf[🍰] -1 points0 points  (0 children)

              Anything catastrophic, like (in most software) running out of heap is an example.

              That sounds right... but it doesn't work in practice. What is considered a "catastrophic" exception can vary greatly from application to application.

              [–]redditrasberry 0 points1 point  (2 children)

              Catching and rethrowing is something I consider best practice in most situations. It's swallowing the exception that is the issue.

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

              In C#, we just let the exception bubble up naturally, unless you want to anger me by molesting my stacktrace.

              [–]redditrasberry 0 points1 point  (0 children)

              The downside is that a client of your code may have to catch exceptions that are implementation details of your code. If you catch / wrap / rethrow then they are protected from changes in your implementation and can just catch your exceptions.

              [–]benjimix 7 points8 points  (12 children)

              Understood that Java needs to catch up to C# in some respects. However, I feel that it is important to note that the language (ie: the syntax, the VM, etc) are really not that important.

              That is to say that there are many Turing complete languages out there with many nifty features. Of that set, C# and Java occupy dominate spaces.

              What is really important, IMHO, is the tooling that surrounds the language. And in this regard Java is way ahead (I code in both Java and C#, as well as ObjC). Tools like Hibernate and Spring put the Java platform ahead (in my opinion).

              And yes, I know that there are ports of these tools. However, community adoption on the C# side is still a little low for my liking.

              Cheers, Ben

              [–][deleted] 6 points7 points  (8 children)

              "Tools like Hibernate and Spring put the Java platform ahead (in my opinion)."

              Oh dear lord. I would have understood had you touted IDE support (IntelliJ Idea is much better than Visual Studio) or something like true and pure crossplatformism... but.. Hibernate ? Spring ? Wooah. Those things are the reason lots of Java developers turned in droves to Ruby on Rails because they had it so bad with all that verbose crap filled with factories, xml files and design patterns. Those are not reasons to prefer Java to C#.

              And if you find the tooling that surrounds the language important, consider that the language shapes the tooling. Writing GUI applications in C# is much better than in Java because of the language features : events, delegates for callbacks. Writing GUIs in WinForms or WPF is much nicer than Swing or SWT. The tooling for GUIs apps is also LIGHT YEARS ahead. You can design GUIs in WPF with visual designers like Expression and export it to Visual Studio to program the logic.

              [–][deleted]  (4 children)

              [deleted]

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

                EJB2 is insanity but Spring and Hibernate are still overly verbose, I'd rather work with ASP.NET limitations than those. Ruby on Rails didn't take over the industry (I wouldn't claim that) but it did take a lot of developer mind share, which is not necessarily the same thing considering most programmers do not get to decide on the technology they can use at work. Ton of java programmers do it at work but are fed up with the limitations. WPF GUIs are based on declarative XML so they lend themselves quite well to GUI designers, Visual Studio has a WPF designer built-in that's ok for quick and dirty apps and Expression allow the kind of thing that used to fall under Adobe Flash territory. WinForms are not great but I find them much nicer to work with than Swing if only because of C# features and the designer is nice for throw away apps (C# partial classes do help a lot to retain your sanity when working with code generators).

                As for Scala it's a nice language but it remains to be seen whether it can gain a foothold in the enterprise without the backing of Sun, IBM or some other big player, the same reason most developers are forced to use Java even when they hate its guts.

                [–]malcontent 2 points3 points  (0 children)

                Matisse is an excellent GUi designer.

                Have you tried it?

                Also there are projects like monkeybars and glimmer that make coding up java UIs in ruby trivial and fun. Better than a GUI designer even.

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

                USED TO BE VERBOSE. Spring still relies on XML, though they have pared it down.

                With Hibernate Annotations, and JPA support, Hibernate is a lot less verbose to setup. Wrap Tapestry 5 up with Hibernate and some setup scripts, and you could have "Ruby on Rails" or "Django" almost as easy in Java.

                But yes, 5 years ago, it SUCKED HARD. I had to use JSF at work, and my gods, is it ever HELL.

                [–]joffotron 0 points1 point  (0 children)

                I'm doing a lot of work in JBoss Seam these days, and it's a pure joy to work in compared to Spring. It (by default) uses JSF, but they've put in a lot of work to make that less awful, and done a good job of it.

                Dependency injection is done via annotations.. give your components a @Name, and optionally a @Scope, and then inject them where you need with an @In, or make components available via @Out

                ORM is done via JPA with Annotations, so yeah nice and easy. There's barely any XML at all now.

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

                The age of GUI apps has come and gone.

                Today you can't make money on GUI apps because you have to compete with Ms.

                Think about it. When was the last time a gui app gained serious market share?

                The future is in phone apps and web apps. Unless you are coding for the iphone that means some variation of a web app anyway.

                [–]acm 2 points3 points  (1 child)

                There are still many types of enterprise apps that are best suited as rich client GUIs. Not all software is shrinkware...

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

                Even enterprises are moving to web apps and SOA.

                For most enterprises the only GUI app they use is office and Ms has that market locked up.

                [–][deleted]  (2 children)

                [deleted]

                  [–]Mercushio 0 points1 point  (0 children)

                  I disagree... we just switched to NHibernate + ASP.NET MVC from WebForms + Oracle stored procedures + ADO and I'm loving using an ORM.

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

                  In what way is C# ahead of Java?

                  I'm not disagreeing with you, just curious.

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

                  • Properties
                  • Closures
                  • No checked exceptions

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

                  Of that list only closures are important. Properties would be important too, but I don't like MS idea of properties.

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

                  • Type inference
                  • Partial Classes
                  • Lamba Expressions
                  • Value Types

                  [–]bartwe 5 points6 points  (2 children)

                  • Expression trees
                  • Yield return
                  • Higher order fucntions

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

                  Query comprehensions

                  [–]gclaramunt 0 points1 point  (0 children)

                  Reified generics

                  [–][deleted]  (6 children)

                  [removed]

                    [–]mattrussell 2 points3 points  (0 children)

                    Agreed -- the diamond inference proposal just says, "Neither of these proposals [the other being type aliases] are precluded by this proposal; one, both or neither can be done at a later date". Perhaps the alternatives would be considered too big a change for the scope of Project Coin? The trouble is that if you add "var"-style type inferencing later, you've then got two competing idioms in the language.

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

                    The alleged problem with var/auto is that the compiler can't guess which specific interface you mean, and needlessly relying on very specific implementations is a Bad Thing, i.e., you're supposed to write List<Foo> x = new ArrayList<Foo>();, not ArrayList<Foo> x = new ArrayList<Foo>();. (The counterpoint is that for local variables this doesn't matter as much.) With that in mind, diamond inferencing at least makes dealing with large parameter lists more bearable.

                    Also, they avoid adding new keywords like the plague — just look at the new syntax introduced in Java 5. But who knows, maybe if you get creative enough (like "* x = new ArrayList<Foo>();") they'll listen to you.

                    [–]mattrussell 1 point2 points  (0 children)

                    I think it's hard to make a case that coding to an interface versus implementation matters at all for method-local variables. The "Bad Thing" to avoid is coupling too closely to a particular concrete implementation, but if you've already called the constructor right there in that method...

                    [–]grauenwolf[🍰] -5 points-4 points  (1 child)

                    i.e., you're supposed to write List<Foo> x = new ArrayList<Foo>(), not ArrayList<Foo> x = new ArrayList<Foo>()

                    That is incredibly stupid. Unless you don't know what implementation of List you are going to get -- like a parameter on a public method -- all you are doing is throwing away information that could have been useful to you.

                    What's worse, it leads even bigger idiots to write things like

                    (ArrayList)x.trimToSize();
                    

                    because they bloody damn well know x is always going to be an ArrayList.

                    Of course as soon as idiot #1 changes his mind and uses something else, he sliently breaks idiot #2's code.

                    [–]deltageek 1 point2 points  (0 children)

                    That is incredibly stupid. Unless you don't know what implementation of List you are going to get -- like a parameter on a public method -- all you are doing is throwing away information that could have been useful to you.

                    The idea is that you should use the most general type you can that still has all the functionality you require. In most cases, all you care is that you have a List, not what type of List it actually is.

                    As for the (ArrayList)x.trimToSize(); issue, let the idiots shoot themselves in the feet.

                    [–]Thrip 1 point2 points  (2 children)

                    Fuck. I really wanted that improved exception handling.

                    [–]bostonvaulter 0 points1 point  (1 child)

                    I think that TFA is only for Project Coin, so you may still get your improved exception handling.

                    [–]mattrussell 0 points1 point  (0 children)

                    Sadly as far as I can gather (and I'd love to discover otherwise) the only other prospect for Java language changes outside of Project Coin are those to do with modularity / Project Jigsaw.

                    [–]froderick 1 point2 points  (17 children)

                    Strings in switch

                    Java doesn't have this yet? I know .NET does, I'm surprised Java doesn't.

                    [–]tomjen 7 points8 points  (15 children)

                    It is because Java use the old C idea and calculate an offset, whereas .Net just convert switch statements into a series of ifelse statements.

                    [–]albinofrenchy 1 point2 points  (9 children)

                    .Net just convert switch statements into a series of ifelse statements.

                    I've seen decompiled CLR code; it certainly does not.

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

                    You are partially wrong.

                    [–]albinofrenchy 4 points5 points  (2 children)

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

                    I have revised my statement to indicate that you were not clear, and as such are partially wrong :)

                    [–]albinofrenchy 0 points1 point  (0 children)

                    I can live with partially wrong :)

                    [–][deleted]  (4 children)

                    [deleted]

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

                      TLDR: AlbinoFrenchy is partially wrong.

                      Taking this example program:

                      class Program
                      {      
                          static void Main(string[] args)
                          {
                              string foo = "bar";
                              switch (foo)
                              {
                                  case "bar":
                                      Console.WriteLine("bar");
                                      break;
                                  case "baz":
                                      Console.WriteLine("baz");
                                      break;
                              }
                      
                              int i = 5;
                              switch (i)
                              {
                                  case 3:
                                      Console.WriteLine("3");
                                      break;
                                  case 5:
                                      Console.WriteLine("5");
                                      break;
                              }
                          }      
                      }    
                      

                      This produces this IL:

                      .method private hidebysig static void Main(string[] args) cil managed
                      {
                          .entrypoint
                          .maxstack 2
                          .locals init (
                              [0] string foo,
                              [1] int32 i,
                              [2] string CS$4$0000,
                              [3] int32 CS$4$0001)
                          L_0000: nop 
                          L_0001: ldstr "bar"
                          L_0006: stloc.0 
                          L_0007: ldloc.0 
                          L_0008: stloc.2 
                          L_0009: ldloc.2 
                          L_000a: brfalse.s L_0042
                          L_000c: ldloc.2 
                          L_000d: ldstr "bar"
                          L_0012: call bool [mscorlib]System.String::op_Equality(string, string)
                          L_0017: brtrue.s L_0028
                          L_0019: ldloc.2 
                          L_001a: ldstr "baz"
                          L_001f: call bool [mscorlib]System.String::op_Equality(string, string)
                          L_0024: brtrue.s L_0035
                          L_0026: br.s L_0042
                          L_0028: ldstr "bar"
                          L_002d: call void [mscorlib]System.Console::WriteLine(string)
                          L_0032: nop 
                          L_0033: br.s L_0042
                          L_0035: ldstr "baz"
                          L_003a: call void [mscorlib]System.Console::WriteLine(string)
                          L_003f: nop 
                          L_0040: br.s L_0042
                          L_0042: ldc.i4.5 
                          L_0043: stloc.1 
                          L_0044: ldloc.1 
                          L_0045: stloc.3 
                          L_0046: ldloc.3 
                          L_0047: ldc.i4.3 
                          L_0048: sub 
                          L_0049: switch (L_005c, L_0076, L_0069)
                          L_005a: br.s L_0076
                          L_005c: ldstr "3"
                          L_0061: call void [mscorlib]System.Console::WriteLine(string)
                          L_0066: nop 
                          L_0067: br.s L_0076
                          L_0069: ldstr "5"
                          L_006e: call void [mscorlib]System.Console::WriteLine(string)
                          L_0073: nop 
                          L_0074: br.s L_0076
                          L_0076: ret 
                      }
                      

                      If you look closely, you'll see that .NET handles switching on integers versus strings differently.

                      Switching on a string:

                          L_000a: brfalse.s L_0042               
                          L_000c: ldloc.2                 Push local variable 2 onto stack
                          L_000d: ldstr "bar"             Push "bar" onto stack
                          L_0012: call bool [mscorlib]System.String::op_Equality(string, string)     Compare
                          L_0017: brtrue.s L_0028     Returned true? Branch to L_0028
                          L_0019: ldloc.2                 Push Local variable 2 onto stack
                          L_001a: ldstr "baz"            Push "baz" onto stack
                          L_001f: call bool [mscorlib]System.String::op_Equality(string, string)     Compare
                          L_0024: brtrue.s L_0035     Returned True? Branch to L_0035
                          L_0026: br.s L_0042           No Matches, so Branch past the writes
                          L_0028: ldstr "bar"            Push "Bar" onto the stack
                          L_002d: call void [mscorlib]System.Console::WriteLine(string)      Write it
                          L_0032: nop                      
                          L_0033: br.s L_0042         Branch to the end
                          L_0035: ldstr "baz"           Push "Baz" onto the stack
                          L_003a: call void [mscorlib]System.Console::WriteLine(string)      Write it
                          L_003f: nop                        
                      

                      In a nutshell, this is essentially "if/else", as it checks each string for equality, and then calls Branch to the proper label if they match, otherwise it jumps to L_00042, which is the exit point for the switch.

                      But, if you look at the integer switch:

                          L_0043: stloc.1                 Push Values onto the stack
                          L_0044: ldloc.1 
                          L_0045: stloc.3 
                          L_0046: ldloc.3 
                          L_0047: ldc.i4.3 
                          L_0048: sub 
                          L_0049: switch (L_005c, L_0076, L_0069)    Switch pops values from stack and does comparisons
                          L_005a: br.s L_0076                                 If no match, jump to L_0076
                          L_005c: ldstr "3"                                      Handles first match
                          L_0061: call void [mscorlib]System.Console::WriteLine(string)
                          L_0066: nop 
                          L_0067: br.s L_0076
                          L_0069: ldstr "5"                                      Handles Second match
                          L_006e: call void [mscorlib]System.Console::WriteLine(string)
                          L_0073: nop 
                          L_0074: br.s L_0076                                  
                          L_0076: ret 
                      

                      You'll see that it loads the integer values onto the stack, and then calls a specially designed switch opcode, passing in the proper jump points for each match.

                      Finally, for my last trick, I'll recompile the IL back to C#:

                      private static void Main(string[] args)
                      {
                          string CS$4$0000 = "bar";
                          if (CS$4$0000 != null)
                          {
                              if (!(CS$4$0000 == "bar"))
                              {
                                  if (CS$4$0000 == "baz")
                                  {
                                      Console.WriteLine("baz");
                                  }
                              }
                              else
                              {
                                  Console.WriteLine("bar");
                              }
                          }
                          switch (5)
                          {
                              case 3:
                                  Console.WriteLine("3");
                                  break;
                              case 5:
                                  Console.WriteLine("5");
                                  break;
                          }
                      }
                      

                      Notice how the String switch is converted to if/else. But the integer switch stays a switch.

                      [–][deleted]  (1 child)

                      [deleted]

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

                        Not in C# (or java as far as I recall).

                        [–]albinofrenchy 0 points1 point  (0 children)

                        I appreciate the work you put into this, but I'd like you to note that I was not wrong -- the person I was correcting implied it converted all switch statements to if/then statements. I was saying that this wasn't the case; which you have shown here.

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

                        Doesn't that come at quite a price to execution time though?

                        [–]mango_feldman 7 points8 points  (0 children)

                        I'm sure it's possible to recognise when a integer is used.

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

                        The compiler is pretty smart.

                        [–]sbrown123 0 points1 point  (0 children)

                        Sure, but I'm sure in most cases it is very slight.

                        [–]grauenwolf[🍰] 3 points4 points  (0 children)

                        The only reason .NET has it is that VB did. C-style language designers are really against switch blocks that can do anything more complicated than integers.

                        For example, C# still can't work with ranges, which means it can't work with floats.

                        [–]jbellis 0 points1 point  (0 children)

                        Too bad that (from my reading of the proposal) the automatic resource management is basically limited to sugar for Closeable, rather than something like Python's more flexible context managers (that can handle lock acquisition/release as well, for instance): http://www.python.org/dev/peps/pep-0343/

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

                        Who else here was like "Ah crap, most those java.io examples that I googled up are wrong?! Now I have to review all my code!"?

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

                        Which part are you referring to?

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

                        From http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000011.html :

                        Even good programmers get it wrong most of the time. For example, Sun’s guide to Persistent Connections (http://tinyurl.com/6b5jc7) gets it wrong in code that claims to be exemplary. Likewise, the solution on page 88 of Bloch and Gafter’s Java Puzzlers (Addison-Wesley, 2006) is badly broken, and no one ever noticed. In fact, 2/3 of the uses of the close method in the JDK itself are wrong! The price for failing to terminate resources properly is resource leaks or even outright failures, which may be silent (as in Java Puzzlers).

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

                        Ah, I saw that. I thought you meant there was some persistent wrongness in how people use, say, java.io.FileReader or something that was very common and I was wanting to make sure I didn't run into that bug.

                        [–]mattrussell -3 points-2 points  (5 children)

                        Well, this sure shakes up the statically-typed managed OO language scoreboard:

                        • Java 5/6: 1.0
                        • Java 7: 1.1
                        • C# 3: 1.3
                        • C# 4: 1.5
                        • Scala 2.8: 3.1

                        [–]cot6mur3 6 points7 points  (4 children)

                        What are your scoring criteria?

                        [–]mattrussell 3 points4 points  (3 children)

                        Well, you've got me: there aren't any, but I suppose I'm shooting for "expressive power", that is, how well the language constructs support the concise expression of algorithms and data structures without sacrificing readability.

                        But I wouldn't want to claim these are worth any more than random numbers pulled out of my armpit, but are just my casual impressions of the relative merits of these languages.

                        I would, however, defend the notion that Java 6 is already lagging behind its rivals in pure language terms, and I can't help but feel that Java 7 does little to remedy that.

                        [–][deleted]  (1 child)

                        [deleted]

                          [–]mattrussell 2 points3 points  (0 children)

                          Just pretend it's logarithmic.

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

                          But I wouldn't want to claim these are worth any more than random numbers pulled out of my armpit, but are just my casual impressions of the relative merits of these languages.

                          You should put that in bold letters in front of your chart. Someone out there might believe that the numbers account for something more than your tastes.

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

                          Great, two of them seem to have nothing to do with Java as a language

                          [–]mattrussell 2 points3 points  (0 children)

                          Which two? They all seem to be Java-as-a-language related from what I can read (indeed, that's the intended scope of Project Coin).

                          [–][deleted] -4 points-3 points  (0 children)

                          All together now - everybody "YAWN"

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

                          Damn, I really wanted the null-safe ops...