Data structures

Python’s containers for data, and the Lisp pair for code.

Python containers

The collection literals build ordinary Python objects:

#[1 2 3]              ;; list
#(1 2 3)              ;; tuple
#{"a": 1 "b": 2}      ;; dict

Items are separated by whitespace. A *: inside a list or tuple literal splices an iterable in place, and the result is always a fresh object:

#[*: xs 1 2]
#(1 *: xs)

Dict keys are expressions. A string key is quoted; a bare name: key looks up the variable name; a parenthesized key is computed:

#{"name": "Ada" "score": 10}
#{(key-for user): (score-for user)}

Access and update use the same suffixes as Python:

xs[0]
d["a"]
set! xs[0] 9
set! d["k"] v
(item-slice xs 1)        ;; xs[1:]
(item-slice xs 0 2)      ;; xs[:2]

Everything a Python object does, it does here: (xs.append 4), (d.get "k" 0), (len xs), (in 2 xs), (sorted xs). Call a method on the binding, (d.get "k"), rather than through the type.

Pairs

The pair is the Lisp cons cell. cons builds a chain, car is its first element, and cdr is the rest:

(cons 1 2 3 nil)     ;; (1 2 3)
(car '(1 2 3))       ;; 1
(cdr '(1 2 3))       ;; (2 3)
(cons 0 '(1 2))      ;; (0 1 2)

cons is variadic: the last argument is the tail, and nil ends a proper list. nil? tests for the empty list, pair? for a cell. first and second are aliases for car and cadr.

nil is not None. (nil? nil) is true and (None? nil) is false; each predicate answers only for its own value.

Pairs are the structure a program is made of: every form the reader produces is a pair chain, and a macro takes them apart with car and cdr and builds its output with cons. Use them for that, and for a problem that is naturally one item and the rest. Use #[...] for data that Python libraries will see.

Quoting

A form in head position is a call. Quote it and it stays data:

(quote (red green blue))
'(red green blue)

The single quote is the reader’s shorthand for quote. A quoted symbol is a symbol value, 'red, and a quoted list is a pair chain of them.

Quasiquote is the template form. A backtick quotes the structure and a comma evaluates one part inside it; ,@ splices a sequence:

var name "Ada"
`(hello ,name)          ;; (hello "Ada")
`(1 ,@#[2 3] 4)         ;; (1 2 3 4)

Quasiquote is how a macro template is usually written; see Macros and hygiene.

Symbols and keywords

A symbol is an interned name: 'foo. A keyword is a self-evaluating marker written with a trailing colon, foo:, used for keyword arguments and as markers in forms such as [else: ...]. (symbol? x) and (keyword? x) classify them. An unquoted keyword in value position compiles to itself, which the compiler/keyword-literals pragma warns about, since it is more often a typo for a variable.

Choosing

You have

Use

application data, anything a Python API will touch

#[...], #(...), #{...}

code as data, macro input and output

pairs, quote, quasiquote

a name as a value

a symbol

an argument label or a structural marker

a keyword