Friday, February 08, 2008

APIs designed around fixed-width integer types

I had a look at the NIO2 API proposed for Java 7. The functionality looks quite nice; in addition to non-blocking I/O and memory-mapped files already present since Java 1.4, they're adding enhanced file attribute support and access control lists.

However, one thing struck me: because the older Buffer class used for memory mappings was designed around having a length that is a Java int (which is fixed in stone as a 32-bit signed 2's complement integer), and this is clearly insufficient for many applications, they added a whole new BigBuffer class with a parallel hierarchy of subclasses to the Buffer hierarchy.

They ran into a similar problem with String; when Java was being designed, 16 bits was enough to represent all code points, but then Unicode 3.0 came along and required 21 bits, so now their string encoding is essentially variable-width, and applications have to deal with 'surrogate pairs' (most don't even bother!).

Fixed size integer operations are great to have in a language for performance reasons (however compilers should support idiom recognition, so that for example applying a bitwise and to an integer operation should result in fixed-width types being used under the hood), but designing APIs around fixed-width integers -- and not supporting overloaded operators for big integers in the language -- is just plain dumb.

2 comments:

Gili said...

Did you email the JSR authors to point out your concerns?

Slava Pestov said...

cow_woc: this isn't something a JSR can fix. Variable-width integers should have been part of the language from the very start. Array, collection and file lengths should have been BigIntegers, and fixed-width types should only have been used for optimization purposes inside inner loops.