Thursday, April 21, 2011

A Few Things I Wish Java Had

As I switch back and forth between Java and C# there are a few things I wish Java had that C# does. Almost all of my gripes are related to syntactic sugar, but I think they are nice to have.
  1. Nullable types - I think they're cleaner than using Object wherever a null reference might come into play. I know that they are still boxed under the hood in .Net (into Nullable<T> struct), so the performance is probably similar, but I think they are nice to have. May have a future post here...
  2. Lambdas - again, really just syntactic sugar for anonymous functions and can get quite ugly, but these are nice to have the majority of the time. (I suppose anonymous methods might be the start for Java. Java 9?)
  3. Unsigned types - can o' worms? Perhaps. See below for a quote from Gosling
  4. Implicitly typed variables - At first, I thought that var was not the greatest idea. But now, I love it. So easy and clean and totally type safe. 
  5. Generic containers that accept value types - Hashtable<Integer, Integer>. Really?
  6. Better collection initializers - C# has this down.
On the unsigned types front... Having signed bytes doesn't make any sense to me. Here's a quote from James Gosling on the topic:
 
Gosling: For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is. Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up.
 
I'm all for simplicity, but signed bytes seem over the top. Maybe he should've had all signed types except bytes or have signed and unsigned bytes. I totally agree with him on the complexity of signed/unsigned arithmetic in C as well, but it's not that hard to grasp (or lookup).
 
Don't get me wrong - Java is nice, these are just a few things that I think C# did really well.

4 comments:

  1. Nullable types might still get boxed in .Net but they're boxed into a struct, which should be faster than being boxed into a reference type (no inheritance which means no v-tables and no RTTI, being value types means no reference tracking, no garbage collection).

    Implicitly typed variables are nice but can be abused to make code harder to read:

    var customers = FetchCustomers();

    Now if you are the one refactoring FetchCustomers you don't really know if you must return a List, or if just IEnumerable is enough without digging deep into the code that uses the variable. Let's say the variable is used 20 lines down:

    mailer.NotifyCustomers(customers);

    Well now you have to dig into the implementation of mailer to find out what type customers has to be. All that could be made explicit:

    ICollection customers = FetchCustomers();

    No ambiguity here. Your contract is right there. There are cases where var is useful, I just personally like being explicit.

    ReplyDelete
  2. I'm not advocating throwing vars all over the place. I just think they have a place when you are creating a variable that has either a really long type specification and you're not going to be using it all over the place (e.g., 20 lines down) or is something you're just prototyping.

    As I said, my initial reaction to var was something along the lines of "WHY?!?!?!?", but I now believe they have a place.

    ReplyDelete
  3. I suppose it's just like everything else, it can be abused :) And the more I think about the code I posted I believe var isn't the villain - the contract should be the method signature, not the variable that stores the result.

    ReplyDelete
  4. When I first started looking into Java I learned that there were no unsigned types. I thought "OK, whatever." but as I continued on it was amazing how often I wanted to create an unsigned type.

    I'm all for simplicity too, but this goes into a philosophical view on what your variable "is". Deciding if your variable is signed or unsigned is a lot like determining if that variable is a float or an int. I feel that the better your data type represents what your variable "is" then the less likely you will introduce unexpected bugs into your code.

    For example, a float number can do everything an int can do. So why not define your count of apples as a float? Because eventually you find out they really are different and a float really isn't the best choice for the job.

    Signed & unsigned might not be as epic a difference as float & int, but I hope the point came across.

    ReplyDelete