TechWorkRamblings

by Mike Kalvas

202206121309 Homoiconic programming languages

A language is homoiconic if a program written in it can be manipulated as data using the language, and thus the program's internal representation can be inferred just by reading the program itself. This property is often summarized by saying that the language treats "code as data".1

One of the most commonly cited homoiconic languages is Lisp. Clojure (a modern dialect of Lisp) and Julia are also homoiconic.

Example

The following Lisp S-expression creates a list of 3 elements with values 1, 2, and 3, and is precisely equivalent to the code required to create the object itself.

(1 2 3) ; => (1 2 3)

More broadly, all Lisp programs are lists (a.k.a. objects which can be manipulated with the Lisp language). Slightly more concretely, the string representation of a Lisp program is valid Lisp data. Passing a hard coded value or passing a Lisp program as input to a Lisp function would behave identically.

An example of non-homoiconicity in JavaScript:

const arr = [1, 2, 3];
arr.toString(); // => '1,2,3'

Here, the string representation (even if we print it more nicely as [1, 2, 3]) is not the same as the code required to create the object (for instance, the variable declaration part). This is a simple example that might fall down on a deeper level, but gets the idea across.


  1. Wikipedia contributors. (2022). Homoiconicity. In Wikipedia. https://en.wikipedia.org/w/index.php?title=Homoiconicity&oldid=1085737296