2.4 Standard Macro Characters
If the reader encounters a macro character , then its associated reader macro function is invoked and may produce an object to be returned. This function may read the characters following the macro character in the stream in any syntax and return the object represented by that syntax.
Any character can be made to be a macro character . The macro characters defined initially in a conforming implementation include the following:
2.4.1 Left
The left-parenthesis initiates reading of a list. read is called recursively to read successive objects until a right parenthesis is found in the input stream. A list of the objects read is returned. Thus
(a b c)
is read as a list of three objects (the symbols a, b, and c). The right parenthesis need not immediately follow the printed representation of the last object; whitespace2 characters and comments may precede it.
If no objects precede the right parenthesis, it reads as a list of zero objects (the empty list).
If a token that is just a dot not immediately preceded by an escape character is read after some object then exactly one more object must follow the dot, possibly preceded or followed by whitespace2 or a comment, followed by the right parenthesis:
(a b c . d)
This means that the cdr of the last cons in the list is not nil, but rather the object whose representation followed the dot. The above example might have been the result of evaluating
(cons ’a (cons ’b (cons ’c ’d)))
Similarly,
(cons ’this-one ’that-one) → (this-one . that-one)
It is permissible for the object following the dot to be a list:
(a b c d . (e f . (g))) ≡ (a b c d e f g)
For information on how the Lisp printer prints lists and conses, see Section 22.1.3.5 (Printing Lists and Conses).
2.4.2 Right
The right-parenthesis is invalid except when used in conjunction with the left parenthesis character. For more information, see Section 2.2 (Reader Algorithm).
2.4.3 Single
Syntax: ’⟨exp⟩
A single-quote introduces an expression to be “quoted.” Single-quote followed by an expression exp is treated by the Lisp reader as an abbreviation for and is parsed identically to the expression (quote exp). See the special operator quote.
2.4.3.1 Examples of Single
’foo → FOO
”foo → (QUOTE FOO)
(car ”foo) → QUOTE
2.4.4 Semicolon
Syntax: ;⟨text⟩
A semicolon introduces characters that are to be ignored, such as comments. The semicolon and all characters up to and including the next newline or end of file are ignored.
2.4.4.1 Examples of Semicolon
(+ 3 ; three
\4)
→ 7
2.4.4.2 Notes about Style for Semicolon
Some text editors make assumptions about desired indentation based on the number of semicolons that begin a comment. The following style conventions are common, although not by any means universal.
2.4.4.2.1 Use of Single Semicolon
Comments that begin with a single semicolon are all aligned to the same column at the right (sometimes called the “comment column”). The text of such a comment generally applies only to the line on which it appears. Occasionally two or three contain a single sentence together; this is sometimes indicated by indenting all but the first with an additional space (after the semicolon).
2.4.4.2.2 Use of Double Semicolon
Comments that begin with a double semicolon are all aligned to the same level of indentation as a form would be at that same position in the code. The text of such a comment usually describes the state of the program at the point where the comment occurs, the code which follows the comment, or both.
2.4.4.2.3 Use of Triple Semicolon
Comments that begin with a triple semicolon are all aligned to the left margin. Usually they are used prior to a definition or set of definitions, rather than within a definition.
2.4.4.2.4 Use of Quadruple Semicolon
Comments that begin with a quadruple semicolon are all aligned to the left margin, and generally contain only a short piece of text that serve as a title for the code which follows, and might be used in the header or footer of a program that prepares code for presentation as a hardcopy document.
2.4.4.2.5 Examples of Style for Semicolon
;;;; Math Utilities
;;; FIB computes the the Fibonacci function in the traditional
;;; recursive way.
(defun fib (n)
(check-type n integer)
;; At this point we’re sure we have an integer argument.
;; Now we can get down to some serious computation.
(cond ((< n 0)
;; Hey, this is just supposed to be a simple example.
;; Did you really expect me to handle the general case?
(error "FIB got ~D as an argument." n))
((< n 2) n) ;fib[0]=0 and fib[1]=1
;; The cheap cases didn’t work.
;; Nothing more to do but recurse.
(t (+ (fib (- n 1)) ;The traditional formula
(fib (- n 2)))))) ; is fib[n-1]+fib[n-2].
2.4.5 Double
Syntax: "⟨text⟩"
The double-quote is used to begin and end a string. When a double-quote is encountered, characters are read from the input stream and accumulated until another double-quote is encountered. If a single escape character is seen, the single escape character is discarded, the next character is accumulated, and accumulation continues. The accumulated characters up to but not including the matching double-quote are made into a simple string and returned. It is implementation-dependent which attributes of the accumulated characters are removed in this process.
Examples of the use of the double-quote character are in Figure 2–18.
|
"Foo" ;A string with three characters in it "" ;An empty string
""APL\360?" he cried." ;A string with twenty characters
"|x| = |-x|" ;A ten-character string
|| :- |
Figure 2–18. Examples of the use of double-quote
Note that to place a single escape character or a double-quote into a string, such a character must be preceded by a single escape character. Note, too, that a multiple escape character need not be quoted by a single escape character within a string.
For information on how the Lisp printer prints strings, see Section 22.1.3.4 (Printing Strings).
2.4.6 Backquote
The backquote introduces a template of a data structure to be built. For example, writing ‘(cond ((numberp ,x) ,@y) (t (print ,x) ,@y))
is roughly equivalent to writing
(list ’cond
(cons (list ’numberp x) y)
(list* ’t (list ’print x) y))
Where a comma occurs in the template, the expression following the comma is to be evaluated to produce an object to be inserted at that point. Assume b has the value 3, for example, then evaluating the form denoted by ‘(a b ,b ,(+ b 1) b) produces the result (a b 3 4 b).
If a comma is immediately followed by an at-sign, then the form following the at-sign is evaluated to produce a list of objects. These objects are then “spliced” into place in the template. For example, if x has the value (a b c), then
‘(x ,x ,@x foo ,(cadr x) bar ,(cdr x) baz ,@(cdr x))
→ (x (a b c) a b c foo b bar (b c) baz b c)
The backquote syntax can be summarized formally as follows.
• ‘basic is the same as ’basic, that is, (quote basic), for any expression basic that is not a list or a general vector .
• ‘,form is the same as form, for any form, provided that the representation of form does not begin with at-sign or dot. (A similar caveat holds for all occurrences of a form after a comma.)
• ‘,@form has undefined consequences.
• ‘(x1 x2 x3 ... xn . atom) may be interpreted to mean
(append [x1] [x2] [x3] ... [xn] (quote atom))
where the brackets are used to indicate a transformation of an xj as follows:
– [form] is interpreted as (list ‘form), which contains a backquoted form that must then be further interpreted.
– [,form] is interpreted as (list form).
– [,@form] is interpreted as form.
• ‘(x1 x2 x3 ... xn) may be interpreted to mean the same as the backquoted form ‘(x1 x2 x3 ... xn . nil), thereby reducing it to the previous case.
• ‘(x1 x2 x3 ... xn . ,form) may be interpreted to mean
(append [x1] [x2] [x3] ... [xn] form)
where the brackets indicate a transformation of an xj as described above.
• ‘(x1 x2 x3 ... xn . ,@form) has undefined consequences.
• ‘#(x1 x2 x3 ... xn) may be interpreted to mean (apply #’vector ‘(x1 x2 x3 ... xn)).
Anywhere “,@” may be used, the syntax “,.” may be used instead to indicate that it is permissible to operate destructively on the list structure produced by the form following the “,.” (in effect, to use nconc instead of append).
If the backquote syntax is nested, the innermost backquoted form should be expanded first. This means that if several commas occur in a row, the leftmost one belongs to the innermost backquote.
An implementation is free to interpret a backquoted form F1 as any form F2 that, when evaluated, will produce a result that is the same under equal as the result implied by the above definition, provided that the side-effect behavior of the substitute form F2 is also consistent with the
description given above. The constructed copy of the template might or might not share list structure with the template itself. As an example, the above definition implies that
‘((,a b) ,c ,@d)
will be interpreted as if it were
(append (list (append (list a) (list ’b) ’nil)) (list c) d ’nil)
but it could also be legitimately interpreted to mean any of the following:
(append (list (append (list a) (list ’b))) (list c) d)
(append (list (append (list a) ’(b))) (list c) d)
(list* (cons a ’(b)) c d)
(list* (cons a (list ’b)) c d)
(append (list (cons a ’(b))) (list c) d)
(list* (cons a ’(b)) c (copy-list d))
2.4.6.1 Notes about Backquote
Since the exact manner in which the Lisp reader will parse an expression involving the backquote reader macro is not specified, an implementation is free to choose any representation that preserves the semantics described.
Often an implementation will choose a representation that facilitates pretty printing of the expression, so that (pprint ‘(a ,b)) will display ‘(a ,b) and not, for example, (list ’a b). However, this is not a requirement.
Implementors who have no particular reason to make one choice or another might wish to refer to IEEE Standard for the Scheme Programming Language, which identifies a popular choice of representation for such expressions that might provide useful to be useful compatibility for some user communities. There is no requirement, however, that any conforming implementation use this particular representation. This information is provided merely for cross-reference purposes.
2.4.7 Comma
The comma is part of the backquote syntax; see Section 2.4.6 (Backquote). Comma is invalid if used other than inside the body of a backquote expression as described above.
2.4.8 Sharpsign
Sharpsign is a non-terminating dispatching macro character . It reads an optional sequence of digits and then one more character, and uses that character to select a function to run as a reader macro function.
The standard syntax includes constructs introduced by the # character. The syntax of these constructs is as follows: a character that identifies the type of construct is followed by arguments in some form. If the character is a letter, its case is not important; #O and #o are considered to be equivalent, for example.
Certain # constructs allow an unsigned decimal number to appear between the # and the character.
The reader macros associated with the dispatching macro character # are described later in this section and summarized in Figure 2–19.
|dispatch char purpose dispatch char purpose|
| :- |
|
Backspace signals error { undefined* Tab signals error } undefined* Newline signals error + read-time conditional Linefeed signals error - read-time conditional Page signals error . read-time evaluation Return signals error / undefined Space signals error A, a array
! undefined* B, b binary rational " undefined C, c complex number # reference to = label D, d undefined $ undefined E, e undefined % undefined F, f undefined & undefined G, g undefined ’ function abbreviation H, h undefined ( simple vector I, i undefined ) signals error J, j undefined * bit vector K, k undefined , undefined L, l undefined : uninterned symbol M, m undefined ; undefined N, n undefined < signals error O, o octal rational = labels following object P, p pathname > undefined Q, q undefined ? undefined* R, r radix-n rational @ undefined S, s structure [ undefined* T, t undefined \ character object U, u undefined ] undefined* V, v undefined ∧ undefined W, w undefined undefined X, x hexadecimal rational
‘ undefined Y, y undefined | balanced comment Z, z undefined ~ undefined Rubout undefined
|Figure 2–19. Standard # Dispatching Macro Character Syntax
The combinations marked by an asterisk (*) are explicitly reserved to the user. No conforming implementation defines them.
Note also that digits do not appear in the preceding table. This is because the notations #0, #1, ..., #9 are reserved for another purpose which occupies the same syntactic space. When a digit follows a sharpsign, it is not treated as a dispatch character. Instead, an unsigned integer argument is
accumulated and passed as an argument to the reader macro for the character that follows the digits. For example, #2A((1 2) (3 4)) is a use of #A with an argument of 2.
2.4.8.1 Sharpsign Backslash
Syntax: #\⟨x⟩
When the token x is a single character long, this parses as the literal character char. Uppercase and lowercase letters are distinguished after #; #\A and #\a denote different character objects. Any single character works after #, even those that are normally special to read, such as left-parenthesis and right-parenthesis.
In the single character case, the x must be followed by a non-constituent character . After #\ is read, the reader backs up over the slash and then reads a token, treating the initial slash as a single escape character (whether it really is or not in the current readtable).
When the token x is more than one character long, the x must have the syntax of a symbol with no embedded package markers. In this case, the sharpsign backslash notation parses as the character whose name is (string-upcase x); see Section 13.1.7 (Character Names).
For information about how the Lisp printer prints character objects, see Section 22.1.3.2 (Printing Characters).
2.4.8.2 Sharpsign Single
Any expression preceded by #’ (sharpsign followed by single-quote), as in #’expression, is treated by the Lisp reader as an abbreviation for and parsed identically to the expression (function expression). See function. For example,
(apply #’+ l) ≡ (apply (function +) l)
2.4.8.3 Sharpsign Left
#( and ) are used to notate a simple vector .
If an unsigned decimal integer appears between the # and (, it specifies explicitly the length of the vector . The consequences are undefined if the number of objects specified before the closing ) exceeds the unsigned decimal integer. If the number of objects supplied before the closing ) is less than the unsigned decimal integer but greater than zero, the last object is used to fill all remaining elements of the vector . The consequences are undefined if the unsigned decimal integer is non-zero and number of objects supplied before the closing ) is zero. For example,
#(a b c c c c)
#6(a b c c c c)
#6(a b c)
#6(a b c c)
all mean the same thing: a vector of length 6 with elements a, b, and four occurrences of c. Other examples follow:
#(a b c) ;A vector of length 3
#(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47)
;A vector containing the primes below 50
#() ;An empty vector
The notation #() denotes an empty vector , as does #0().
For information on how the Lisp printer prints vectors, see Section 22.1.3.4 (Printing Strings), Section 22.1.3.6 (Printing Bit Vectors), or Section 22.1.3.7 (Printing Other Vectors).
2.4.8.4 Sharpsign Asterisk
Syntax: #*⟨bits⟩
A simple bit vector is constructed containing the indicated bits (0’s and 1’s), where the leftmost bit has index zero and the subsequent bits have increasing indices.
Syntax: #⟨n⟩*⟨bits⟩
With an argument n, the vector to be created is of length n. If the number of bits is less than n but greater than zero, the last bit is used to fill all remaining bits of the bit vector .
The notations #* and #0* each denote an empty bit vector .
Regardless of whether the optional numeric argument n is provided, the token that follows the asterisk is delimited by a normal token delimiter. However, (unless the value of *read-suppress* is true) an error of type reader-error is signaled if that token is not composed entirely of 0’s and 1’s, or if n was supplied and the token is composed of more than n bits, or if n is greater than one, but no bits were specified. Neither a single escape nor a multiple escape is permitted in this token.
For information on how the Lisp printer prints bit vectors, see Section 22.1.3.6 (Printing Bit Vectors).
2.4.8.4.1 Examples of Sharpsign Asterisk
For example, #\*101111
#6\*101111
#6\*101
#6\*1011
all mean the same thing: a *vector* of length 6 with *elements* 1, 0, 1, 1, 1, and 1.
For example:
#\* ;An empty bit-vector
2.4.8.5 Sharpsign Colon
Syntax: #:⟨symbol-name⟩
#: introduces an uninterned symbol whose name is symbol-name. Every time this syntax is encountered, a distinct uninterned symbol is created. The symbol-name must have the syntax of a symbol with no package prefix .
For information on how the Lisp reader prints uninterned symbols, see Section 22.1.3.3 (Printing Symbols).
2.4.8.6 Sharpsign Dot
#.foo is read as the object resulting from the evaluation of the object represented by foo. The evaluation is done during the read process, when the #. notation is encountered. The #. syntax therefore performs a read-time evaluation of foo.
The normal effect of #. is inhibited when the value of *read-eval* is false. In that situation, an error of type reader-error is signaled.
For an object that does not have a convenient printed representation, a form that computes the object can be given using the #. notation.
2.4.8.7 Sharpsign B
#Brational reads rational in binary (radix 2). For example,
#B1101 ≡ 13 ;11012
#b101/11 ≡ 5/3
The consequences are undefined if the token immediately following the #B does not have the syntax of a binary (i.e., radix 2) rational.
2.4.8.8 Sharpsign O
#Orational reads rational in octal (radix 8). For example,
#o37/15 ≡ 31/13
#o777 ≡ 511
#o105 ≡ 69 ;1058
The consequences are undefined if the token immediately following the #O does not have the syntax of an octal (i.e., radix 8) rational.
2.4.8.9 Sharpsign X
#Xrational reads rational in hexadecimal (radix 16). The digits above 9 are the letters A through F (the lowercase letters a through f are also acceptable). For example,
#xF00 ≡ 3840
#x105 ≡ 261 ;10516
The consequences are undefined if the token immediately following the #X does not have the syntax of a hexadecimal (i.e., radix 16) rational.
2.4.8.10 Sharpsign R
#nR
#radixRrational reads rational in radix radix. radix must consist of only digits that are interpreted as an integer in decimal radix; its value must be between 2 and 36 (inclusive). Only valid digits for the specified radix may be used.
For example, #3r102 is another way of writing 11 (decimal), and #11R32 is another way of writing 35 (decimal). For radices larger than 10, letters of the alphabet are used in order for the digits after 9. No alternate # notation exists for the decimal radix since a decimal point suffices.
Figure 2–20 contains examples of the use of #B, #O, #X, and #R.
|
#2r11010101 ;Another way of writing 213 decimal
#b11010101 ;Ditto
#b+11010101 ;Ditto
#o325 ;Ditto, in octal radix
#xD5 ;Ditto, in hexadecimal radix
#16r+D5 ;Ditto
#o-300 ;Decimal -192, written in base 8
#3r-21010 ;Same thing in base 3
#25R-7H ;Same thing in base 25
#xACCEDED ;181202413, in hexadecimal radix
|| :- |
Figure 2–20. Radix Indicator Example
The consequences are undefined if the token immediately following the #nR does not have the syntax of a rational in radix n.
2.4.8.11 Sharpsign C
#C reads a following object, which must be a list of length two whose elements are both reals. These reals denote, respectively, the real and imaginary parts of a complex number. If the two parts as notated are not of the same data type, then they are converted according to the rules of floating-point contagion described in Section 12.1.1.2 (Contagion in Numeric Operations).
#C(real imag) is equivalent to #.(complex (quote real) (quote imag)), except that #C is not affected by *read-eval*. See the function complex.
Figure 2–21 contains examples of the use of #C.
|
#C(3.0s1 2.0s-1) ;A complex with small float parts.
#C(5 -3) ;A “Gaussian integer”
#C(5/3 7.0) ;Will be converted internally to #C(1.66666 7.0) #C(0 1) ;The imaginary unit; that is, i.
|| :- |
Figure 2–21. Complex Number Example
For further information, see Section 22.1.3.1.4 (Printing Complexes) and Section 2.3.2.3 (Syntax of a Complex).
2.4.8.12 Sharpsign A
#nA
#nAobject constructs an n-dimensional array, using object as the value of the :initial-contents argument to make-array.
For example, #2A((0 1 5) (foo 2 (hot dog))) represents a 2-by-3 matrix:
0 1 5
foo 2 (hot dog)
In contrast, #1A((0 1 5) (foo 2 (hot dog))) represents a vector of length 2 whose elements are lists:
(0 1 5) (foo 2 (hot dog))
#0A((0 1 5) (foo 2 (hot dog))) represents a zero-dimensional array whose sole element is a list: ((0 1 5) (foo 2 (hot dog)))
#0A foo represents a zero-dimensional array whose sole element is the symbol foo. The notation #1A foo is not valid because foo is not a sequence.
If some dimension of the array whose representation is being parsed is found to be 0, all dimensions to the right (i.e., the higher numbered dimensions) are also considered to be 0.
For information on how the Lisp printer prints arrays, see Section 22.1.3.4 (Printing Strings), Section 22.1.3.6 (Printing Bit Vectors), Section 22.1.3.7 (Printing Other Vectors), or Section 22.1.3.8 (Printing Other Arrays).
2.4.8.13 Sharpsign S
#s(name slot1 value1 slot2 value2 ...) denotes a structure. This is valid only if name is the name of a structure type already defined by defstruct and if the structure type has a standard constructor function. Let cm stand for the name of this constructor function; then this syntax is equivalent to
#.(cm keyword1 ’value1 keyword2 ’value2 ...)
where each keywordj is the result of computing
(intern (string slotj) (find-package ’keyword))
The net effect is that the constructor function is called with the specified slots having the specified values. (This coercion feature is deprecated; in the future, keyword names will be taken in the package they are read in, so symbols that are actually in the KEYWORD package should be used if that is what is desired.)
Whatever object the constructor function returns is returned by the #S syntax.
For information on how the Lisp printer prints structures, see Section 22.1.3.12 (Printing Structures).
2.4.8.14 Sharpsign P
#P reads a following object, which must be a string.
#P⟨expression⟩ is equivalent to #.(parse-namestring ’⟨expression⟩), except that #P is not affected by *read-eval*.
For information on how the Lisp printer prints pathnames, see Section 22.1.3.11 (Printing Pathnames).
2.4.8.15 Sharpsign Equal
#n=
#n=object reads as whatever object has object as its printed representation. However, that object is labeled by n, a required unsigned decimal integer, for possible reference by the syntax #n#. The scope of the label is the expression being read by the outermost call to read; within this expression, the same label may not appear twice.
2.4.8.16 Sharpsign Sharpsign
#n#
#n#, where n is a required unsigned decimal integer , provides a reference to some object labeled by #n=; that is, #n# represents a pointer to the same (eq) object labeled by #n=. For example, a structure created in the variable y by this code:
(setq x (list ’p ’q))
(setq y (list (list ’a ’b) x ’foo x))
(rplacd (last y) (cdr y))
could be represented in this way:
((a b) . #1=(#2=(p q) foo #2# . #1#))
Without this notation, but with *print-length* set to 10 and *print-circle* set to nil, the structure would print in this way:
((a b) (p q) foo (p q) (p q) foo (p q) (p q) foo (p q) ...)
A reference #n# may only occur after a label #n=; forward references are not permitted. The reference may not appear as the labeled object itself (that is, #n=#n#) may not be written because the object labeled by #n= is not well defined in this case.
2.4.8.17 Sharpsign Plus
#+ provides a read-time conditionalization facility; the syntax is #+test expression. If the feature expression test succeeds, then this textual notation represents an object whose printed representation is expression. If the feature expression test fails, then this textual notation is treated as whitespace2; that is, it is as if the “#+ test expression” did not appear and only a space appeared in its place.
For a detailed description of success and failure in feature expressions, see Section 24.1.2.1 (Feature Expressions).
#+ operates by first reading the feature expression and then skipping over the form if the feature expression fails. While reading the test, the current package is the KEYWORD package. Skipping over the form is accomplished by binding *read-suppress* to true and then calling read.
For examples, see Section 24.1.2.1.1 (Examples of Feature Expressions).
2.4.8.18 Sharpsign Minus
#- is like #+ except that it skips the expression if the test succeeds; that is,
#-test expression ≡ #+(not test) expression
For examples, see Section 24.1.2.1.1 (Examples of Feature Expressions).
2.4.8.19 Sharpsign Vertical
#|...|# is treated as a comment by the reader. It must be balanced with respect to other occurrences of #| and |#, but otherwise may contain any characters whatsoever.
2.4.8.19.1 Examples of Sharpsign Vertical
The following are some examples that exploit the #|...|# notation:
;;; In this example, some debugging code is commented out with #|...|#
;;; Note that this kind of comment can occur in the middle of a line
;;; (because a delimiter marks where the end of the comment occurs)
;;; where a semicolon comment can only occur at the end of a line
;;; (because it comments out the rest of the line).
(defun add3 (n) #|(format t "~&Adding 3 to ~D." n)|# (+ n 3))
;;; The examples that follow show issues related to #| ... |# nesting.
;;; In this first example, #| and |# always occur properly paired,
;;; so nesting works naturally.
(defun mention-fun-fact-1a ()
(format t "CL uses ; and #|...|# in comments."))
→ MENTION-FUN-FACT-1A
(mention-fun-fact-1a)
▷ CL uses ; and #|...|# in comments.
→ NIL
#| (defun mention-fun-fact-1b ()
(format t "CL uses ; and #|...|# in comments.")) |#
(fboundp ’mention-fun-fact-1b) → NIL
;;; In this example, vertical-bar followed by sharpsign needed to appear
;;; in a string without any matching sharpsign followed by vertical-bar
;;; having preceded this. To compensate, the programmer has included a
;;; slash separating the two characters. In case 2a, the slash is
;;; unnecessary but harmless, but in case 2b, the slash is critical to
;;; allowing the outer #| ... |# pair match. If the slash were not present, ;;; the outer comment would terminate prematurely.
(defun mention-fun-fact-2a ()
(format t "Don’t use |\# unmatched or you’ll get in trouble!"))
→ MENTION-FUN-FACT-2A
(mention-fun-fact-2a)
▷ Don’t use |# unmatched or you’ll get in trouble!
→ NIL
#| (defun mention-fun-fact-2b ()
(format t "Don’t use |\# unmatched or you’ll get in trouble!") |#
(fboundp ’mention-fun-fact-2b) → NIL
;;; In this example, the programmer attacks the mismatch problem in a
;;; different way. The sharpsign vertical bar in the comment is not needed
;;; for the correct parsing of the program normally (as in case 3a), but
;;; becomes important to avoid premature termination of a comment when such
;;; a program is commented out (as in case 3b).
(defun mention-fun-fact-3a () ; #|
(format t "Don’t use |# unmatched or you’ll get in trouble!"))
→ MENTION-FUN-FACT-3A
(mention-fun-fact-3a)
▷ Don’t use |# unmatched or you’ll get in trouble!
→ NIL
#|
(defun mention-fun-fact-3b () ; #|
(format t "Don’t use |# unmatched or you’ll get in trouble!"))
|#
(fboundp ’mention-fun-fact-3b) → NIL
2.4.8.19.2 Notes about Style for Sharpsign Vertical
Some text editors that purport to understand Lisp syntax treat any |...| as balanced pairs that cannot nest (as if they were just balanced pairs of the multiple escapes used in notating certain symbols). To compensate for this deficiency, some programmers use the notation #||...#||...||#...||# instead of #|...#|...|#...|#. Note that this alternate usage is not a different reader macro; it merely exploits the fact that the additional vertical-bars occur within the comment in a way that tricks certain text editor into better supporting nested comments. As such, one might sometimes see code like:
#|| (+ #|| 3 ||# 4 5) ||#
Such code is equivalent to:
#| (+ #| 3 |# 4 5) |#
2.4.8.20 Sharpsign Less
#< is not valid reader syntax. The Lisp reader will signal an error of type reader-error on encountering #<. This syntax is typically used in the printed representation of objects that cannot be read back in.
2.4.8.21 Sharpsign Whitespace
# followed immediately by whitespace1 is not valid reader syntax. The Lisp reader will signal an error of type reader-error if it encounters the reader macro notation #⟨Newline⟩ or #⟨Space⟩.
2.4.8.22 Sharpsign Right
This is not valid reader syntax.
The Lisp reader will signal an error of type reader-error upon encountering #).
2.4.9 Re
Note that the Lisp reader will generally signal an error of type reader-error when reading an expression2 that has been abbreviated because of length or level limits (see *print-level*, *print-length*, and *print-lines*) due to restrictions on “..”, “...”, “#” followed by whitespace1, and “#)”.