Quine (Erlang)

From LiteratePrograms

Jump to: navigation, search
Other implementations: BASIC | Clojure | dc | Erlang | Forth | JavaScript / URI | Lisp | Oz | Perl | Python | Smalltalk

A "Quine" is a program that prints its own sourcecode when it is run. See Wikipedia's article on Quines for more information, and David Madore's Page for a highly readable introduction to the art of constructing Quines.

Contents

Implementing a Quine

There are a variety of different ways we might go about producing a Quine in Erlang. Here we describe two of them.

Encoding as a list of Ints

Perhaps the easiest way is to take advantage of the fact that Erlang internally represents strings as lists of integers. We can then simply encode the entire program as a list of integers, and use the ~s and ~w output format selectors to print the list first as a string and then as an actual list.

<<quine.erl>>=
-module(quine).
-export([start/0]).
start() ->
    Data = data(),
    io:format("~s~n~ndata() ->~n    ~w.~n", [Data, Data]),
    halt().
data() ->
    [45,109,111,100,117,108,101,40,113,117,105,110,101,41,46,10,45,101,120,112,111,114,116,40,91,115,116,97,114,116,47,48,93,41,46,10,10,115,116,97,114,116,40,41,32,45,62,10,32,32,32,32,68,97,116,97,32,61,32,100,97,116,97,40,41,44,10,32,32,32,32,105,111,58,102,111,114,109,97,116,40,34,126,115,126,110,126,110,100,97,116,97,40,41,32,45,62,126,110,32,32,32,32,126,119,46,126,110,34,44,32,91,68,97,116,97,44,32,68,97,116,97,93,41,44,10,32,32,32,32,104,97,108,116,40,41,46].

Encoding as a string

An alternative and slightly more elegant approach (inspired by the Python Quine) is to represent the program as string data. The secret to making this work is again to make use of Erlang's representation of strings as integer lists. But this time we keep most of the program as a string, and only encode the quote characters (which allows us to avoid having to escape them in the source string).

<<quine2.erl>>=
-module(quine2).
-export([start/0]).
quine(Source) -> 
    io:format(Source ++ [$(,34] ++ Source ++ [34,$),$.]),
    halt().
start() ->
    quine("-module(quine2).
-export([start/0]).
quine(Source) -> 
    io:format(Source ++ [$(,34] ++ Source ++ [34,$),$.]),
    halt().
start() ->
    quine").

This comes close to David Madore's “quine ‘quine’”.

Testing the Quine

Compiling and running quine2.erl does indeed produce the source for quine2.erl, demonstrating that it is a Quine.

$ erlc quine2.erl 
$ erl -run quine2
Erlang (BEAM) emulator version 5.4.12 [source] [hipe]
-module(quine2).
-export([start/0]).
quine(Source) -> 
    io:format(Source ++ [$(,34] ++ Source ++ [34,$),$.]),
    halt().
start() ->
    quine("-module(quine2).
-export([start/0]). 
quine(Source) -> 
    io:format(Source ++ [$(,34] ++ Source ++ [34,$),$.]),
    halt().
start() ->
    quine").
Download code
Views