what it matches. Accordingly, he set up many preprocessor definitions:
#define STRING char *
#define IF if(
#define THEN ){
#define ELSE } else {
#define FI ;}
#define WHILE while (
#define DO ){
#define OD ;}
#define INT int
#define BEGIN {
#define END }
This enabled him to code the shell using code like this:
INT compare(s1, s2)
STRING s1;
STRING s2;
BEGIN
WHILE s1++ == s
DO IF *s2++ == 0
THEN return(0);
FI
OD
return(--s1 - s2);
END
Now let's look at that again, in C this time:
int compare(s1, s2)
char s1, s2;
{
while (s1++ == s2) {
if (*s2++ == 0) return (0);
}
return (--s1 - s2);
}
This Algol-68 dialect achieved legendary status as the Bourne shell permeated far beyond
Bell Labs, and it vexed some C programmers. They complained that the dialect made it
much harder for other people to maintain the code. The BSD 4.3 Bourne shell (kept in
/bin/sh) is written in the Algol subset to this day!
I've got a special reason to grouse about the Bourne shell—it's my desk that the bugs
reported against it land on! Then I assign them to Sam! And we do see our share of bugs: