# Self-replicating code
A small journey through spoons, string escaping in Haskell and the theory of evolution.
Be entertained.
## Making a spoon using only a spoon
I saw this thumbnail on Youtube and immediately felt **thumbnail envy**.
If I could come up with thumbnails like these, I would be a Youtube star.
No matter the contents of the video, the idea is genius.

(Find the actual video [here](https://www.youtube.com/watch?v=OSfUUqNkrOQ) if you care regardlessly.)
The premise of the video is that of a fix point:
The input of the process is a spoon and the output is a spoon again.
If you focus solely on the spoon and treat everything else as *environment*, the spoon basically replicated itself.
Are there other such fix points? Of course:
This file has been truncated. show original
tl:dr
A quine is a program that produces its source code as output.
I got drawn into quines and couldn’t stop for a while. I put my insights together in a (hopefully) entertaining essay.
Show me your favourite quine!
I encourage anyone to just try and implement a quine by themselves. I don’t say it’s easy. It’s not impossible either. It doesn’t necessarily require a lot of programming experience … rather a hang for riddles.
7 Likes
<insert output of (fmt <$> readFile quine.hs)><insert output of (fmt <$> readFile quine.hs)>"
-- ^ 10 ------------------------------------------------------------------- 80> --
{- prelude-10-80/quine (tristanC)
SPDX: CC0-1.0
-}
this is the output that I get. What am I doing wrong?
And what about that readFile
?
I guess that happens when running the readme version, can you try with the provided quine.hs
file?
1 Like
yeah that one works! But is it accessing the file system?
EDIT: ah, so I guess the code in the readme is meant to be used to create the final, minified code.
Well no, that wouldn’t be a quine otherwise
1 Like
jaror
November 9, 2023, 10:59pm
7
For an extra challenge use import Prelude (putStrLn)
and avoid escape sequences in string literals.
One of my old university professors has an extensive page about a quine challenge (in JavaScript, but should not be that hard to adapt). He also has a bunch of hints, and a generalized challenge (with more hints):
Write a program G […]
that takes as input any valid […] definition of a function f that takes a string as argument, and
that produces as output a valid […] program P_f
such that the program P_f behaves like the function f applied to the program P_f itself, that is, like f (P_f ).
So for the input: "f x = putStrLn x"
, the output should be a regular quine.
I never did get completely through it. Maybe I should try again.
1 Like
What’s the idea behind this? No functions except putStrLn
?
And avoid escape sequences: this can be done rather trivially by using chr(34)
for double quotes. But is this what you mean?
jaror
November 9, 2023, 11:09pm
9
Yes, you’d only be allowed to use putStrLn
and the base language, so no chr
either.
But you can of course define your own functions.
I think the idea behind it is that it forces you to implement your own escaping mechanism.
1 Like
jaror
November 10, 2023, 9:37am
10
Here’s a quine that I would consider not using any “cheating” functions from Prelude and it also does not use the built-in string escaping mechanism:
SPOILER
escape ('%':'%':xs) = '%' : escape xs
escape ('%':'|':xs) = '|' : escape xs
escape ('%':'#':xs) = '#' : escape xs
escape ('%':'$':xs) = '$' : escape xs
escape ('#':xs) = '"' : self ++ '"' : escape xs
escape ('|':xs) = '\n' : escape xs
escape ('%':xs) = '"' : escape xs
escape ('$':xs) = '\\' : escape xs
escape (x:xs) = x : escape xs
escape [] = []
self = "escape ('%%':'%%':xs) = '%%' : escape xs|escape ('%%':'%|':xs) = '%|' : escape xs|escape ('%%':'%#':xs) = '%#' : escape xs|escape ('%%':'%$':xs) = '%$' : escape xs|escape ('%#':xs) = '%' : self ++ '%' : escape xs|escape ('%|':xs) = '$n' : escape xs|escape ('%%':xs) = '%' : escape xs|escape ('%$':xs) = '$$' : escape xs|escape (x:xs) = x : escape xs|escape [] = []||self = #||main = putStrLn (escape self)"
main = putStrLn (escape self)
But it still stores the whole program in a long unidiomatic string. The next step would be to factor that out into a pretty printing ADT similar to the Doc
type from pretty printing libraries like this one: https://hackage.haskell.org/package/prettyprinter-1.7.1/docs/src/Prettyprinter.Internal.html#Doc .
1 Like
I will try myself first. The longer I think about Quines, the more straightforward they become … the new challenge is welcome.
1 Like
jaror
November 11, 2023, 10:37pm
12
Here’s the basic idea of what I mean by this, although this is not yet a quine (it does produce a quine but the result has one very long line again):
SPOILER
data Doc = Text String | QU | BS | Self | Doc :-: Doc | Doc :|: Doc
eval :: Doc -> String
eval (Text xs) = xs
eval QU = ['"']
eval BS = ['\\']
eval Self = eval (quote self)
eval (xs :-: ys) = eval xs ++ eval ys
eval (xs :|: ys) = eval xs ++ '\n' : eval ys
quote :: Doc -> Doc
quote (Text xs) = Text "(Text " :-: QU :-: Text xs :-: QU :-: Text ")"
quote QU = Text "QU"
quote BS = Text "BS"
quote Self = Text "Self"
quote (xs :-: ys) = Text "(" :-: quote xs :-: Text " :-: " :-: quote ys :-: Text ")"
quote (xs :|: ys) = Text "(" :-: quote xs :-: Text " :|: " :-: quote ys :-: Text ")"
self =
Text "data Doc = Text String | QU | BS | Self | Doc :-: Doc | Doc :|: Doc"
:|: Text ""
:|: Text "eval :: Doc -> String"
:|: Text "eval (Text xs) = xs"
:|: Text "eval QU = ['" :-: QU :-: Text "']"
:|: Text "eval BS = ['" :-: BS :-: BS :-: Text "']"
:|: Text "eval Self = eval (quote self)"
:|: Text "eval (xs :-: ys) = eval xs ++ eval ys"
:|: Text "eval (xs :|: ys) = eval xs ++ '" :-: BS :-: Text "n' : eval ys"
:|: Text ""
:|: Text "quote :: Doc -> Doc"
:|: Text "quote (Text xs) = Text " :-: QU :-: Text "(Text " :-: QU :-: Text " :-: QU :-: Text xs :-: QU :-: Text " :-: QU :-: Text ")" :-: QU
:|: Text "quote QU = Text " :-: QU :-: Text "QU" :-: QU
:|: Text "quote BS = Text " :-: QU :-: Text "BS" :-: QU
:|: Text "quote Self = Text " :-: QU :-: Text "Self" :-: QU
:|: Text "quote (xs :-: ys) = Text " :-: QU :-: Text "(" :-: QU :-: Text " :-: quote xs :-: Text " :-: QU :-: Text " :-: " :-: QU :-: Text " :-: quote ys :-: Text " :-: QU :-: Text ")" :-: QU
:|: Text "quote (xs :|: ys) = Text " :-: QU :-: Text "(" :-: QU :-: Text " :-: quote xs :-: Text " :-: QU :-: Text " :|: " :-: QU :-: Text " :-: quote ys :-: Text " :-: QU :-: Text ")" :-: QU
:|: Text ""
:|: Text "self = " :-: Self
:|: Text ""
:|: Text "main = putStrLn (eval self)"
main = putStrLn (eval self)
I need a better pretty printer.
Little late to the party but here is a quine of order two I wrote many years ago in Haskell.
1 Like