Skip to main content

*readtable*

readtable∗ Variable

Value Type:

a readtable.

Initial Value:

A readtable that conforms to the description of Common Lisp syntax in Chapter 2 (Syntax).

Description:

The value of *readtable* is called the current readtable. It controls the parsing behavior of the Lisp reader , and can also influence the Lisp printer (e.g., see the function readtable-case).

Examples:

(readtablep \*readtable\*) → true 

(setq zvar 123)123
(set-syntax-from-char #\z #\’ (setq table2 (copy-readtable))) → T
zvar → 123
(setq \*readtable\* table2) → #<READTABLE>
zvar → VAR
(setq \*readtable\* (copy-readtable nil)) → #<READTABLE>
zvar → 123

Affected By:

compile-file, load

See Also:

compile-file, load, readtable, Section 2.1.1.1 (The Current Readtable)

Expanded Reference: *readtable*

Inspecting the current readtable

*readtable* holds the current readtable, which controls how the Lisp reader parses input.

(readtablep *readtable*)
=> T

(readtable-case *readtable*)
=> :UPCASE

Binding a modified readtable locally

The standard idiom for making temporary readtable modifications is to bind *readtable* to a copy.

(let ((*readtable* (copy-readtable)))
(setf (readtable-case *readtable*) :preserve)
(symbol-name (read-from-string "Hello")))
=> "Hello"

;; Outside the LET, the original readtable is still in effect
(readtable-case *readtable*)
=> :UPCASE

Resetting to the standard readtable

Assigning a copy of the standard readtable (via nil) restores standard syntax.

(let ((*readtable* (copy-readtable)))
;; Make a modification
(set-syntax-from-char #\z #\' *readtable*)
;; Reset to standard
(setf *readtable* (copy-readtable nil))
;; Now z is a normal constituent again
(with-input-from-string (s "zebra")
(read s)))
=> ZEBRA

Custom reader syntax via readtable

All reader macros and syntax changes operate through the current readtable.

(let ((*readtable* (copy-readtable)))
(set-macro-character #\@
(lambda (stream char)
(declare (ignore char))
(list 'at-sign (read stream t nil t))))
(with-input-from-string (s "@foo")
(read s)))
=> (AT-SIGN FOO)