Now on ScienceBlogs: Attack of the pregnant cannibal fathers

Seed Media Group

Collective Imagination

Good Math, Bad Math

Finding the fun in good math; Shredding bad math and squashing the crackpots who espouse it.

Search

Profile

markcc.jpg
Mark Chu-Carroll (aka MarkCC) is a PhD Computer Scientist, who works for Google as a Software Engineer. My professional interests center on programming languages and tools, and how to improve the languages and tools that are used for building complex software systems.

Donors Choose

Other Information

Add this blog to my Technorati Favorites!

Recent Posts

Recent Comments

Categories

Blogroll

Old Topic Indices

Great Online Books

« From Beautiful to Twisted in One Syntactic Step: False | Main | Why am I doing this Pi-Calculus Language Thing? »

True Pathology: A Multilingual Quine

Category: pathological programming
Posted on: April 27, 2007 7:40 PM, by Mark C. Chu-Carroll

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))))
; -} -- *)

Share this: Stumbleupon Reddit Email + More

Comments

1

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

Posted by: Porges | April 27, 2007 9:41 PM

2

Wow! Great find.

That is truly awe-inspiringly pathological. I don't even know how to begin understanding that.

Posted by: Mark | April 27, 2007 10:40 PM

3

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/ .

Posted by: Michael Poole | April 27, 2007 10:48 PM

4

I have run across one in unix shell, c, and at least one of fortran and perl. Sadly, I can't find it.

Posted by: Aaron Denney | April 27, 2007 11:46 PM

5

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...)

Posted by: Coin | April 28, 2007 12:06 AM

6

Thats the scariest piece of code I've seen since I started playing w/ J.

It makes my brain hurt...

sweet.

Posted by: Joseph Fredette | April 28, 2007 12:09 AM

7

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/

Posted by: Zero | April 28, 2007 2:11 AM

8

What's the etymology of the term? Is it based on the philosopher?

Posted by: Clark | April 28, 2007 3:43 PM

9

"Polyglot" is an english word for a person who can speak several languages.

Posted by: Coin | April 28, 2007 4:08 PM

10

I....did not know these things existed.

CooOOOOOoooooooooolll.

Posted by: Luna_the_cat | April 28, 2007 8:19 PM

11

etymology of "polyglot":
poly -- many
glotta -- (Greek) tongue - also the root word for the medical terms "glottis" and words like "glossary".

Posted by: Luna_the_cat | April 28, 2007 8:25 PM

12

Yes Quine is from on the philosopher. I think it might have been Douglas Hodstadter who popularized the term.

Posted by: Markk | April 28, 2007 11:10 PM

13

Oh, that term. Now I feel stupid :P

Posted by: Coin | April 29, 2007 5:13 AM

14

...as do I...

Posted by: Luna_the_cat | April 29, 2007 6:04 AM

15

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.

Posted by: Iavor | April 30, 2007 12:25 AM

Post a Comment

(Email is required for authentication purposes only. On some blogs, comments are moderated for spam, so your comment may not appear immediately.)






Stats

ScienceBlogs

Search ScienceBlogs:

Go to:

Advertisement
Enter to win a free copy of The Monty Hall Problem
Visit the Collective Imagination blog
Advertisement
Collective Imagination

© 2006-2009 Seed Media Group LLC. ScienceBlogs is a registered trademark of Seed Media Group. All rights reserved.

Sites by Seed Media Group: Seed Media Group | ScienceBlogs | SEEDMAGAZINE.COM