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
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
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:
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.