~ / track A / clojure basics

Lisp syntax and homoiconicity

Basic

Clojure code is written in the same data structures the language manipulates: lists, vectors, maps, symbols. Calling a function f with arguments a and b looks like (f a b) — function first, then arguments, all inside parens. That's the whole syntax. Because code is data, a program can read and transform other programs without a separate parser.

Minimal example

A function call is just a list with the operator in head position. Read the parentheses as "apply the first thing to the rest":

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

Vectors use square brackets and are used everywhere literal data is needed — arguments, bindings, sequence literals:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

Practical example

Because code is data, you can quote a form to keep it as data instead of evaluating it, then inspect it like any other list:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

This is what powers macros: a macro receives unevaluated code as data, rewrites it, and returns new code. Same syntax, no separate template language.

Exercise

Build the form (* 2 (+ 3 4)) as plain data (a list of a symbol and a nested list), then evaluate it. Try swapping the outer operator from * to - without rewriting the whole expression.

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate
 status: new