Next: , Up: Definitions


1.4.1 Notational Conventions

The following notational conventions are used throughout this document.

1.4.1.1 Font Key

Fonts are used in this document to convey information.

name

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.

name

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.

name

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.

name

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.

1.4.1.2 Modified BNF Syntax

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.

1.4.1.2.1 Splicing in Modified BNF Syntax

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)
1.4.1.2.2 Indirection in Modified BNF Syntax

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)

O::=
A | B* | C
1.4.1.2.3 Additional Uses for Indirect Definitions in Modified BNF Syntax

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:

— Macro: case keyform {normal-clause}* [otherwise-clause] {result}*
— Macro: ccase keyplace {normal-clause}* {result}*
— Macro: ecase keyform {normal-clause}* {result}*
normal-clause::=
(keys {form}*)
otherwise-clause::=
({otherwise | t} {form}*)
clause::=
normal-clause | otherwise-clause

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.”

1.4.1.3 Special Symbols

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.

or

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.

not

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
1.4.1.4 Objects with Multiple Notations

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.”

1.4.1.4.1 Case in Symbols

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.

1.4.1.4.2 Numbers

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.

1.4.1.4.3 Use of the Dot Character

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."

1.4.1.4.4 NIL

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.

For Evaluation? Notation Typically Implied Role
Yes nil use as a boolean.
Yes 'nil use as a symbol.
Yes '() use as an empty list
No nil use as a symbol or boolean.
No () use as an empty list.

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.

1.4.1.5 Designators

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.

1.4.1.6 Nonsense Words

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.