Homoiconicity is the property of a programming language in which programs are written using the same data structures that the language itself manipulates. In the LISP family, including Scheme and Clojure, a piece of code is just a list, and lists are an ordinary kind of data the language already knows how to build and take apart.
This idea goes back to LISP’s origins. John McCarthy’s foundational paper on LISP defines programs as symbolic expressions, or “S-expressions,” and shows how these same expressions can be both the data a program operates on and the program itself. The 1975 Scheme report continues this tradition, describing a LISP-like interpreter where programs are expressed and evaluated as these nested list structures.
Because code and data share one representation, a program can treat another program as data: it can read a list that happens to be a program, rearrange it, build a new one, and then run the result. There is no separate, hidden syntax tree to wrestle with; the visible parentheses are the structure.
This is the foundation of LISP’s famously powerful macro systems. A macro is a piece of code that takes program fragments as list data, transforms them, and returns new code to be compiled or run. Homoiconicity is what makes such metaprogramming feel natural rather than bolted on, and it remains one of the most distinctive features of the LISP and Scheme tradition.