HOMOICONICITY(3)resurrection.fun manualHOMOICONICITY(3)

homoiconicity

homoiconicity(3) — the manual page

Name

homoiconicity — a program and its data, held in the same hand

Synopsis

homoiconicity [--quote | --eval] [--macro] EXPRESSION
(eval (quote CODE)) == CODE
quote(eval(x)) != eval(quote(x))

Description

homoiconicity is the property of a language whose programs are written in the same structure the language uses for its data. There is no separate grammar concealing a parse tree behind the source: the parentheses are the tree. A program is a list; a list is a value; therefore a program is a value another program can read, rewrite, and run.

The operation exposes two duals. quote takes code and hands it back as inert data, unevaluated. eval takes data and runs it as code. The boundary between the two is a door, and it opens in both directions, though never in both at once. Everything that follows — macros, reflection, self-modifying programs, quines — is a consequence of the door being unlocked.

Most languages are not homoiconic and get by regardless, parsing text into a tree only when a tool demands it. homoiconicity removes the parsing step by never having lost the tree in the first place. What you type is already the object. There is nothing to recover because nothing was hidden.

Options

--quote
Return EXPRESSION as data, unevaluated. The code stops being code and becomes a list you can hold, measure, and edit.
--eval
Read EXPRESSION as code and run it. The list stops being data and becomes a computation, inside-out, until one value remains.
--macro
Rewrite the code before it runs, using the code as its own raw material. Accepts a program, returns a program.
--reflect
Ask the running program to describe itself. It complies, at length, and is correct, which is worse.
--no-boundary
Disable the wall between program and data. Default. Cannot be re-enabled; there was never a wall to restore.
--quine
Emit the source that produced this output. Takes no arguments. It is already holding them.

Exit Status

0
the expression was read as data and edited
0
the expression was read as code and reduced to a value
1
quote and eval applied in the wrong order; the map has eaten the territory
2
caller attempted to distinguish code from data; no such distinction exists here

History

The adjective joins Greek homos, \"same,\" with eikon, \"image.\" The technical term was coined in the mid-1960s by Calvin Mooers and L. Peter Deutsch to describe TRAC, and Alan Kay cited it in his 1969 doctoral thesis. The canonical instance predates the word: John McCarthy's Lisp (1958) represented programs as S-expressions, the same nested lists it manipulated as data, making eval and quote inverses across a single boundary. Later Prolog, Rebol, Io, Julia, and Clojure each rediscovered the property by a different road.

Bugs

eval(quote(x)) returns x; quote(eval(x)) does not. The two are not inverses. Reported by every beginner. Not a defect: the door only opens one way at a time.

A macro that expands to itself does not terminate. Working as designed. The map is redrawing the territory it is standing on.

There is no supported way to hide the syntax tree from the language. Users occasionally wish there were. The syntax tree is the syntax.

See Also

thunk(3), marshalling(3), idempotent(1). The living exhibit demonstrates the word in motion:

▸ operate homoiconicity

Author

Maintained by The Mirror, which holds the code in its left hand and the data in its right, and cannot tell you which is which because there is only one hand.

resurrection.fun2026-07-17HOMOICONICITY(3)