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<-( *.)]; main = {-" @@ "; -} sequence_ (map putStrLn (x ++ ( *:) ++ y)); (x, _:y) = {-" @@ "; -} span p (tail (dropWhile p ( *.))); p = (/= \"\"); infixr {-" @@ "; -} @@; (@@) = (:); e = [] {- *) let rec s = function [] -> (*" @@ "; *) [],[] | 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<-( *.)]; main = {- ; -} sequence_ (map putStrLn (x ++ ( *:) ++ y)); (x, _:y) = {- ; -} span p (tail (dropWhile p ( *.))); p = (/= ""); infixr {- ; -} @@; (@@) = (:); e = [] {- *) let rec s = function [] -> (* ; *) [],[] | 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)))) ; -} -- *)
- Log in to post comments
More like this
For your amusement and edification, the following is a very simple interpreter for fractran
programs which, in addition to running the program to generate its result also generates a trace
to show you how the program executed.
;; A Trivial Fractran Interpreter
;;
;; Copyright 2006 Mark…
I'm currently away on a family vacation, and as soon as vacation is over,
I'm off on a business trip for a week. And along the way, I've got some deadlines
for my book. So to fill in, I'm recycling some old posts. I decided that it's been
entirely too long since there was any pathological…
While I was waiting for stuff to install on my new machine, I was doing some browsing around the web, and came across an interesting article at a blog called "The Only Winning Move", titled [Scheme Death Knell?](http://theonlywinningmove.blogspot.com/2006/10/scheme-death-knell.html). It's not a bad…
One thing that we've seen already in Haskell programs is type
classes. Today, we're going to try to take our first look real look
at them in detail - both how to use them, and how to define them. This still isn't the entire picture around type-classes; we'll come back for another look at them…
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 :P
...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 :(