4. Early Attempts That Fail

When first faced with the problem of writing a self-documenting program, the initial attempts at solutions tend to lead to dead ends. Still, they provide insight into the structure of a working solution. Two such ideas are examined here.

Brute Force

In the brute force approach, we simply take the "print myself out" idea literally. We examine the code and start generating statements to print out the program. The first line of any C program reads:
    main() {
So obviously, the second line will have to read:
    printf( "main() {\n" );
Namely, a line that prints out the first line. Now, we have to add a line that prints out the second line. That will look like this:
    printf( "printf( \"main() {\\n\" );\n" );
And, of course, we need to include a line to print that line out:
    printf( "printf( \"printf( \\\"main() {\\\\n\\\" );\\n\" );\n" );
There is an obvious difficulty here. Any program that attempts to solve the problem this way will have to be infinitely long. As soon as the program contains any instructions at all, it will have to contain instructions to print those instructions, and a loop will begin. Brute force fails because we continuously need to refer to previously done work; we can never catch up.

Name That Program

We need to bring out the use/mention distinction to overcome this infinite loop problem. In particular, we need to separate the use and mention aspects of the program to achieve our goal. In brute force, the use and mention were wrapped up in each other. The use of each line of code contained the mention of the line before it. Perhaps we can get around this by specifying the mention first, and then using it later.

To accomplish this, we first define a string f which contains a mention of the whole program. Then we can print the program from within its own code by printing f - a mention, rather than a use, of the code. Based on this idea, we get the following program:

    char*f="main(){printf(f);}";
    main(){printf(f);}
When run, this program produces the following output:
    main(){printf(f);}
Unfortunately, we do not yet have a solution, because this is not the complete program! This idea failed to take into account the extra line that was added at the start to define the mention of the program. Our solution would have to output a copy of this line as well. But where do we obtain a mention of this line? We almost have one already! Except for the initial 'char*f="' and the closing '";', the line is a mention of itself. So we may be very close to a solution indeed. The critical step is to print out the same string twice: once as the mention, and once as the use.
[back] [up] [right]