C Is Not Algol....
Writing the UNIX Version 7 shell (command interpreter) at Bell Labs in the late 1970's,
Steve Bourne decided to use the C preprocessor to make C a little more like Algol-68.
Earlier at Cambridge University in England, Steve had written an Algol-68 compiler, and
found it easier to debug code that had explicit "end statement" cues, such as if ... fi
or case ... esac. Steve thought it wasn't easy enough to tell by looking at a " }" 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++ == *s2
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!
The shell doesn't use malloc, but rather does its own heap storage management using sbrk.
Maintenance on software like this too often introduces a new bug for every two it solves.
Steve explained that the custom memory allocator was done for efficiency in string handling,
and that he never expected anyone except himself to see the code.
Writing the UNIX Version 7 shell (command interpreter) at Bell Labs in the late 1970's,
Steve Bourne decided to use the C preprocessor to make C a little more like Algol-68.
Earlier at Cambridge University in England, Steve had written an Algol-68 compiler, and
found it easier to debug code that had explicit "end statement" cues, such as if ... fi
or case ... esac. Steve thought it wasn't easy enough to tell by looking at a " }" 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++ == *s2
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!
The shell doesn't use malloc, but rather does its own heap storage management using sbrk.
Maintenance on software like this too often introduces a new bug for every two it solves.
Steve explained that the custom memory allocator was done for efficiency in string handling,
and that he never expected anyone except himself to see the code.
No comments:
Post a Comment