Quine is a computer program that prints own source code.
It might seem crazy and impossible, but in reality there is a technique how to create such programs. Further more it is possible to do using many (if not all) programming languages.
Before we start with this project we should differentiate what a valid quine is. A quine is considered as valid if it does not take any input to produce the result. For example if a program reads a source code file and outputs it - this is considered as cheating and it is not a valid quine.
Here we will take a look at 2 implementations of quines - one with Java and one with JavaScript. Both of them will use similar technique but as we will see the verboseness of the programming language plays a huge role.
Ok, let's get started!
Link to Wikipedia: https://en.wikipedia.org/wiki/Quine_(computing)
Here is a live coding session that shows how it can be done.
Duration: 4:10 (coding - 4:02)
Disclaimer: never use this code in production. It was created for fun.
Let's break down the solution and comment on some complex or interesting things.
0:10 - as I mentioned before, we will use Java for this project first.
And we will start with "cheating" version that will just read the file called Quine.java
and will output it using System.out.println
Note that Java by nature is quite verbose and we need to declare a class called Quine
(same as our file name) and also main
method with a proper signature.
Reading a file line by line involves chaining of several I/O related objects - BufferedReader
, InputStreamReader
and FileInputStream
.
Then we can just iterate through all lines of the file and output them as is.
Here we are cutting the corners a bit as we are not doing any error handling. But it's not the goal of this project, right?
0:41 - we can run our Java code and make sure that it outputs the exact same code as in source file - of course it does so as it reads it!
0:43 - now let's start over again and try to do a valid quine.
The major idea is to have the code duplicated in some String
variable.
For example if our source file starts with class Quine {
, then it should be also present in code
variable.
We will output our code
using System.out.printf
as we need to interpolate our code
and put the actual value of code
inside. Notice that we are using %s
inside code
- it will be the placeholder for string replacement.
In some sense we can consider it as one level of recursion.
And this is how most of the quines are built - have a code as string with placeholder for the code from a string. Sounds confusing? Yes it is! But actually it looks quite natural after some time.
1:29 - we run our program for the first time and we can see that it outputs something similar to original source code with few exceptions:
1:34 - trying to fix quotes. We can try to add them to code
string using \"
. It makes the result better, but not identical.
Also the resulting program will not compile...
1:44 - usually building quines requires a language-specific trick how to deal with quotes. For Java it can be done by escaping quote sibol in a clever way.
Try to run the following code: System.out.printf("%c", 34);
It will output just "
as 34
is ASCII code for double quote character!
This means that we can use %c
placeholder to output any character!
We can now replace our previous attempt to escape quotes with \"
with %c
and see how it goes.
2:01 - run the program again and see that it produces valid Java code that semantically identical to original source code.
What we need to do in the end - just uglify original source code so it is also a one-liner.
Now we got a valid Java quine!
Now let's take a look what happens if we take some less verbose language such as JavaScript. You might imagine that the quines will be shorter due to absence of Java's boilerplate with classes and methods.
Actually it is!
2:41 - but first - let's start with "cheating" version. Well, it's not 100% cheating, but it's on a border line to be so.
Idea is that you can print an object that represents a JavaScript function and it will actually print function's body!
function f() { console.log(String(f)); }; f();
You can see what is the output - it gives us a very good start.
Basically we need to adjust a bit the function's body and we are done.
Final version is trivial: function f() {console.log(String(f)+";f()")};f()
Really impressive!
3:28 - ok, but what about real JavaScript quine? Is it possible at all?
Yes, it is! And we will use the same idea as for Java quine.
Again we define a variable, let's call it s
that will be a placeholder for the code.
Skeleton will be s="s=%s;console.log(s,s);";console.log(s,s);
What happens here? Main program will just output value of s
using console.log
and it will replace %s
with value of s
!
But when we run it we notice same problem as with Java - missing quotes.
Similar to Java we will do a trick to deal with quotes.
node.js
has a special placeholder for string
variables that output objects as JSON. Luckily JSON representation of a string is a string inside double quotes! That's exactly what we need!
Note: I could not find official documentation that describes these placeholders. If you know about it more - please add a comment below!
We can just replace %s
with %j
and that's all!
Now we have completed 2 fully valid quines - one with Java and another one with JavaScript.
As you see - both of them use the same approach:
Sources: https://github.com/5minute/examples/tree/main/quine