No enumerations!

10th February 2002

So one night in the early 90s, Bill Joy and James Gosling were lounging around on their bean-bags with laptops, finalising the specifications for what would be the Programming Language Of The Future, the language that was to combine all the best features of C, Smalltalk, Ada and more; the language that would, one day, sweep the out-of-control monstrosity that is C++ from the face of the planet.

Unfortunately, Billy and Jimbo had had a few too many beers that night, and started getting a bit giggly as they messed about dotting the i's and crossing the t's of the spec. So around two in the morning, Gosling dissolves into a fit of helpless laughter. When Joy manages to get him coherent again (it takes a while), Gosling explains what's so funny:

``We've got this great type-safe language, right?''
``Uh-huh.''
``And there are no holes in the type system, so everything's secure?
``Right ...''
``So why don't we ... Why don't we take out enum?''

And of course, at this point, Joy also collapses in a heap of sophomoric jollity, and they excise the relevant part of the spec. before falling into a deep, drunken slumber. Unfortunately, before the hangovers have time to clear the next morning, an over-enthusiastic underling has the spec. couriered to the printer, and it's too late.

No? Well, then. Can you think of a more rational explanation?

I would remind you at this point that Java has been through versions 1.0, 1.1, 1.2 and 1.3. That's plenty of opportunities to fix this loathesome wart on the face of what's actually a really nice little language. (You could be forgiven for thinking that I don't like it much from the tirades that commentate on the ZOOM specification, but the truth is that I like it a lot. Still - how much better it could have been!)

Amazingly, there is nothing about enumerations in the comp.lang.java FAQ (www.ibiblio.org/javafaq/javafaq.html), the Java Programmers FAQ (www.afu.com/javafaq.html), Sun's JDK FAQ (java.sun.com/products/jdk/faq.html), or even the JAVA IAQ [Infrequently Answered Questions] (www.norvig.com/java-iaq.html), That looks to me like a tacit admission of guilt :-)

For those looking for some constructive suggestions in these commentaries, there is a fairly well-known alternative to the trivial approach adopted for ZOOM's record-syntax enumeration in the Record interface: it's an idiom called the ``typesafe enum'', which is discussed in detail at www.javaworld.com/javaworld/jw-07-1997/jw-07-enumerated.html. In essence, it works like this:

	public final class RecordSyntax {
	    public static final RecordSyntax GRS1   = new RecordSyntax();
	    public static final RecordSyntax SUTRS  = new RecordSyntax();
	    public static final RecordSyntax USMARC = new RecordSyntax();
	    public static final RecordSyntax UKMARC = new RecordSyntax();
	    public static final RecordSyntax XML    = new RecordSyntax();
	    private RecordSyntax() {}
	}
  

The private constructor prohibits client code from instantiating the class, so that the only instances of the enumeration class that can ever exist are the ones explicitly created at compile-time. That means that enumeration values can be compared with == (identity) rather than an equals() method (equivalence).

It's quite a cute hack, though it really shouldn't be necessary. But see www.javaworld.com/javaworld/javatips/jw-javatip122.html for a detailed critique of this approach.

Anyway, we can't use it here for two simpler reasons. For one, it's just much too verbose, so that the enumeration handling code would dwarf the rest of the Record interface. Second, and more important, it's no good putting it in our interface, since client code, using (and importing) an implementation would have to refer explicitly to org.z3950.zoom.Record.USMARC and friends. Blummen' useless.

You know what would be a really great way to represent enumerations? With an enum keyword. You'd say something like:

	public interface Record {
	    enum RecordType { GRS1, SUTRS, USMARC, UKMARC, XML };
	    enum RecordType recsyn();
	    ...
  

This is such a brilliant, simple solution that it makes me wonder why no-one's ever though of it before. Or, no, wait - that's right! It's been in every single language since PDP-8 assembler. Except one.

Feedback to <mike@indexdata.com> is welcome!