Pairs, Lists, and Quotation
cons builds a pair; car and cdr take it apart:
(cons 1 2)
;=> (1 . 2)
(car (cons 1 2))
;=> 1
(cdr (cons 1 2))
;=> 2
A pair whose second component is another pair, ending in nil, prints as a list:
(cons 1 (cons 2 (cons 3 nil)))
;=> (1 2 3)
An improper tail falls back to dotted notation, as (1 . 2) above.
Lists are nothing but this: nil-terminated chains of pairs. car of a
list is its first element; cdr is the rest; null? detects the end.
Dotted notation is print-only. . is an ordinary symbol character, so
'(1 . 2) does not read back as a pair — it reads as a three-element
list whose middle element is the symbol .:
(cdr '(1 . 2))
;=> ('. 2)
Improper pairs are written with cons, never quoted.
car and cdr are for pairs only:
(car 5)
;! type error in car: expected Tup, got Cst(5)
Quotation
Building lists element by element with cons gets old. quote takes
a datum — the source text itself, unevaluated — and produces it as a
value; 'x is reader shorthand for (quote x):
'(1 2 3)
;=> (1 2 3)
'(a (b c) 4)
;=> ('a ('b 'c) 4)
(car '(a b c))
;=> 'a
Under a quote, symbols are data rather than variable references —
which is why 'a is how the symbol a is written, and why quoted
structure can mention names that are bound nowhere. This matters more
here than in most Lisps: Pink programs are quoted data, and Part III
consists largely of handing quoted λ↑↓ source to an evaluator that is
itself a floor program.
The empty list is written 'nil in quoted contexts by convention
(a quoted nil is still nil):
'nil
;=> nil
(null? 'nil)
;=> 1
Quasiquotation
A quasiquote `datum is a quote with holes. Inside it, ,expr
splices the value of expr into the datum:
`(1 ,(+ 1 2) 3)
;=> (1 3 3)
(let x 'mid `(a ,x b))
;=> ('a 'mid 'b)
Everything outside an unquote is data, exactly as under quote. Two
reader notes: ,@ (splicing unquote in Scheme) is read as a plain
, — there is no list splicing — and in loaded files quasiquote is
expanded at read time into plain cons/quote source, so library
code can use templates without the evaluator knowing about them
(lib/mk.naj is one big quasiquote template over an object program).
The cadr family
cadr, caddr, and cadddr — second, third, fourth element — are
surface sugar, rewritten to car/cdr chains before evaluation:
(cadr '(a b c))
;=> 'b
(caddr '(a b c))
;=> 'c
Following the reference implementation’s sug pre-pass, the rewrite
applies to the whole source tree including quoted data:
'(cadr x)
;=> ('car ('cdr 'x))
The quoted form arrives as (car (cdr x)) — because Pink source is
quoted data, and the Pink evaluator only understands the desugared
forms. Sugar that stopped at quotation would leave every quoted
program to desugar itself.