Why was Modula 3 so good?
The question has bothered me enough that I bought a new copy of Systems Programming with Modula 3 to reread. I reread, and was no wiser.
I liked the brevity of the language description. The designers explictly tried to make the language simple enough to describe in fifty pages. That may have something to do with the clarity of Modula 3 code.
I liked many of the minor features. I've mentioned the 31-bit integers before. Branded native types are another.
In Modula 3, you could define a variable as (I forget the exact syntax) branded msec cardinal timeout;
and get protection against unit confusion. If you branded a string as untrustworthy user-supplied input, you couldn't just assign it to an untagged string. If you branded an integer as msec
, you couldn't just pass it to a function which accepted a seconds
-tagged integer. That half-type gave a pleasant amount of protection against careless mistakes.
I seem to be saying that I liked Modula 3 because it was a compiled object-oriented language with simple syntax, sufficiently expressive, with some good features and no bad ones. Put that way, I admit that's my kind of language.
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.
Archiveopteryx git head crashes a bit. Not every day, but some people reports that it crashes every week or month, at random times. Clearly there is a bug. Abhijit and I have discussed it and found a way to contain it, and I've written the code.
But I haven't found a way to push the fix to the master tree. I seem unable to commit and push that code. My soul wants to find the bug and fix it, not contain it.
Meanwhile, I had an appointment with the dentist this morning.
In the waiting room I read a fascinating blog post about a Chromium exploit. Sergey Glazunov, clearly an admirably clever hacker, stitched together fourteen bugs, quirks and missed hardening opportunities
to form a critical exploit. The bugtracking information for one of the bugs shows that it was reported, discussed for a few days, then it was idle until Sergey leveraged it, and then it was fixed.
Chromium is a nice browser, and I appreciate the hardening and exploit resistance the team has added. I particularly appreciate the team's honesty: They run their pwnium contests and are frank about the results.
But now I am even less happy about making fault tolerant code. I feel that it may be mentally difficult to make a program tolerate faults and at the same time make a programmer not tolerate faults.
Consider the function Message::acceptableBoundary(). That function's reading order is exactly the same as the its execution order. This is not unusual in C and C++ (and more or less in Java), but there is a significant exception, for(). […More…]
Jira is what I'm supposed to look at in the morning. It tells me what's urgent. What I should fix. It's almost never anything I really want to do. I want to write code. Something that's challenging, with a useful result.
Telling me to open a web browser is not a good way to make me perform chores. Sorry.
All bug trackers suck. That's why Abhijit and I really don't want to use one for aox.
Here's what we do instead. It's subtle.
There's a notes file in the version-controlled source tree. The only way to add to a note (ie. file a bug) is to make us do it. There are some scripts that look at the file. […More…]
One really good thing I learnt from working with Abhijit on Archiveopteryx is how to get quickly into the flow. Click, flow.
The basic pattern involves a good kind of task, and a good way to get to it. Both parts are vital. […More…]
Writing about Knuth's literate programming book reminded me about when I met him (at a conference) and asked why the following algorithm wasn't in TAOCP. He grasped the algorithm from a ten-second description, and said it wasn't there because he didn't know about it. Good reason.
My TA at university (when I invented it for an exercise) wasn't aware of it either, but unlike Knuth, my TA didn't understand it. And I hadn't commented the code at all. Sigh.
Here are some words in sorted order: […More…]
I have a feeling that most (all?) parser generators are written with one overwhelming goal: Parse fast/well when the grammar and input are both correct. […More…]