Understanding quine-central: how do quine loops work?
        
        
        
        
        
          Yesterday another Recurser introduced me to
          quine-central, which is:
        
[A] Haskell program that generates a Haskell program that prints out a Perl program that prints out a Python program that prints out a Ruby program that prints out a C program that prints out a Java program that prints out a Rust program that prints out an OCaml program that prints out a Swift program that prints out a Racket program that prints out a Javascript program that prints out the first Haskell program generated.
“How the hell does that work?” I thought to myself. Maybe you’re thinking that too, so here’s my attempt at an explanation.
          quine-central can produce quine loops of any length, so
          let’s first think about a loop of three programming languages:
          Haskell, Ruby, and C. In this case, quine-central prints
          a Haskell program that prints a Ruby program that prints a C program
          that prints the first Haskell program generated.
        
           
        
          The generated Haskell program has two lines. The first line defines a
          function called q that takes three arguments.
          q builds and returns a string that contains its first
          argument, then a newline, and finally some Ruby code that calls a
          function called q. This call to q in Ruby
          takes the same arguments but rotated one position to the left. That
          is, it takes the second argument to the Haskell q, then
          the third, then the first.
        
           
        
          In the actual output, {a0} is replaced with the value of
          a0. Same goes for the other variables. Also, this isn’t
          quite the actual code. I simplified it a little for demonstration
          purposes.
        
          The generated Haskell program's second line is a main method that
          calls the function q defined on the first line and prints
          the result. Each argument passed to q is the source code
          for a definition of q in a language in the loop. The
          first argument is a definition of q in Ruby, the second
          in C, the last in Haskell.
        
main = putStrLn $ q "{Ruby    definition of q}"
                    "{C       definition of q}"
                    "{Haskell definition of q}"
          In all of these definitions, q does the same thing as it
          does in the Haskell program. It prints its first argument, then prints
          a call to a function called q, but in the next language
          in the loop. It also rotates its arguments one position to the left
          before printing them.
        
          When the program is run, q starts by printing its first
          argument, which is a declaration of q in Ruby. Then, it
          prints a call to q in Ruby. The arguments to this call
          are the second, third, and first arguments passed to q in
          the Haskell program, which are definitions of q in C,
          Haskell, and Ruby respectively.
        
          The output of the Haskell program is a Ruby program with a very
          similar structure. Both have two lines. Both declare a function
          q on the first line. q does the same thing
          in both programs. And both call q on the second line,
          passing in definitions of q for the rest of the loop.
        
When this Ruby program is run, it in turn prints a C program with the same structure. And that C program in turn prints a Haskell program with the same structure. In fact, it prints the original Haskell program, closing the loop.
          In the next post, I’ll discuss how
          quine-central generates these programs in the first
          place. We’ll also do away with some of the simplifications I made to
          the programs in this post and look at how
          quine-central handles the problems posed by string
          escaping.