"Is the title when preceded by its quotation", is the title when preceded by its quotation

Over the last several months I’ve been fascinated by the work of Douglas Hofstadter. Right now I’m reading Metamagical Themas, before that I read Gödel, Escher, Bach and I Am a Strange Loop. All of these books touch on the unexpected things that happen when systems are complex enough to reference themselves. Hofstadter thinks consciousness is a side effect of our mind’s capacity for self-reference. To understand his thinking on that topic, you should read his work (in fact, you should read it even if that’s not your goal). In this post I want to briefly touch on a comparatively mundane topic, Quines.

Hofstadter coined the term Quine (named for Willard Van Orman Quine) to be an indirect form of self reference. For example, the title of this post is a Quine

‘Is the title when preceded by its quotation’, is the title when preceded by its quotation

A direct form of self reference, along these lines, would be the following (which is clearly not a Quine).

This is the title

You can create the same sort of self-reference in software. For example the following is a program which prints itself using direct self-reference. It reads its own source file, and prints itself (provided you have saved it as not_a_quine.cc).

#include <iostream>
#include <fstream>

int main () {
    using namespace std;
    string line;
    ifstream myfile("not_a_quine.cc");
    while (getline (myfile,line)) {
        cout << line << '\n';
    }
    return 0;
}

The code above seems unremarkable, almost like cheating. In a way it’s also brittle and non-scalable. Imagine that biological cells replicated in this way, each one having to reference a centrally located “source code file” to make its copy. How would a cell in your finger access its version of not_a_quine.cc which might be in your big toe? What if the source is corrupted?

Its more interesting, and more difficult, to do the same sort of thing without allowing for direct self-reference. The code below is an example of this, and so it can be called a Quine (nb, it was heavily influenced by some similar code written in Java).

#include <iostream>
int main() {
    using namespace std;
    char q = 34;
    char c = 44;
    string str[18] = {
"#include <iostream>",
"int main() {",
"    using namespace std;",
"    char q = 34;",
"    char c = 44;",
"    string str[18] = {",
"    };",
"    for (int i = 0; i < 6; i++) {",
"        cout<<str[i]<<endl;",
"    }",
"    for (int i = 0; i < 18; i++) {",
"        cout<<q+str[i]+q+c<<endl;",
"    }",
"    for (int i = 6; i < 18; i++) {",
"        cout<<str[i]<<endl;",
"    }",
"    return 0;",
"}",
    };
    for (int i = 0; i < 6; i++) {
        cout<<str[i]<<endl;
    }
    for (int i = 0; i < 18; i++) {
        cout<<q+str[i]+q+c<<endl;
    }
    for (int i = 6; i < 18; i++) {
        cout<<str[i]<<endl;
    }
    return 0;
}

Its output can be compiled as well, and recursively so for as long as you like:

g++ -o a quine.cc ; ./a | g++ -x c++ -o b - ; ./b | g++ -x c++ -o c -

Interestingly, I started off writing program using char * instead of std::string and printf() instead of std::cout <<, but found it difficult for reasons mostly having to do with embedding quotation marks inside of quotation marks. Perhaps there is a lesson here about how more complicated systems (eg, c++ instead of c) are better suited for self-reference.

*****
Written by David Friedman on 23 January 2022