While browser over at programming.reddit.com, I came across something simultaneously hideous and amazing.
I’ve showed quines before as part of the pathological programming posts: a quine is a program which, when run, generates itself as an output. I’ve even written about a programming language where the only way to create a loop is through quining the program.
But I’ve never seen anything like this before. It’s a multilingual quine: the program below is not just a quine, but it’s simultaneously a quite in three different languages: OCaml, Haskell, and Scheme. I have no idea how the author managed to figure out how to do this; and I probably don’t want to. 🙂
;; (*.) = {- *) let (@@) x y = x::y let e = [] let a = (* (letrec ((a '( ; -} -- *) " " @@ " A polyglot quine in " @@ " Haskell & O'Caml & Scheme " @@ " Author: Unknown " @@ " " @@ " Usage: runhugs thisfile # www.haskell.org/hugs " @@ " ocamlc -o x thisfile.ml ;./x # www.ocaml.org " @@ " scsh -s thisfile # www.scsh.net " @@ " " @@ "" @@ ";; (*.) = {- *) let (@@) x y = x::y let e = [] let a = (*" @@ "(letrec ((a '(" @@ "; -} -- *)" @@ "" @@ " e" @@ ";; (*:) = [" " ++ show x ++ " @@" | x (*" @@ "; *) [],[] | x::y -> if x = "" then [],y else let a,b = s y (*" @@ "; *) in x::a,b let b,d = s (snd (s a)) let f = String.escaped (*" @@ "; *) let c = List.map (fun x -> " \"" ^ f x ^ "\" @@") a" @@ ";; List.iter (fun x -> print_endline x) (b @ c @ d) (*" @@ ")) (f (lambda (x) (if (null? x) x (if (string? (car x)) (cons (" @@ "car x) (f (cdr x))) (f (cdr x)))))) (g (lambda (x) (if (string=?" @@ """ (car x)) (cons '() (cdr x)) (let ((y (g (cdr x)))) (cons (" @@ "cons (car x) (car y)) (cdr y)))))) (h (lambda (x) (if (null? x)" @@ "#f (begin (display (car x)) (newline) (h (cdr x)))))) (i (lambda" @@ "(x) (if (null? x) #f (begin (display " ") (write (car x)) (" @@ "display " @@") (newline) (i (cdr x))))))) (let ((b (g (cdr (g" @@ "(f a)))))) (h (car b)) (i (f a)) (h (cdr b))))" @@ "; -} -- *)" @@ e ;; (*:) = [" " ++ show x ++ " @@" | x (* ; *) [],[] | x::y -> if x = "" then [],y else let a,b = s y (* ; *) in x::a,b let b,d = s (snd (s a)) let f = String.escaped (* ; *) let c = List.map (fun x -> " "" ^ f x ^ "" @@") a ;; List.iter (fun x -> print_endline x) (b @ c @ d) (* )) (f (lambda (x) (if (null? x) x (if (string? (car x)) (cons ( car x) (f (cdr x))) (f (cdr x)))))) (g (lambda (x) (if (string=? "" (car x)) (cons '() (cdr x)) (let ((y (g (cdr x)))) (cons ( cons (car x) (car y)) (cdr y)))))) (h (lambda (x) (if (null? x) #f (begin (display (car x)) (newline) (h (cdr x)))))) (i (lambda (x) (if (null? x) #f (begin (display " ") (write (car x)) ( display " @@") (newline) (i (cdr x))))))) (let ((b (g (cdr (g (f a)))))) (h (car b)) (i (f a)) (h (cdr b)))) ; -} -- *)
There’s one in Python, Perl, C and C++ at:
http://www.phong.org/bf/polyglotC++PerlPythonC.c
And a whole bunch (C + Pascal, C + Tcl, C + Lisp, C + dc, C + dc + Brainfuck) at:
http://www.nyx.net/~gthompso/poly/polyglot.htm
Wow! Great find.
That is truly awe-inspiringly pathological. I don’t even know how to begin understanding that.
That’s pretty disturbing — I have seen polyglot programs before, but a polyglot quine is new to me. Google easily turns up a few others, though; for example, http://www.phong.org/bf/ .
I have run across one in unix shell, c, and at least one of fortran and perl. Sadly, I can’t find it.
Ah, you should see this page. They have a C+Pascal quine, a C+tcl quine, a C+dc (dc!!!) quine, a C+dc+brainfuck quine, a C+vi quine, and my personal favorite for aesthetics, a C+Scheme quine:
t(setq /*;*/){}main(){char q='”‘,s=’\’;char*a=
“~%t(setq /*;*/){}main(){char q=’~A’;char*a=
~S;char*b=/*
)(setq a ~S)
(setq */ ~S;printf(b,s,q,s,s,q,a,q,q,s,s,s,q,s,s,s,s,q,q,b,q/*
)(format t /* a /* a */);}~%”;char*b=/*
)(setq a “\”‘,s=’\\”)
(setq */ ”
t(setq /*;*/){}main(){char q=’%c%c’,s=’%c%c’;char*a=
%c%s%c;char*b=/*
)(setq a %c%c%c%c%c’,s=’%c%c%c%c%c)
(setq */ %c%s%c;printf(b,s,q,s,s,q,a,q,q,s,s,s,q,s,s,s,s,q,q,b,q/*
)(format t /* a /* a */);}
“;printf(b,s,q,s,s,q,a,q,q,s,s,s,q,s,s,s,s,q,q,b,q/*
)(format t /* a /* a */);}
At least one of the tricks from this is used in your C+haskell+ocaml quine– the neat duality between ; as a statement separator in most languages versus a comment operator in Scheme.
(Polyglots aren’t actually that hard, but almost all of them that you’ll ever find at some point depend heavily on something that is a comment operator in one language but something more meaningful in another. A popular trick is to mix C with perl/shell by loading up the beginning with complicated #defines, which of course are comments in perl…)
Thats the scariest piece of code I’ve seen since I started playing w/ J.
It makes my brain hurt…
sweet.
You may already know about this, but someone once constructed a polyglot for eight languages: COBOL (ANSI), Pascal (ISO), Fortran (ANSI, f77), C (ANSI-ish), PostScript, Linux/Unix shell script (bash, sh, csh), x86 machine language (MS-DOS, Win32, Linux) and Perl (version 5). No quine, but still utterly mind-boggling how they even figured out how to produce a comment syntax that was valid for all of the languages, let alone make it do something (it prints “hello polyglots”).
http://ideology.com.au/polyglot/
What’s the etymology of the term? Is it based on the philosopher?
“Polyglot” is an english word for a person who can speak several languages.
I….did not know these things existed.
CooOOOOOoooooooooolll.
etymology of “polyglot”:
poly — many
glotta — (Greek) tongue – also the root word for the medical terms “glottis” and words like “glossary”.
Yes Quine is from on the philosopher. I think it might have been Douglas Hodstadter who popularized the term.
Oh, that term. Now I feel stupid 😛
…as do I…
The code does not seem to quite work with GHC but can be fixed by indenting lines 4-36 by 1 space. This is quite cool, I hadn’t seen it before.
By the way a good way to start understanding how this works is to look at it in an editor that has good syntax highlighting support.
i’m confused. it’s complicated 🙁