Every Emacs Lisp value is an object with a type. Variables have no types; values do. Some objects have a read syntax, so the Lisp reader can build them from source text. Others (buffers, windows, processes) exist only at run time and print in a form the reader rejects. This page lists the types, the syntax of each, the predicates that test them, how equality works and how the types fit together.
Numbers
| Type | Read syntax | Notes |
|---|---|---|
| fixnum | 1, -3, +4, 1., #xff, #o17, #b101, #24r1k | an integer that fits the machine’s tagged-integer range; most-positive-fixnum and most-negative-fixnum give the limits (a trailing dot is an integer, not a float) |
| bignum | the same syntax, larger values | arbitrary precision; the result of integer arithmetic is promoted automatically; bignump and fixnump test the two; bignums are not eq to each other even when equal, so use eql or = |
| float | 1.5, .5, 1e3, -2.5e-3 | IEEE 754 double precision; floatp tests it |
| infinity | 1.0e+INF, -1.0e+INF | read and printed with this exact spelling |
| NaN | 0.0e+NaN, -0.0e+NaN | the sign is kept; a digit string after the decimal point, as in 1.5NaN, sets the payload; isnan tests it, and (= x x) is false for a NaN |
integerp is true for fixnums and bignums, natnump for non-negative integers, numberp for integers and floats, zerop for zero, and number-or-marker-p also admits markers. -0.0 is a different float from 0.0: (= 0.0 -0.0) is true and (eql 0.0 -0.0) is false. The ranges and the arithmetic functions belong to the numbers chapter of the manual; this section covers only the types.
Characters
A character is an integer, so there is no separate character type. Its read syntax is a question mark and the character: ?a is 97, ?\n is 10, ?\C-x is 24, ?\M-x sets the meta bit, ?\x41 and ?\N{LATIN SMALL LETTER A} name the code point. Valid characters run from 0 to (max-char), which is 4194303; the Unicode range is 0 to #x10FFFF and the values above it, up to #x3FFF7F and including the raw-byte range #x3FFF80 to #x3FFFFF, belong to Emacs’s extension. characterp tests an integer for being a character. The escapes are listed in Lexical structure; the character functions are in Strings and characters.
Symbols
A symbol is an object with a name, a value cell, a function cell and a property list. It is the one type that the reader interns: reading the same name twice gives the same object. Symbols are written as their name; characters that would end or change the token are escaped with a backslash.
| Kind | Syntax | Notes |
|---|---|---|
| interned symbol | foo, foo-bar, \,, a\ b | found in the obarray by name; intern makes one, intern-soft only looks |
| keyword | :test | an interned symbol whose name starts with a colon; it evaluates to itself, cannot be set, and keywordp tests it |
| uninterned symbol | #:foo | not in any obarray; make-symbol and gensym create them; two with the same name are different objects; used by macros to avoid capture |
| symbol in another obarray | made with intern and an obarray argument | since Emacs 30 an obarray is its own type, made by obarray-make and tested by obarrayp; before that it was a vector |
| empty name | ## | the interned symbol whose name is the empty string |
| shorthand | my-fn read as my-package-fn | set by the file-local variable read-symbol-shorthands, an alist of (SHORT-PREFIX . LONG-PREFIX); the reader expands the prefix, so the source is shorter than the symbol (Emacs 28 and later) |
nil and t | nil, t | constants that evaluate to themselves; nil is also the empty list and false; every other value is true |
The symbol cells are read with symbol-value, symbol-function and symbol-plist, and symbol-name gives the name. Property lists and the value cell are described in Variables and scope. A symbol with the symbol-with-pos type may appear during byte-compilation; it is not source syntax.
Cons cells and lists
A cons cell is a pair of two slots, the CAR and the CDR. Its read syntax is dotted-pair notation (A . B). A list is a chain of conses whose last CDR is nil; (1 2 3) reads as (1 . (2 . (3 . nil))). The empty list () is the symbol nil. A list that ends in something other than nil is dotted, and one that loops back on itself is circular; the printer writes shared and circular structure with #1= and #1# labels when print-circle is on, and the reader understands them.
(1 . 2) ; a cons cell
(1 2 3) ; a proper list
(1 2 . 3) ; a dotted list
'(a . (b . nil)) ; same object as (a b)
#1=(a . #1#) ; a circular list
| Shape | Form | Typical access |
|---|---|---|
| association list (alist) | ((key . value) (key2 . value2)) | assq, assoc, alist-get; an entry may be written (key value), and then the value is in the CDR as a one-element list |
| property list (plist) | (:name "x" :size 3) | plist-get, plist-put, plist-member; keys compare with eq unless a predicate is passed |
| tree | nested lists | copy-tree, flatten-tree |
The list functions are in Lists and hash tables.
Sequences and arrays
A sequence is a list or an array. An array is a fixed-length object with constant-time access: a vector, a string, a bool-vector or a char-table. sequencep and arrayp test for them; length, elt, copy-sequence, reverse, nreverse and append work across them.
| Type | Read syntax | Notes |
|---|---|---|
| string | "text" | an array of characters; unibyte or multibyte; may carry text properties, read as #("text" 0 2 (face bold)); stringp |
| vector | [1 "two" three] | the elements are not evaluated when a vector is evaluated, so quote is unnecessary; vectorp, make-vector, vector |
| bool-vector | #&5"\37" | a length, then a string holding the bits, low bit first; bool-vector-p, make-bool-vector, bool-vector |
| char-table | #^[…] | maps characters to values, with a default, a parent and extra slots; the printed form is long and implementation-defined; make-char-table, char-table-p, char-table-range, set-char-table-range; used for syntax tables, case tables, display tables and category tables |
| sub-char-table | #^^[…] | an internal node of a char-table, with no use of its own in programs |
Strings are covered in Strings and characters.
Hash tables and records
| Type | Read syntax | Notes |
|---|---|---|
| hash table | #s(hash-table test equal data (k1 v1 k2 v2)) | made by make-hash-table with :test (eq, eql, equal, or one defined by define-hash-table-test), :size, :weakness; access with gethash, puthash, remhash, maphash; the printed form can be read back |
| record | #s(type slot1 slot2) | a fixed-size object whose first slot is a type tag, made by record or make-record; recordp; cl-defstruct and EIEIO classes build on it; type-of returns the tag when it is a symbol |
Function objects
| Type | Predicate | What it is |
|---|---|---|
| symbol with a function definition | fboundp | calling the symbol calls its function cell, following aliases |
| lambda list | functionp | the source form (lambda (x) …); allowed as a function, and the only form before Emacs 30 besides closures |
| interpreted-function | interpreted-function-p | since Emacs 30, what evaluating a lambda or defun yields in the interpreter; laid out like a byte-code function, and printed as #[(x) ((+ x 1)) (t)] with the captured lexical environment in the third slot |
| byte-code function | byte-code-function-p | compiled code: #[ARGS CODE CONSTANTS DEPTH DOC INTERACTIVE]; created by the byte compiler, or by make-byte-code |
| closure | closurep | since Emacs 30, the common parent type of interpreted-function and byte-code-function; a closure holds the lexical variables it captured |
| primitive function (subr) | subrp, primitive-function-p | written in C and shown as #<subr car>; subr-arity gives the argument limits |
| special form | special-form-p | a subr that receives its arguments unevaluated (see Evaluation) |
| macro | macrop | a list (macro . FUNCTION) in a function cell |
| native-compiled function | native-comp-function-p | a subr produced by the native compiler (Native compilation) |
| autoload object | autoloadp | a list (autoload FILE DOC INTERACTIVE TYPE) in a function cell; calling it loads FILE first (Packages and autoloads) |
| oclosure | oclosure-type | a function object that also has named slots and a type (Emacs 29 and later); defined with oclosure-define |
The first three rows of the table above are described further in Functions. functionp is true for any of them, for a symbol that has a function definition, and for the lambda list.
Editing and system types
These objects represent the editor and the system. They have no read syntax; their printed form, in angle brackets, cannot be read back.
| Type | Printed form | Predicate and notes |
|---|---|---|
| buffer | #<buffer name> | bufferp, buffer-live-p; a killed buffer prints as #<killed buffer> |
| marker | #<marker at 10 in name> | markerp; a position that moves with edits; make-marker, point-marker, set-marker |
| window | #<window 3 on name> | windowp, window-live-p |
| frame | #<frame name 0x…> | framep, frame-live-p |
| overlay | #<overlay from 1 to 5 in name> | overlayp; a buffer range carrying properties |
| process | #<process name> | processp |
| thread, mutex, condition variable | #<thread 0x…> | threadp, mutexp, condition-variable-p; cooperative threads, made by make-thread, make-mutex |
| keymap | (keymap …) | keymapp; an ordinary list that starts with the symbol keymap; see Commands and modes |
| finalizer | #<finalizer> | make-finalizer takes a function that runs when the object is garbage-collected |
| user pointer | #<user-ptr …> | user-ptrp; a C pointer held by a dynamic module |
| window configuration, font, tree-sitter objects, syntax table | various | syntax tables are char-tables; see Regexps and syntax tables |
Type predicates
| Predicate | True for |
|---|---|
null | nil only; also the way to write not |
consp | a cons cell |
atom | anything that is not a cons cell, including nil |
listp | a cons cell or nil |
nlistp | anything that is not a list |
proper-list-p | a list that ends in nil and does not loop; returns its length |
symbolp, keywordp, booleanp | a symbol; a keyword; nil or t |
stringp, vectorp, arrayp, sequencep | as named |
integerp, floatp, numberp, natnump, characterp | as named |
functionp, subrp, commandp | callable; a subr; an interactive function |
hash-table-p, recordp, bufferp, markerp, processp | as named |
cl-typep | tests a value against a type specifier from cl-deftype or a built-in type name, including (or …), (member …), (integer LOW HIGH) |
Equality
| Function | Compares |
|---|---|
eq | object identity. Fixnums, symbols and characters of the same value are eq. Floats, bignums and strings are not, unless they are the very same object |
eql | like eq, but numbers of the same type and value are equal; a float compares by its bits, so NaNs of the same payload are eql and 0.0 and -0.0 are not |
equal | structure: conses element by element, strings by characters (not properties), vectors, bool-vectors, records, markers (same buffer and position), char-tables |
equal-including-properties | like equal, and string text properties must match too |
=, /= | numeric value across integer and float; an argument that is not a number or marker is an error |
string=, string-equal | strings or symbols by contents |
Hash tables with :test equal use equal; memq, assq, delq use eq, and member, assoc, delete, remove use equal. Constants written in source may be shared, so two equal literal strings can be one object.
Mutability
Strings, vectors, conses, records, hash tables and char-tables can change in place. Numbers, characters and symbol names cannot. A literal that is quoted in source code ('(1 2 3), "abc", [1 2]) is part of the code, and the byte compiler may store identical literals once and place them in read-only memory. Changing a literal is undefined behaviour. Copy it first with copy-sequence, copy-tree or copy-alist, or build the value with list, vector or make-string. Pure storage is used while Emacs is dumped; the error (setting-constant …) is signalled when a program tries to set a constant such as nil, t or a keyword.
Type hierarchy, type-of and cl-type-of
type-of returns a symbol naming the primitive type of an object: integer, float, symbol, string, cons, vector, bool-vector, char-table, hash-table, subr, buffer, marker, window, frame, process, overlay, thread, mutex, obarray, interpreted-function, byte-code-function and so on; for a record it returns the type tag. cl-type-of (Emacs 30) is more precise: it returns null for nil and boolean for t, and splits integers into fixnum and bignum. The types form a hierarchy (see cl--typeof-types and cl--direct-supertypes-of-type) that cl-typep and cl-defmethod dispatch on.
| Type | Parents |
|---|---|
fixnum, bignum | integer, then number and integer-or-marker, then number-or-marker, then atom, then t |
float | number |
null | boolean, list and symbol |
cons | list, then sequence |
string, vector, bool-vector, char-table | array, then sequence |
interpreted-function, byte-code-function | closure, then function |
subr kinds | primitive-function, special-form, subr-native-elisp |
| everything | t is the root; nil as a type is the empty type |
(type-of 1) ; => integer
(cl-type-of 1) ; => fixnum (Emacs 30)
(type-of nil) ; => symbol
(cl-type-of nil) ; => null (Emacs 30)
(type-of "a") ; => string
(type-of (lambda ())) ; => interpreted-function (Emacs 30)
(cl-typep 3 '(integer 0 10)) ; => t
Not described
Known, not yet covered
- Reference: the full tree of built-in types as returned by
cl--direct-supertypes-of-typeis summarised, not listed; it changed between Emacs 29 and 30. - Reference: printed forms of window configurations, fonts, tree-sitter nodes and parsers, sqlite objects, and the
symbol-with-postype are not given. - Reference: the print variables that control output of the types above (
print-circle,print-length,print-escape-newlines) are not tabulated; the reader side is in Lexical structure.
See also
- Lexical structure – how the reader turns text into these objects
- Lists and hash tables – the functions on conses, alists, plists and hash tables
- Strings and characters – strings, characters and text properties
- Functions – function objects in detail
- Lisp Data Types – the manual’s chapter on types
- Equality Predicates – the manual’s section on
eq,eqlandequal