The following notational conventions are used throughout this document.
Fonts are used in this document to convey information.
Denotes a formal term whose meaning is defined in the Glossary. When this font is used, the Glossary definition takes precedence over normal English usage.
Sometimes a glossary term appears subscripted,
as in “whitespace2.”
Such a notation selects one particular Glossary definition out of several,
in this case the second.
The subscript notation for Glossary terms is generally used where the
context might be insufficient to disambiguate among the available definitions.
Denotes the introduction of a formal term locally to the current text.
There is still a corresponding glossary entry, and is formally equivalent
to a use of “name,” but the hope is that making such uses
conspicuous will save the reader a trip to the glossary in some cases.
Denotes a symbol in the COMMON-LISP
package.
For information about case conventions,
see Section 1.4.1.4.1 (Case in Symbols).
name
Denotes a sample name or piece of code that a programmer might write in Common Lisp.
This font is also used for certain standardized names that are not
names of external symbols of the COMMON-LISP
package,
such as keywords1,
package names,
and loop keywords.
Denotes the name of a parameter or value.
In some situations the notation “«name»” (i.e., the same font, but with surrounding “angle brackets”) is used instead in order to provide better visual separation from surrounding characters. These “angle brackets” are metasyntactic, and never actually appear in program input or output.
This specification uses an extended Backus Normal Form (BNF) to describe the syntax of Common Lisp macro forms and special forms. This section discusses the syntax of BNF expressions.
The primary extension used is the following:
〚O〛
An expression of this form appears whenever a list of elements is to be spliced into a larger structure and the elements can appear in any order. The symbol O represents a description of the syntax of some number of syntactic elements to be spliced; that description must be of the form
O1 | ... | Ol
where each Oi can be of the form S or of the form S* or of the form S¹. The expression 〚O〛 means that a list of the form
(Oi1... Oij) 1≤ j
is spliced into the enclosing expression, such that if n ≠ m and 1≤ n,m≤ j, then either Oin≠ Oim
or Oin = Oim = Qk, where for some 1≤ k ≤ n, Ok is of the form Qk*. Furthermore, for each Oin that is of the form Qk¹, that element is required to appear somewhere in the list to be spliced.
For example, the expression
(x 〚A | B* | C〛 y)
means that at most one A
, any number of B
's, and
at most one C
can occur in any order.
It is a description of any of these:
(x y) (x B A C y) (x A B B B B B C y) (x C B A B B B y)
but not any of these:
(x B B A A C C y) (x C B C y)
In the first case, both A
and C
appear too often,
and in the second case C
appears too often.
The notation 〚O1 | O2 | ...〛+ adds the additional restriction that at least one item from among the possible choices must be used. For example:
(x 〚A | B* | C〛+ y)
means that at most one A
, any number of B
's, and
at most one C
can occur in any order, but that in any case at least
one of these options must be selected.
It is a description of any of these:
(x B y) (x B A C y) (x A B B B B B C y) (x C B A B B B y)
but not any of these:
(x y) (x B B A A C C y) (x C B C y)
In the first case, no item was used;
in the second case, both A
and C
appear too often;
and in the third case C
appears too often.
Also, the expression:
(x 〚A¹ | B¹ | C〛 y)
can generate exactly these and no others:
(x A B C y) (x A C B y) (x A B y) (x B A C y) (x B C A y) (x B A y) (x C A B y) (x C B A y)
An indirection extension is introduced in order to make this new syntax more readable:
↓O
If O is a non-terminal symbol, the right-hand side of its definition is substituted for the entire expression ↓O. For example, the following BNF is equivalent to the BNF in the previous example:
(x 〚
↓O〛 y)
A
| B
* | C
In some cases, an auxiliary definition in the BNF might appear to be unused within the BNF, but might still be useful elsewhere. For example, consider the following definitions:
Here the term “clause” might appear to be “dead” in that it is not used in the BNF. However, the purpose of the BNF is not just to guide parsing, but also to define useful terms for reference in the descriptive text which follows. As such, the term “clause” might appear in text that follows, as shorthand for “normal-clause or otherwise-clause.”
The special symbols described here are used as a notational convenience within this document, and are part of neither the Common Lisp language nor its environment.
This indicates evaluation. For example:
(+ 4 5) → 9
This means that the result of
evaluating the form (+ 4 5)
is 9
.
If a form returns multiple values, those values might be shown separated by spaces, line breaks, or commas. For example:
(truncate 7 5) → 1 2 (truncate 7 5) → 1 2 (truncate 7 5) → 1, 2
Each of the above three examples is equivalent, and specifies
that (truncate 7 5)
returns two values, which are 1
and 2
.
Some conforming implementations actually type an arrow (or some
other indicator) before showing return values, while others do not.
The notation “or→” is used to denote one of several possible alternate results. The example
(char-name #\a) → NIL or→ "LOWERCASE-a" or→ "Small-A" or→ "LA01"
indicates that nil
, "LOWERCASE-a"
, "Small-A"
, "LA01"
are
among the possible results of (char-name #\a)
—each with equal preference.
Unless explicitly specified otherwise, it should not be assumed that the set of possible
results shown is exhaustive.
Formally, the above example is equivalent to
(char-name #\a) → implementation-dependent
but it is intended to provide additional information to illustrate some
of the ways in which it is permitted for implementations to diverge.
The notation “not→” is used to denote a result which is not possible. This might be used, for example, in order to emphasize a situation where some anticipated misconception might lead the reader to falsely believe that the result might be possible. For example,
(function-lambda-expression (funcall #'(lambda (x) #'(lambda () x)) nil)) → NIL, true, NIL or→ (LAMBDA () X), true, NIL not→ NIL, false, NIL not→ (LAMBDA () X), false, NIL
This indicates code equivalence. For example:
(gcd x (gcd y z)) ≡ (gcd (gcd x y) z)
This means that the results and observable side-effects of evaluating
the form
(gcd x (gcd y z))
are always the same as the results
and observable side-effects of
(gcd (gcd x y) z)
for any
x
, y
, and z
.
Common Lisp specifies input and output with respect to a non-interactive stream model. The specific details of how interactive input and output are mapped onto that non-interactive model are implementation-defined.
For example, conforming implementations are permitted to differ in issues
of how interactive input is terminated. For example, the function read
terminates when the final delimiter is typed on a non-interactive stream.
In some implementations, an interactive call to read
returns
as soon as the final delimiter is typed, even if that delimiter is not a newline.
In other implementations, a final newline is always required.
In still other implementations, there might be a command which “activates”
a buffer full of input without the command itself being visible on the program's
input stream.
In the examples in this document, the notation “▷” precedes lines where interactive input and output occurs. Within such a scenario, “this notation” notates user input.
For example, the notation
(+ 1 (print (+ (sqrt (read)) (sqrt (read)))))
▷ 9 16
▷ 7
→ 8
shows an interaction in which
“(+ 1 (print (+ (sqrt (read)) (sqrt (read)))))
”
is a form to be evaluated,
“9 16
” is interactive input,
“7
” is interactive output, and
“8
” is the value yielded from the evaluation.
The use of this notation is intended to disguise small differences in interactive input and output behavior between implementations.
Sometimes, the non-interactive stream model calls for a newline. How that newline character is interactively entered is an implementation-defined detail of the user interface, but in that case, either the notation “<Newline>” or “↩” might be used.
(progn (format t "~&Who? ") (read-line))
▷ Who? Fred, Mary, and Sally↩
→ "Fred, Mary, and Sally", false
Some objects in Common Lisp can be notated in more than one way. In such situations, the choice of which notation to use is technically arbitrary, but conventions may exist which convey a “point of view” or “sense of intent.”
While case is significant in the process of interning a symbol,
the Lisp reader, by default, attempts to canonicalize the case of a
symbol prior to interning; see Section 23.1.2 (Effect of Readtable Case on the Lisp Reader).
As such, case in symbols is not, by default, significant.
Throughout this document, except as explicitly noted otherwise,
the case in which a symbol appears is not significant;
that is, HELLO
, Hello
, hElLo
, and hello
are
all equivalent ways to denote a symbol whose name is "HELLO"
.
The characters backslash and vertical-bar are used to explicitly
quote the case and other parsing-related
aspects
of characters. As such,
the notations |hello|
and \h\e\l\l\o
are equivalent ways
to refer to a symbol whose name is "hello"
, and which is distinct from
any symbol whose name is "HELLO"
.
The symbols that correspond to Common Lisp defined names have uppercase names even though their names generally appear in lowercase in this document.
Although Common Lisp provides a variety of ways for programs to manipulate the input and output radix for rational numbers, all numbers in this document are in decimal notation unless explicitly noted otherwise.
The dot appearing by itself in an expression such as
(
item1 item2 .
tail)
means that tail represents a list of objects at the end of a list. For example,
(A B C . (D E F))
is notationally equivalent to:
(A B C D E F)
Although dot is a valid constituent character in a symbol, no
standardized symbols contain the character dot,
so a period that follows a reference to a symbol at the end of
a sentence in this document should always be interpreted as a period
and never as part of the symbol's name.
For example, within this document, a sentence such as
“This sample sentence refers to the symbol car
.”
refers to a symbol whose name is "CAR"
(with three letters),
and never to a four-letter symbol "CAR."
nil
has a variety of meanings.
It is a symbol in the COMMON-LISP
package with the name "NIL"
,
it is boolean (and generalized boolean) false,
it is the empty list,
and it is the name of the empty type (a subtype of all types).
Within Common Lisp, nil
can be notated interchangeably as either NIL
or ()
.
By convention, the choice of notation offers a hint as to which of its many
roles it is playing.
|
Figure 1.1: Notations for NIL
Within this document only, nil
is also sometimes notated as false to
emphasize its role as a boolean.
For example:
(print ()) ;avoided (defun three nil 3) ;avoided '(nil nil) ;list of two symbols '(() ()) ;list of empty lists (defun three () 3) ;Emphasize empty parameter list. (append '() '()) → () ;Emphasize use of empty lists (not nil) → true ;Emphasize use as Boolean false (get 'nil 'color) ;Emphasize use as a symbol
A function is sometimes said to “be false” or “be true”
in some circumstance.
Since no function object can be the same as nil
and all function objects represent true when viewed as booleans,
it would be meaningless to say that the function was literally false
and uninteresting to say that it was literally true.
Instead, these phrases are just traditional alternative ways of saying that the
function “returns false” or “returns true,” respectively.
A designator is an object that denotes another object.
Where a parameter of an operator is described as a designator, the description of the operator is written in a way that assumes that the value of the parameter is the denoted object; that is, that the parameter is already of the denoted type. (The specific nature of the object denoted by a “«type» designator” or a “designator for a «type»” can be found in the Glossary entry for “«type» designator.”)
For example, “nil
” and “the value of *standard-output*
” are operationally
indistinguishable as stream designators. Similarly,
the symbol foo
and the string "FOO"
are operationally indistinguishable as string designators.
Except as otherwise noted, in a situation where the denoted object might be used multiple times, it is implementation-dependent whether the object is coerced only once or whether the coercion occurs each time the object must be used.
For example, mapcar
receives a function designator as an argument,
and its description is written as if this were simply a function. In fact, it
is implementation-dependent whether the function designator is
coerced right away or whether it is carried around internally in the form that
it was given as an argument and re-coerced each time it is needed. In most
cases, conforming programs cannot detect the distinction, but there are some
pathological situations (particularly those involving self-redefining or
mutually-redefining functions) which do conform and which can detect this difference.
The following program is a conforming program, but might or might not have
portably correct results, depending on whether its correctness depends on one or
the other of the results:
(defun add-some (x) (defun add-some (x) (+ x 2)) (+ x 1)) → ADD-SOME (mapcar 'add-some '(1 2 3 4)) → (2 3 4 5) or→ (2 4 5 6)
In a few rare situations, there may be a need in a dictionary entry to refer to the object that was the original designator for a parameter. Since naming the parameter would refer to the denoted object, the phrase “the «parameter-name» designator” can be used to refer to the designator which was the argument from which the value of «parameter-name» was computed.
When a word having no pre-attached semantics is required (e.g., in an example), it is common in the Lisp community to use one of the words “foo,” “bar,” “baz,” and “quux.” For example, in
(defun foo (x) (+ x 1))
the use of the name foo
is just a shorthand way of saying
“please substitute your favorite name here.”
These nonsense words have gained such prevalance of usage, that it is commonplace for newcomers to the community to begin to wonder if there is an attached semantics which they are overlooking—there is not.