Totally awesome software for iPhone and OS X

Tuesday, December 16, 2008

La Philosophie pour les Nul(l)s...

As the dark, cold nights are drawing in I've been throwing logs on the fire, sitting in a comfortable chair with a glass of Cardhu and thinking a little about null values work (or should work) in Java. For example, if you define a method as returning a String, conceptually speaking, what should it do? Should it return only String instances, or should it return either an instance of a String or null.

I've long been used to the way Java happily passes null around and have developed a hell of a lot of code over the years that checks for null, as I'm sure have most people. But, wouldn't it make more sense if the implicit contract of the return type specified by the method were adhered to?

Recently, in some cases, we've been writing what I guess you could call 'null-safe' objects (all fields pre-initialised and setters that don't allow values to be nullified). This on the face of it seems conceptually valid, the methods return what they say they'll return and there's a lot less null checking to do when using them. Objects written like this are ideal for e.g. sticking into freemarker templates as then the template designers don't need to care about checking whether or not values exist because they always do.

Problem solved?

Not really. There is an obvious conceptual difference between zero and nothing for a Long value, or between 'no string at all' and an empty string. And if you're going to 'protect' your objects like this, how do you signal that you've done so to other users of your API?

I think most people are comfortable with a certain synonymity between a null string and an empty string, but it gets trickier for other types (and let's not even get into primitives - which can't ever be null in Java). The problem seems to be that Java has no proper way of handling null other than throwing an unchecked exception when you accidentally encounter it.

Microsoft's venerable .NET has the concept of nullable types which (at least for value types, structs and enums) allows you to specify that a type can, infact, be null e.g. int? j = null; But this, with the exception of allowing nullable value types is little more than a syntatcially nice way of doing null checking (or, indeed the 'null-safe' object approach I identified above).

Is there a better way?

Well, it appears that other languages may have a more cromulent approach. Haskell, Scala etc. avoid the use of null (well, technically Scala does have null, but generally it's not used).

Scala prefers instead the use of a simple 'Option' monad that has two sub-classes 'Some' and 'None'. Option is type-safe, so you can have an Option of any type (but only of the type you define it to be). 'None' is essentially a type-safe null (a singleton object, like Nil in Ruby) and 'Some' is a holder for the actual value. Combined with Scala's filtering and pattern matching, we can explicitly exclude 'None' values from operations or act differently (insert a defult value instead, perhaps) depending on how we want to proceed. I'm no Scala expert, but this does seem a saner approach.

Another similar approach is taken by Objective-C, in which Nil is an object. The nice thing about the way Objective-C handles Nil (and objects in general) is that you can happily send messages to Nil and nothing bad will happen. Unexpected things may happen, but nothing bad :)

Oops *oops = nil;
NSLog(@"Oops is doing %@", [oops doSomething]);

This will probably, from memory, print out something like "Oops is doing (null)", not brilliant. But surely better than a runtime exception?

So, in short, I don't really know what the answer is here... In some cases you need to know about null, nil and empty values and in other cases you don't, that's a given. And you can, kind of, achieve this duality in Java but it's annoying that null itself is a special case. It's not an object, it isn't a proper type and calling methods on a null object throws a runtime exception. You could, I suppose, almost say that this approach was similar to Scala's, in that every java Object is implicity an 'Option', 'Some' is the value (if any) and null is synonymous with 'None' (except it's not type-safe etc. etc. etc.) and you do all the pattern matching and checking yourself and if you don't, or get it wrong the whole thing blows up in your face.

I can't help thinking there could have been a cleaner way to handle all of this.

Monday, December 15, 2008

Fancy learning books.

Bill the lizard has a great post listing books that programmers don't really read . In the post he points out that lots of people claim to have read titles such as the GOF patterns book, but haven't really :) He also suggests a list of books which programmers actually (probably) have read, such as Code Complete.

I'll confess to owning a copy of The Art of Computer Programming and never having read it. I have worked through some of the maths with a paper and pencil and I've used it as an infrequent reference but that's about it. I'm saving the rest of it for my retirement...

As for his other suggestions, I agree wholeheartedly. If you're looking for a comprehensive list of worthwhile holiday reading you could do worse than filling in the gaps in your book collection with these suggestions.

On another note, I noticed the following comment from 'anonymous'.

I graduated from Imperial(UK) around 2 years ago and have been programming for a well-known company in a well-paid job for just over a year now. I have read none of these books. Hurray!


Sadly, this attitude is quite prevalent amongst 'career coder drones' in the various industries I've worked in. It seems bizzare to me that people would be working in a field that they have little or no interest in - other than that of getting paid at the end of the month.

I suppose you can get away with it, but, as they say, 'those who don't learn from history are doomed to repeat it' and I'm sure it's unmotivated, bookshy coders like this that are responsible for the 'well-paid' contracts in 'well-known' companies that I keep getting offered to help fix their broken wheel reimplementations...

© 2007 Wired Up And Fired Up