Home Backend Development Python Tutorial QuineRelay: Birth of the Quine serpent

QuineRelay: Birth of the Quine serpent

Aug 07, 2024 pm 10:30 PM

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+[]})())`)})`)())
Copy after login

Python: Try it online!

print("console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q+[]})())`)})`)())")
Copy after login

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"
Copy after login

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 ++ [')']")
Copy after login

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)+')'")
Copy after login

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.

QuineRelay: Birth of the Quine serpent

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

QuineRelay: Birth of the Quine serpent

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

QuineRelay: Birth of the Quine serpent


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)
Copy after login

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)
Copy after login

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)
Copy after login

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)
Copy after login

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);
Copy after login

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)
Copy after login

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 + '');
Copy after login

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:

  • Ouroboros programs, wiki page.
  • A Third Order Quine in Three Languages, blog by sigfpe.
  • Chain Quine, GitHub repo by Ibragimov Ruslan.
  • 128 Quine Relay, GitHub repo by Yusuke Endoh.
  • QuineRelay: Birth of the Quine serpent, self-referencing blog where a word in each n-order example hyperlinks to the next, cyclically. (May not work in dev.to; checkout the canonical blog)
  • Jörmungandr, wiki page.
  • Ouroboros, wiki page.
  • Art of Code, talk by Dylan Beattie

The above is the detailed content of QuineRelay: Birth of the Quine serpent. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to solve the permissions problem encountered when viewing Python version in Linux terminal? How to solve the permissions problem encountered when viewing Python version in Linux terminal? Apr 01, 2025 pm 05:09 PM

Solution to permission issues when viewing Python version in Linux terminal When you try to view Python version in Linux terminal, enter python...

How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading? How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading? Apr 02, 2025 am 07:15 AM

How to avoid being detected when using FiddlerEverywhere for man-in-the-middle readings When you use FiddlerEverywhere...

How to efficiently copy the entire column of one DataFrame into another DataFrame with different structures in Python? How to efficiently copy the entire column of one DataFrame into another DataFrame with different structures in Python? Apr 01, 2025 pm 11:15 PM

When using Python's pandas library, how to copy whole columns between two DataFrames with different structures is a common problem. Suppose we have two Dats...

How to teach computer novice programming basics in project and problem-driven methods within 10 hours? How to teach computer novice programming basics in project and problem-driven methods within 10 hours? Apr 02, 2025 am 07:18 AM

How to teach computer novice programming basics within 10 hours? If you only have 10 hours to teach computer novice some programming knowledge, what would you choose to teach...

How does Uvicorn continuously listen for HTTP requests without serving_forever()? How does Uvicorn continuously listen for HTTP requests without serving_forever()? Apr 01, 2025 pm 10:51 PM

How does Uvicorn continuously listen for HTTP requests? Uvicorn is a lightweight web server based on ASGI. One of its core functions is to listen for HTTP requests and proceed...

How to solve permission issues when using python --version command in Linux terminal? How to solve permission issues when using python --version command in Linux terminal? Apr 02, 2025 am 06:36 AM

Using python in Linux terminal...

How to get news data bypassing Investing.com's anti-crawler mechanism? How to get news data bypassing Investing.com's anti-crawler mechanism? Apr 02, 2025 am 07:03 AM

Understanding the anti-crawling strategy of Investing.com Many people often try to crawl news data from Investing.com (https://cn.investing.com/news/latest-news)...

See all articles