DEV Community

Cover image for QuineRelay: Birth of the Quine serpent
Darshan A S
Darshan A S

Posted on • Edited on • Originally published at darshan.hashnode.dev

QuineRelay: Birth of the Quine serpent

In the previous adventures of the Quine blog series, we explored how to write our own Quines and Introns. Today we will see what QuineRelays are and how you can leverage Introns to create them.

Imagine a circle of programs, each written in a different language. Each program in this circle has a single purpose: to print the source code of the next program in the sequence. The last program then closes the loop by printing the source code of the very first program.

Essentially, QuineRelays are a set of n programs, in n different languages such that:

  • Each program outputs the source of the next.
  • The last program outputs back the source of the first one. Think Circular-Linked-List here. The last example is a mind-blower!

Let's see some examples to grasp the concept better.


2nd-order relay

This 2nd-order QuineRelay features a JavaScript program that prints a Python program, which then prints the original JavaScript program back. It's a dynamic duo of self-replication.
JavaScript → Python ⥀

JavaScript: Try it online!

console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q+[]})())`)})`)())
Enter fullscreen mode Exit fullscreen mode

Python: Try it online!

print("console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q+[]})())`)})`)())")
Enter fullscreen mode Exit fullscreen mode

3rd-order relay

Things get even more interesting with a 3rd-order QuineRelay. This one starts with a Haskell program, which outputs a Python program, which outputs a Ruby program, and finally, the Ruby program loops back to the original Haskell program.
Haskell → Python2 → Ruby ⥀

Haskell: Try it online!

q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']
main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end"
Enter fullscreen mode Exit fullscreen mode

Python2: Try it online!

def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'
q("def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'","def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end","q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']")
Enter fullscreen mode Exit fullscreen mode

Ruby: Try it online!

def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end
q("def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end","q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']","def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'")
Enter fullscreen mode Exit fullscreen mode

4th-order relay

Here's a 4th-order QuineRelay: Ruby → Java → C# → Python ⥀
GitHub


Across cultures, there are several shared symbolisms. One of them is the Ouroboros, which has references in Egyptian, Greek, Roman, Hindu, Siberian, Norse, African, and South American mythologies. The Ouroboros is an ancient symbol depicting a serpent or dragon consuming its own tail, representing the eternal cycle of creation and destruction.

Oroborus symbol

In Norse mythology, Jörmungandr is a colossal serpent, the middle child of Loki and the giantess Angrboða. Odin cast Jörmungandr into the ocean surrounding Midgard (the realm of humans), where the serpent grew so immense that it encircled the world and grasped its own tail. As a result of it surrounding Midgard (the Earth) it is referred to as the World Serpent - Ouroboros. Jörmungandr releasing its tail is one of the signs of the beginning of Ragnarök (the final battle of the world).

Quine relays embody this symbolism quite neatly, as each program in the cycle gives rise to the next, only to be reborn in the end, and hence are nicknamed Ouroboros programs.


128th-order Ouroboros relay

Hold on to your seats. Here's a 128th-order Ouroboros QuineRelay. Yes, you read that right. 128 !!!
Ruby → Rust → Scala → ... (120 others) ... → Python → R → Ratfor → rc → REXX ⥀
GitHub

128 QuineRelay languages

As if this wasn't impressive enough, it includes an easter egg. The original Ruby code when zoomed out contains an Ouroboros dragon!

128 QuineRelay code snapshot


Writing your own QuineRelay

Let's start the Python intron we wrote earlier and try to turn it into a 2nd-order QuineRelay.

Python Intron: Try it online!

intron = 'wubbalubbadubdub'
data = "print('intron =', repr(intron)); print('data =', repr(data)); print(data)"
print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Enter fullscreen mode Exit fullscreen mode

Using the magic of introns, we can now easily put the code part of a sibling Quine of a different language into the intron. Producing a program of the form:

Python:

intron = "code part of sibling"
data = "code part of self"
print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Enter fullscreen mode Exit fullscreen mode

Since, each variable is just, acting as data of a different Quine. Let's rename data and intron, into d1 and d2 respectively.

Python:

d1 = "code part of self"
d2 = "code part of sibling"
print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d1)
Enter fullscreen mode Exit fullscreen mode

Now, d2 acts as an intron, but the above program still tried to print code part of self. To have it print source of the next, let's print(d2) instead of print(d1) at the end.

Python:


d1 = "code part of self"
d2 = "code part of sibling"
print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
Enter fullscreen mode Exit fullscreen mode

We already know that the contents of d1 is just a copy of line 3. But we don't yet have the contents of d2.

Say, we wanted to create a QuineRelay with JavaScript. Let's write a similar intron in JS.

JavaScript:

d1 = "code part of sibling"
d2 = "code part of self"
console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1);
Enter fullscreen mode Exit fullscreen mode

Now, line 3 of the above JS intron, is the code of the sibling program we wanted!
Paste each other's code as introns in the other.
Note. We need to add d1 + '' in js to avoid some quoting mismatches

Python: Try it online!

d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)"
d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 + '');"
print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
Enter fullscreen mode Exit fullscreen mode

JavaScript: Try it online!

d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)"
d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 + '');"
console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 + '');
Enter fullscreen mode Exit fullscreen mode

There you go. It's a proper 2nd order QuineRelay! A Python program, that prints a JavaScript program, that prints the original Python program back in a cycle.


Creating a QuineRelay is an exercise in creative coding and understanding how different languages represent and manipulate strings. It involves weaving together introns from various programs, each containing the code to replicate its next neighbour.

At its core, an nth-order relay is a game of n clever ways to escape quotes across n programming languages.

Stay tuned for the next post on MultiQuine!


Sources and references:

Top comments (0)