A quine is a program which produces its own sourcecode as its output. Typically, the trick is to use a format string with a call to
a print
or printf
function. Since lisps can easily treat sourcecode as any other data, writting a quine in lisp is not as
mind-bending an excersise as in other languages (see the examples here).
Additionally, access to anonymous functions in Clojure makes it easy to get the recursion required for a quine.
Writing a quine initially seems a daunting task, but once it's broken down a bit, it becomes surprisingly easy. Armed with lambdas and syntax quoting, all we need to do is write a function which returns the argument passed to it wrapped in lambda syntax, and applied to the argument wrapped in syntax quoting.
I initially wrote this using the special form backtick and unquoting with ~
but then remembered that Clojure gives the namespace
qualified symbols when these are nested within each other (try implementing the below code using these symbols instead of quote
to
see that it won't implement a proper quine since the actual syntax will be different even though they will be evaluated in the same
way). See this article on syntax quoting from
8th Light for a really good explanation of quoting in Clojure.
((fn [x] (list (list (quote fn) (quote [x]) x) (list (quote quote) x))) (quote (list (list (quote fn) (quote [x]) x) (list (quote quote) x))))
I use quote
and list
to wrap the argument with (fn [x] *arg*)
and then use another list
call to create a list which applies
this function on the quoted form of the argument. I use (quote quote)
to quote out a call to quote
. This is needed so that the
symbol quote
is passed rather than the result of evaluating quote
. After this function was written, I just copied it and passed
it as a quoted argument to the function.
Putting some better indentation into the code:
((fn [x] (list (list (quote fn) (quote [x]) x) (list (quote quote) x)))
(quote (list (list (quote fn) (quote [x]) x) (list (quote quote) x))))
Overall this was a good excersise in syntax quoting, recursive reasoning and useless problem solving. Highly recommended!