Integer variables in Modula-3
Modula 3 is perhaps my favourite language. It has (had — it's practically dead now) most of what I like about java, most of what I like about c++, most of what I like about modula 2, and some unique features.
One of its little greatnesses is in the integer type system.
In modula 3, an unsigned integer is 31 or 63 bits long (as I recall, there are two unsigned integer types, although a tutorial I found on the web now mentions only one). Signed integers are 32 or 64 bits, so if a is a signed integer, a=b always works, regardless of whether b is signed or unsigned.
a=b does not throw exceptions, a=b; b=a does not change the value of b, and the cost of that is merely that you have to start using 64-bit variables at 2147483648 instead of at 4294967296.
Update: I want to expand on that, and compare it to java. The language designers of both java and modula3 understood that confusion or sloppiness with regard to signed and unsigned integers was a significant source of bugs in c/c++. Java solved it by not having unsigned integers, modula3 solved it by reducing their bit width by 1.5-3%.
I have seen many java programs that either output long to formats or protocols where only unsigned numbers are legal, or that read into long when the format clearly says 64 bits unsigned
, so I think the java solution isn't very good. They chopped off the problematic feature and instead people use a misfit type. Sometimes it works: In this example it likely works because the sender too, uses a java long, so the so-called 64 bits unsigned ID is really 63-bit. I am not sure whether this kind of bug is preferable to the kind of signed/unsigned bugs in classic c.
Modula3, on the other hand, made the less obvious choice of leaving one bit at zero. The CPU registers are 32 or 64 bits wide, modula3 restrains programs to using 31 or 63 bits. As a result, programmers can still express the unsigned nature of many numbers using the type system, without sign problems. Subtle, well-considered, 97% good.