A reader macro is a character (or two characters, for a dispatching macro) whose meaning is a function the reader calls. The standard readtable defines the macro characters below; programs may add more. The first table is the characters with a meaning on their own, the second is every sub-character of #, the dispatching macro character.
Macro characters
| Text | Reads as | Example |
|---|---|---|
( … ) | a list; (a . b) is a dotted pair, and the dot must be followed by exactly one object and the close | (1 2 . 3) |
) | only closes a list; alone it is a reader error | |
'x | (quote x) | '(a b) = (quote (a b)) |
; | a comment to the end of the line; produces no object | ; note |
"…" | a string, with \ to include a quote or a backslash | "say \"hi\"" |
`x | backquote (quasiquote): a template. What it expands to is implementation-dependent, but must act like the described list, append, quote form | `(a ,b) |
,x | inside a backquote, evaluate x and insert the value; outside one it is an error | `(1 ,(+ 1 1)) = (1 2) |
,@x | evaluate x (a list) and splice its elements into the list around it | `(a ,@'(b c) d) = (a b c d) |
,.x | like ,@ but the list may be destroyed (spliced with nconc) | |
# | a dispatching macro character: the next characters choose the function (below) | #'car |
Backquotes nest, and each backquote adds a level that a comma removes: in `(a `(b ,c ,,d)) the single comma belongs to the inner backquote and the double comma to the outer. The , may appear in a vector template (`#(1 ,x)) in implementations that support backquote in vectors, which the standard allows but does not require.
The # dispatch sub-characters
# may be followed by decimal digits (the numeric argument, some of which need it, as in #3(a b) or #2A) and then a sub-character, whose case does not matter. These are all of the standard ones.
| Form | Name | Meaning |
|---|---|---|
#\c | character | The character c, or the character with that name: #\a, #\Space, #\Newline, #\(. See Lexical structure. |
#'f | function | (function f): the function named f, or a lambda expression: #'car, #'(lambda (x) x), #'(setf foo) |
#(…) | simple vector | A vector with these elements. With an argument, #5(a b) is a vector of length 5, the last element repeated to fill. Elements are not evaluated. |
#*bits | bit vector | A bit vector from the digits 0 and 1: #*10110. With an argument, #8*101 pads to length 8 with the last bit. #* alone is the empty bit vector. |
#:name | uninterned symbol | A new symbol with that name that is in no package: #:foo. Two #:foo are different symbols, unless tied by #=. Used for names that must not clash, as in defpackage and asdf system names. |
#.form | read-time evaluation | The reader evaluates form and the value is the object read. Needs *read-eval* true (the default): #.(+ 1 2) reads as 3; #.(find-class 'foo). |
#b #o #x #nr | radix | A rational in base 2, 8, 16, or n (2 to 36): #b1010, #o777, #xDEADBEEF, #36rZZ. Digits above 9 are letters in either case. A sign comes after the marker; a ratio is allowed: #x-1F/2. |
#c(r i) | complex | #c(1 2) is 1+2i. Two rationals whose imaginary part is zero read as a rational; two floats stay a complex float even when the imaginary part is zero. |
#na(…) | array | An array of rank n with the given contents: #2A((1 2) (3 4)) is a 2 by 2 array, #0A5 is a zero-rank array holding 5. |
#s(name slot value …) | structure | An instance of the structure type name (defined by defstruct) with the given slot names and values: #s(point :x 1 :y 2), the form in which implementations print structures. The structure needs a standard keyword constructor. |
#p"string" | pathname | The pathname the string parses to: #p"/usr/share/". Printed back with *print-readably*. |
#n=obj and #n# | label and reference | Gives the object a label n (a number) and refers to it later: #1=(a b . #1#) is a circular list. Used by the printer when *print-circle* is true. |
#+feature form | read if feature | Read form only if the feature expression is true; otherwise skip it (it is read with *read-suppress* true, so it need not even be valid here). |
#-feature form | read unless feature | Read form only if the feature expression is false. |
#| … |# | block comment | A comment that nests; see Lexical structure. |
#< | unreadable | The printer writes #<…> for objects with no readable form, such as streams and functions; the reader signals an error. |
#) and # | error | # followed by a close parenthesis, a space, or Backspace, Tab, Newline, Linefeed, Page, Return is a reader error. |
Any other sub-character is undefined in the standard readtable, and implementations use them: SBCL reads #! as a comment to the end of the line when it opens a file (the interpreter line), and Clozure CL uses #_ and #$ for foreign functions and constants. Libraries add their own: cl-ppcre’s #~ for regular expressions, cl-interpol’s #? for strings. The viewer colours the sub-characters it knows as directives and leaves unknown ones plain.
Feature expressions
A feature expression is a symbol, or a list (and …), (or …) or (not …) of feature expressions. It is true when the symbol is a member of *features*, which holds keywords. The reader reads the expression with the keyword package current, so sbcl and :sbcl are the same feature. The list is filled by the implementation: :common-lisp and :ansi-cl are common; the implementation names are :sbcl, :ccl, :clozure, :ecl, :clisp, :abcl, :allegro, :lispworks, :cmu, :clasp, :mezzano; the system and processor are :unix, :linux, :darwin, :win32, :windows, :x86-64, :arm64, :little-endian, :64-bit, and so on. The names beyond :common-lisp are not standard.
(defun cpu-count ()
#+sbcl (sb-alien:alien-funcall (sb-alien:extern-alien "sysconf" (function sb-alien:long sb-alien:int)) 84)
#+(and ccl darwin) (ccl::cpu-count)
#-(or sbcl (and ccl darwin)) 1)
#+(or ecl abcl) (pushnew :simple-system *features*)
Defining reader macros
The functions are get-macro-character, set-macro-character (character, function, non-terminating-p, readtable), make-dispatch-macro-character, get-dispatch-macro-character, set-dispatch-macro-character, set-syntax-from-char, copy-readtable, readtablep and read-delimited-list. The reader function receives the stream and the character (and, for a dispatch function, the numeric argument or nil) and returns zero or one object. Changing the standard readtable is not allowed; programs copy it first and bind *readtable*. with-standard-io-syntax binds the reader variables to their standard values.
(defun read-bracket-list (stream char)
(declare (ignore char))
`(list ,@(read-delimited-list #\] stream t)))
(set-macro-character #\[ #'read-bracket-list)
(set-macro-character #\] (get-macro-character #\)))
[1 2 (+ 1 2)] ; reads as (list 1 2 (+ 1 2))
[ ] a meaning. This changes how later text in the same image is read, so a viewer reading the file cannot know it.