Proposed ANSI Revisions and Clarifications
This page is a listing of proposed and wishlist revisions and clarifications to ANSI Common Lisp. It is not a forum for pie-in-the sky thoughts about future Lisps (for which, see Lisp - Next Generation) or extra functionality that could be standardized (see Proposed Extensions To ANSI.)

Please check that what you're proposing isn't already in the standard.

Clarifications to the current standard:

  • Issue PRINTING-SPACE: Change the behavior of character printing such that invisible graphic characters such as space can be printed by name. The ~:C format directive does this already.

  • Issue BUTLAST-DOTTED-LIST: Clarify behaviour of BUTLAST and NBUTLAST for dotted lists.

  • Issue ARRAY-ELEMENT-TYPE-NIL: Explicitly allow or disallow arrays of element type NIL, and clarify whether they are strings or not.

  • Issue ARRAY-UPGRADING-UNDECIDABLE: As defined, array element upgrading is undecidable. Fix this.

  • Issue EQUAL-CIRCULAR-LIST: Change "EQUAL may fail to terminate if x or y is circular" to "if x and y are circular", so that (equal t '#1=(nil #1#)) is required to terminate. (There is no such wording for EQUALP.)

  • Issue DEFINE-COMPILER-MACRO-DECLINE: Clarify what a compiler macro function should return if it declines to expand the form. The glossary entry says NIL; DEFINE-COMPILER-MACRO and say the original form.

  • Issue PROG2-RETURN-VALUE: PROG2 returns the primary value of the second form, as specified under "Arguments and Values". The text under "Description" that claims otherwise is wrong.

  • Issue ERROR-EXAMPLE: Correct the invalid IF form in the (informational) wargames:no-win-scenario example for ERROR.

  • Issue CHECK-TYPE-EXAMPLE: Correct the example for CHECK-TYPE that suggests that a case conversion of the first letter of the optional string might take place.

  • Issue FORMAT-RADIX-COMMACHAR: Clarify or correct the interaction between padchar and commachar in FORMAT (CLHS

  • Issue PRINTING-ARRAYS-READABLY: The description of *PRINT-READABLY* says that throwing a PRINT-NOT-READABLE error is allowed for certain arrays. CLHS seems to imply that no error is allowed. This should probably be clarified one way or the other.

  • Issue DESTRUCTURING-NIL: Confirm or disconfirm that NIL in a destructuring lambda list (or a macro lambda list) acts as a "don't care" symbol, matching any object without causing a binding. Why would it do that, other than in LOOP destructuring?

  • RESTART-CASE clarification
    • Issue RESTART-CASE-EXAMPLE: RESTART-CASE examples: read-new-value should use *QUERY-IO* as specified above in the description of :INTERACTIVE option.
    • Clarify, that the argument to the test function may be a condition or NIL.
    • :(CLHS RESTART-CASE) refers to "each arglist" but the "Arguments and Values" sections talks about lambda-list. It should therefore be "each lambda-list".

  • LOOP clarifications
    • Issue LOOP-FINALLY-VARIABLES: Clarify whether iteration variables are visible in FINALLY clauses. CLHS requires FINALLY clauses to end up in the same tagbody where the loop body is. The forms that bind iteration variables cannot be inside the tagbody as part of the loop body, because the loop prologue wouldn't then be able to access the variables. Thus, the binding forms must be around the tagbody, so the variables must be visible in FINALLY clauses. CLHS may help deduce the values of the variables.
    • Issue LOOP-WITH-NIL: Is (loop with x of-type nil do (return x)) required to construct and return an "appropriate default value" for type NIL?

  • Issue DEFCLASS-READER-FUNCTION-NAME: The specification for DEFCLASS is a bit strange - in particular the use of reader-function-name for both :reader and :accessor, with two different descriptions given. Propose clarification by changing the second to accessor-function-name in both places.

  • DEFINE-CONDITION clarifications
    • Issue DEFINE-CONDITION-WRITERS: The writeability or otherwise of condition slots is a little unclear. DEFINE-CONDITION's Syntax allows :writer and :accessor, though the Description does not specify them, and the issues seem to imply that conditions were meant to be read-only objects.
    • Issue DEFINE-CONDITION-DOCUMENTATION: The :documentation option applies to the whole type in "Syntax" but to individual slots in "Arguments and Values" and "Description". DEFCLASS allows it in both places. It seems that :documentation was inadvertently omitted from the options BNF, although the text describes it as applicable in both locations per DEFCLASS.
    • Issue DEFINE-CONDITION-SLOT-NAME: The syntax where slot-name is "the list of slot name/slot form pairs" seems redundant, given :initform. Was it left in by accident? Current practice: (define-condition foo () ((((slot-name-symbol . "slot form"))))) signals an error in CMUCL release-18e-branch, SBCL, and CLISP 2.32.
    • DEFINE-CONDITION-REPORT: The description of the :report option is put down at the bottom, in with slot-options, rather than normal options. Simple typo, but makes the page a little confusing.

  • Issue READER-MACRO-VALUES: Ok for reader macros to return more than one value?

  • Issue DEFMACRO-VALUES: If the body of :(CLHS DEFMACRO) returns multiple values, can the macro function return them too?

  • Issue WITH-HASH-TABLE-ITERATOR-BINDING-TYPE: The Exceptional Situations for WITH-HASH-TABLE-ITERATOR claim it establishes a local function. Should be a local macro.

  • Issue CLOSE-FILE-OPENED-WITH-SUPERSEDE: Clarify the behaviour of :(CLHS CLOSE) when :abort is T and an old file is being superseded: :(CLHS OPEN) implies that an implementation is allowed to have already deleted the old file, whereas CLOSE does not allow this.

  • Issue STANDARD-PACKAGE-NICKNAMES: Section 11.1.2 gives 'a summary of the names and nicknames of those standardized packages'. Clarify whether this list is exhaustive, or if an implementation may provide other nicknames.


  • Issue DEFCONSTANT-PREVIOUS-VALUE: :(CLHS DEFCONSTANT) says "The consequences are undefined if there are any bindings of the variable named by name at the time defconstant is executed or if the value is not eql to the value of initial-value." Clarify "...or the symbol-value of name...", or equivalent.

  • Issue MAKE-INSTANCES-OBSOLETE-SYMBOL: Clarify that :(CLHS MAKE-INSTANCES-OBSOLETE), when called on the name of a class, returns that name, not the class object itself.

  • Issue THE-VALUES: The entry for THE seems to imply that the number of values is not important. However, the entry for VALUES says that using &optional or &rest constrains the number of values.

  • Issue STANDARDIZED-RESTART-NAMES: Clarify that ABORT, CONTINUE, MUFFLE-WARNING, STORE-VALUE and USE-VALUE may be bound as restart names by conforming code; this seems to be the intent, but formally CLHS (point 18) could be read as disallowing it.

  • Issue VALUES-&ALLOW-OTHER-KEYS: (:(clhs values) :(clhs "&ALLOW-OTHER-KEYS")) matches the syntax for the VALUES type specifier, but the description doesn't say what it means. Because the syntax does not allow :(clhs "&KEY"), &allow-other-keys was probably a mistake.

  • Issue DO-SEMANTICS: According to the entry for DO, "do iterates over a group of statements while a test condition holds." But the iteration really continues until the test form returns true, which is more or less the opposite of what that sentence seems to suggest. Change that sentence to read "do iterates over a group of statements until a test form returns true".

  • Issue FORMAT-TABULATE: CLHS, paragraph 1 describes what the ~T format directive does. If colnum is less than the current column, colinc is positive, and (mod (- curcol colnum) colinc) is 0, then it is unclear if this directive causes any spaces to be printed (and similarly for the case in PPRINT-TAB). Existing implementations do print at least one space in this case. Clarify that this is the intended behavior.

  • Issue DEFGENERIC-METHOD-COMBINATION-NAME: Clarify that the method-combination in a :(CLHS DEFGENERIC) form is specified through a symbol, not a METHOD-COMBINATION object.

  • Issue DEFGENERIC-MULTIPLE-DECLARE: Clarify that multiple DECLARE options can occur in a single :(CLHS DEFGENERIC) form.

  • Issue FORMAT-RADIX-NONINTEGER: Clarify that the ~R directive (and the ~B, ~O, and ~X directives) print like ~A when the argument is not an integer. Also, clarify that in these cases (and ~D) the mincol and padchar arguments are passed along appropriately to the ~A directive, and that the *PRINT-BASE* is bound appropriately.

  • Issue FORMAT-RADIX-MISSING-RADIX: Clarify the meaning of the ~R directive when the first parameter is missing but later parameters are not. Also, clarify whether ~VR means the same thing as ~R when the V parameter is NIL.

  • Issue FORMAT-G-NONNUMBER: Clarify that the ~G directive behaves like the ~E, ~F and ~dollars directives on non-numeric arguments.

  • Specify that the tabsize argument to PPRINT-TABULAR may be present and be NIL. This makes ~v/pprint-tabular/ work properly in FORMAT when the argument is NIL, and is consistent with the sample imeplementation given for PPRINT-TABULAR.

  • The treatment of ~T is inconsistent depending on the presence of the colon modifier. As stated, the versions with the colon modifier are the same as calls to pprint-tab, but those without are not. This means the former get turned off when printing to something that is not a pretty printing stream or when *print-pretty* is nil, but the latter are always on. Clarify whether this was intended. Note that Lispworks appears to treat all versions as calls to pprint-tab.

  • In the ~A format directive, the behavior of minpad format parameter is described as follows: 'The string is padded on the right (or on the left if the @ modifier is used) with at least minpad copies of padchar; padding characters are then inserted colinc characters at a time until the total width is at least mincol.' Clarify that the implementation uses the minimum number of padding characters consistent with this requirement.

  • Issue PRINT-LENGTH-AND-STRUCTURES: clarify the effect the *PRINT-LENGTH* printer control variable has on the default method for printing structure objects.

  • Clarify that there should be a predefined method for PRINT-OBJECT on the class CONDITION, not only on the classes STANDARD-OBJECT and STRUCTURE-OBJECT. Rationale: The description of DEFINE-CONDITION says "Condition reporting is mediated through the print-object method..." and "Specifying :REPORT ... is equivalent to (DEFMETHOD PRINT-OBJECT ...)". This implies that conditions are printed through PRINT-OBJECT, and therefore a predefined method needs to be in place.

  • The notes about WITH-ACCESSORS claim it'll give a binding like (variable-namei () (accessor-namei in)) to SYMBOL-MACROLET, which however does not accept that syntax. The empty parentheses should be removed.

  • Function FIND makes it impossible to find NIL in a sequence since NIL will be returned regardless of the input sequence. The suggestion is to add a second returned variable that is T if the element was found and NIL if it was not - like in GETHASH. (The usual way to deal with this is to use MEMBER instead.)

  • Issue CLASS-OBJECT-SPECIALIZER:AFFIRM: ANSI CL 7.6.2 says that class objects are usable as parameter-specializer-names. This is consistent with the vote on issue CLASS-OBJECT-SPECIALIZER:AFFIRM. However, in the Syntax section of the macros DEFMETHOD and DEFGENERIC, only symbols and (eql ...) lists are allowed as parameter specializer names in a method lambda list. Proposal: Update the syntax section of DEFMETHOD and :(CLHS DEFGENERIC). Otherwise classes without proper name are nearly useless - since no methods can be defined for them using only ANSI CL facilities.

  • Issue TIME-ALWAYS-PRINTS: The :(CLHS TIME) macro prints timing information on a form. Clarify whether it does so only when the form terminates normally, or also when control is transfered from the form by a :(CLHS GO), :(CLHS THROW), :(CLHS RETURN), :(CLHS RETURN-FROM), or by the raising of a condition.

  • Issue READ-DELIMITED-LIST:END-OF-FILE: The :(CLHS READ-DELIMITED-LIST) page of the standard says: "It is an error to reach end-of-file during the operation of read-delimited-list." This means the behavior is undefined (see the glossary entry for "error"), which makes this function useless in practice. This should be defined as an exceptional situation with behavior consistent with :(CLHS READ) and other reader functions.

  • Issue INVALID-CHARACTER-SYNTAX: The invalid constituent characte trait is defined in the standard syntax for whitespace characters. The standard states (glossary and that "Characters with the constituent trait invalid cannot ever appear in a token except under the control of a single escape character." However, the reader algorithm causes such characters to be treated as alphabetic if they are found inside multiple escape characters (so that the last case of step 9 of the reader algorithm never applies). Resolve this contradiction.

  • :(CLHS BOUNDP) refers to "the function bound". It should be "the function boundp".

  • Issue SOME: In contrast to the paragraphs on :(CLHS EVERY), :(CLHS NOTANY), and :(CLHS NOTEVERY) the detail that "some returns as soon as any invocation of predicate returns a non-nil value" is missing form the paragraph on :(CLHS SOME) in the CLHS. This probably doesn't give license to an implementation to delay the return and process further elements, since a few paragraphs higher up the text reads "until a termination criterion is met or the end of the shortest of the sequences is reached".

  • Issue ADJOIN-KEY: The standard is inconsistent in its treatment of the KEY parameter to the :(CLHS ADJOIN) function. In the examples and notes, the key function is applied to the item being added, as it is in the related macro :(CLHS PUSHNEW). However, the page points to section 17.2.1, which states explicitly that the key function is never applied to the item being searched for. All implementations do the former, not the latter, so this is probably a spec bug.

  • :(CLHS POP) states that the value of the place argument is "possibly, but necessarily, a dotted list or circular list". It should read "possibly, but not necessarily".

  • Incomplete classes: :(CLHS DEFCLASS) states that for standard classes, "It is not required that the superclasses of a class be defined before the defclass form for that class is evaluated." Let's call such a class with a not-yet-defined superclass an "incomplete class". One can now argue whether an incomplete class is a class or not, i.e. if :(CLHS FIND-CLASS) is required to return it, given its name.
    • Since :(CLHS DEFCLASS) says "defclass defines a new named class", an incomplete class should be considered as a class.
    • CLHS 4.3.1 says that a class determines the structure of a set of objects. This is not true for incomplete classes, as they cannot be instantiated.
    • CLHS 4.3.1 says that each class has a class precedence list. Incomplete classes don't, since the complete list of superclasses is unknown.
    • CLHS 4.3.1 says that the class t is a superclass of every class except itself. So there should be a chain of direct-superclass relations from an incomplete class to t. But for incomplete classes for which all direct superclasses don't exist yet there is no such chain.

  • :(CLHS WITH-PACKAGE-ITERATOR) doesn't specify behavior when no symbol-types is presented. It should be PROGRAM-ERROR. The spec seems clear to me: "with-package-iterator signals an error of type program-error if no symbol-types are supplied". How is this unspecified? --Nikodemus
  • Issue UNLESS: Fix typo in UNLESS form action specifications to read "In an unless form, if the test-form yields false, the forms are evaluated in order from left to right and the values returned by the forms are returned from the unless form. Otherwise, if the test-form yields *true*, the forms are not evaluated, and the unless form returns nil."
  • :(CLHS LOG) specifies two-argument logarithm in terms of division of two on-argument calls to :(CLHS log). There are two separate problems here; the first is trivial, in that the definition
(log base number) == (/ (log number) (log base)) has base and number inverted. The second is that this definition in conjunction with the Rule of Float Substitutability (:(CLHS will introduce intermediate single-floats into the computation of (log (fact 1000) 10d0), leading to inaccuracy in the final result. Proposed resolution: clarify that the (corrected) definition of two-argument :(CLHS log) is for locating the branch cuts rather than for an explicit evaluation strategy.

  • Issue AREF-EXCEPTIONS: The page for :(CLHS AREF) says "Exceptional situations: none." It should specify that an error of class :(CLHS TYPE-ERROR) "should be" (1.4.2) signaled if the subscripts are out of bounds. This also applies to :(CLHS CHAR).
  • :(CLHS 2.3.1) says that float exponents are read in the current input radix. :(CLHS says that float exponents are printed as a decimal integer. This would imply that floats are not readably printable under the condition that :(clhs *read-base*) is not 10. — Kevin Reid thinks this ought to be revised to consistently use whichever radix is used by most existing CL implementations.
  • Issue MERGE-PREDICATE-CALL: The page for :(CLHS MERGE) says
    The first argument to the predicate function is an element of sequence-1 as returned by the key (if supplied); the second argument is an element of sequence-2 as returned by the key (if supplied).
    If this were true for every call to the predicate, this requirement, also given on that page, could not be satisfied:
    The merging operation is guaranteed stable; if two or more elements are considered equal by the predicate, then the elements from sequence-1 will precede those from sequence-2 in the result.
    In fact, the optimal algorithm for MERGE (optimal in the sense of minimizing the number of calls to the predicate) will always call the predicate with the arguments in the reverse order (one from sequence-2 followed by one from sequence-1).
  • Issue APPLY-EXAMPLE-WRONG: The last example for :(CLHS APPLY) is wrong, because it assumes particular behavior of TYPE-OF. Fix this.
  • Clarification proposal for CLHS 22.3: status of trailing commas and V parameters to FORMAT directives. This proposal is available as CDR 7.
  • Issue DEFSTRUCT-TYPE: The "Arguments and Values" and "Description" sections on :(CLHS DEFSTRUCT) disagree about the top level :type argument. The former says it's list, vector, (vector size), or something implementation-defined, while the latter says it's list, vector, or (vector element-type). Specifying a size would be pointless as it would just be the number of slots defined in the form, and anything implementation-defined would be another subtype of SEQUENCE or something. Plus it would mean you can only represent with T vectors for no reason. As far as I know, all implementations go with the description.

    Proposed changes to the standard:

    • Un-deprecate REMOVE-IF-NOT, DELETE-IF-NOT.

    • Issue UNDEPRECATE-IF-NOT: Un-deprecate all *-if-not functions.

    • Issue REMOVE-SET: Remove SET (already deprecated).

    • Issue CONSTANTLY-MULTIPLE-VALUES: Extend CONSTANTLY to return multiple values if given other than 1 argument.

    • Issue PRINT-OBJECT-RETURNS: The requirements that PRINT-UNREADABLE-OBJECT returns nil and that user-defined methods for PRINT-OBJECT must return the object don't fit well together. The example in PRINT-UNREADABLE-OBJECT demonstrates the problem: It is in error because it returns nil from PRINT-OBJECT, in the assumption that the return value of PRINT-UNREADABLE-OBJECT is usable as a return value of PRINT-OBJECT. It would be a simplification if returning nil from PRINT-OBJECT were allowed, or if PRINT-UNREADABLE-OBJECT were specified to return the object. (By contrast, DESCRIBE-OBJECT may return anything.) The :REPORT option of DEFINE-CONDITION defines a method for PRINT-OBJECT, so the issue affects that too. In particular, (:REPORT "foo") defines a method that typically returns the string "foo", rather than the required condition object.

    • Issue BOOLEAN-RETURNS: Many functions are specified to return true when they could just as easily return T. Since most (all?) implementations already return T for these functions, tighten the standard so this is required. Why would this be a good thing? Issue MACROEXPAND-RETURN-VALUE changed the language to the opposite direction. (Actually, that issue just noted the inconsistency; the proposed solution there would change the requirement to 'true'. Another possible solution would be to change everything else to require T.) It would be a good thing because it would remove a gratuitous and unnecessary incompatibility between implementations, which would make it slightly easier to write portable programs. GCL ansi-tests would have been noticably easier to write had all the predicates returned T for true. -- Paul Dietz

    • Issue NO-NEXT-METHOD: NO-APPLICABLE-METHOD is specified to be called/signalled only when there are no applicable methods. However, there is an error situation for built-in method combinations that is not covered by this: when there is no primary method. Specify an analogous NO-PRIMARY-METHOD generic-function/condition pair.

    • Issue UNDEPRECATE-REQUIRE: [ may be contentious ] Undeprecate single-argument require, reflecting its continuing usage by Lisp implementors to load optional bolt-on modules that are supplied with the implementation. This is not supposed to be a means for the user to load his own or third-party libraries, for which a real DEFSYSTEM is a better solution. Note that a real DEFSYSTEM is outside the scope of this page. If cl:require is actually removed, implementations can still have ext:require, which doesn't seem too bad if the names of the modules are already not portable. Alternatively some parts of the REQUIRE mechanism might be specified -- eg. *REQUIRE-HOOK* or *REQUIRE-HOOKS*. You're right. REQUIRE should be removed and implementations that use it can have EXT:REQUIRE or something

    • Issue TYPE-OF-BIGNUM: The definition of TYPE-OF implies that BIGNUM or FIXNUM cannot be the types returned (due to requirement 1 and the presence of UNSIGNED-BYTE in figure 4-2.) This was probably not intended. Fix this.

    • Issue COMPILER-MACRO-IMPLICIT-BLOCK. Specify that :(CLHS DEFINE-COMPILER-MACRO) should establish an implicit block around the body.

    • Issue SXHASH-NEGATIVE-ZERO: SXHASH and the file compiler are affected by a loose specification of similarity with respect to negative zeros. It would appear that an implementation is permitted to dump negative zeros as positive ones (and vice versa), to the extent that (defconstant foo 0.0) (defvar *bar* (eql foo foo)) need not return true; also, it requires (sxhash 0.0) to be equal to (sxhash -0.0) even though (equal 0.0 -0.0) is false. Specify that negative zeros are not similar to positive zeros.

    • Issue IMAGPART-NEGATIVE-ZERO: The IMAGPART and COMPLEX functions are inconsistent in their treatment of objects of type (REAL * (0)): (complex -2.0) returns an object whose imaginary part is (coerce 0 'single-float), while (imagpart -2.0) returns (* 0 -2.0), which is different in implementations supporting negative zeros. This has ramifications in the treatment of branch cuts for real numbers.

    • Issue FORMAT-VERBATIM: FORMAT should offer a directive that prints a string verbatim to the output stream, character by character, ignoring printer settings such as *PRINT-CIRCLE* and *PRINT-LEVEL*; i.e., one that corresponds to WRITE-STRING and not PRINC or PRIN1. The section on Formatted Output almost reads as if ~A is supposed to ignore printer settings when printing strings ("If arg is a string, its characters will be output verbatim"); however, under this interpretation, ~S will also ignore those variables when printing strings, since it's specified as "just like ~A, but arg is printed with escape characters", while it is clearly desirable to honor printer settings in ~S. So, at least some clarification is needed here. Consider the following code snippet.
  • (defparameter *separator* ",")
    (defstruct foo (a 'a) (b 'b))
    (defmethod print-object ((foo foo) stream)
      (print-unreadable-object (foo stream)
        (format stream "~A~A~A" (foo-a foo) *separator* (foo-b foo))))
    (let ((*print-circle* t)) (print (list (make-foo) (make-foo))))
    The intended output is (# #). However, in at least one CL implementation, the output will be (# #), i.e., the printer will detect the shared structure and use sharpsign notation instead of printing the string verbatim. [Side note: There's no way to tell for sure where the printed representation of the object the #1= refers to ends, so the output is not very useful.] It's hard to argue that this output is non-conforming because of the wording in the description of ~S. So I don't think there's a way to write this print-object method without resorting to an explicit write-string (or copy-seq, but this will cons needlessly; or using a symbol, which is counter-intuitive). It's a pity format has this limitation. Issue PRINC-READABLY seems to be related to this.

  • Issue DEFCONSTANT-REDEFINE: Change the behavior of DEFCONSTANT so that it assigns a value to the given symbol only if that symbol is not already bound (much like DEFVAR)

    I think that's a bad idea. DEFCONSTANT is only problematic for values that cannot be compared with EQL but only, for example, with EQUAL. This may lead to the situation that one wants to use, for example, constant strings, but everytime the respective DEFCONSTANT form is reevaluated an error is issued because two EQUAL strings are not necessarily EQL. Here is another proposal: Add a TEST keyword to DEFCONSTANT that allows programmers to specify how they intend to use the constant, i.e. under what equivalence semantics. In the case of string constants they can say, for example: (DEFCONSTANT +example+ "example" :test #'equal). The idea here is that this is a promise to the compiler that the rest of the program does not rely on the EQL identity of the value of +example+. In turn, if the value of +example+ is indeed changed to another value that is not EQUAL in a subsequent DEFCONSTANT form the compiler can issue a warning / error as before.

  • Issue COMPILE-FILE-EXTENSIONS: Change COMPILE-FILE to allow implementation-defined keys (much like SBCL / CMUCL's use of :TRACE-FILE or LispWorks's :LOAD; I'm sure other implementations have similar extensions)

  • Issue FORMAT-LOGICAL-BLOCK-PREFIX-SUFFIX: Allow ~~ (Tilde) in the prefix and suffix segments of ~ (Logical Block). Currently, those segments cannot contain any format directives, so the corresponding output strings cannot contain tilde characters. It is not necessary to allow other directives (~%) or parameters (~V~, ~1~) to fix this.

  • Issue CONDITIONS-NOT-EXTERNALIZABLE: Clarify the intention and interaction between :(CLHS MAKE-LOAD-FORM), that specifies primary methods on conditions to signal an error, and :(CLHS that specifies that the file compiler uses MAKE-LOAD-FORM to externalize conditions. Taken togather with :(CLHS this implies that given a portable program and a conforming implementation standardized conditions can never appear as externalized objects in compiled code, which probably was not the intention.


    • Clarify that standardized conditions cannot be externalized.
    • Allowing (but not requiring) implementations to use something else then MAKE-LOAD-FORM to externalize standardized conditions.
    • Allowing implementations to define methods on MAKE-LOAD-FORM for standard conditions that signal an error only if the real class of the condition is not a standardized condition.

  • Issue MAP-INTO-SAMPLE-DEFINITION: The notes section on :(CLHS MAP-INTO) section give an example of how it could be implemented; the example is incorrect in the way it handles the fill-pointer of result-sequence. MAP-INTO is specified to ignore the fill-pointer when deciding how many iterations to perform, and afterwards change it to the number of iterations performed.

  • Issue KEYWORD-TYPE: KEYWORD and KEYWORDP are inconsistent (and the former is inconsistent with the glossary definition of 'keyword'.) A symbol is in the KEYWORD type if it is accessible in the package, but KEYWORDP is true if the symbol has the package named KEYWORD as its home package. The latter was probably intended. Fix this by either prohibiting importing (and shadow importing) of symbols into the keyword package, or force the home package of the symbol to be changed when this is done.

  • Issue MAKE-CONDITION-ERROR: MAKE-CONDITION should be allowed to signal an error on
  • type arguments that do not name classes, like (or type-error program-error).

  • Issue PATHNAME-PRINT-READABLY: NAMESTRING, PARSE-NAMESTRING, PATHNAME et al use (in the examples sections) a readable syntax for printing pathnames:
  • #S(PATHNAME ...). It should be specified as such, instead of requiring #P"..." which is not always readable.

  • PRINT-UNREADABLE-OBJECT's specification, if taken literally, requires that an ugly space be printed after the type description but before the closing bracket if type is true, identity is false, and the forms don't print anything. This may not have been intended; change so that the space is not printed in this situation (and the mirror case with identity being true.)

  • The glossary entry for "single escape" includes this parenthetical comment: "In the standard readtable, slash is the only single escape." This should reference "backslash", not "slash".

  • ARITHMETIC-ERROR-OPERATION is specified to return a function designator in Arguments and Values, but a list in Description. Those types are disjoint; presumably the description is wrong.

  • Section (Sharpsign Asterisk) states that an error of type :(CLHS READER-ERROR) is signaled if [...] "n is greater than one, but no bits were specified." This should be "n is greater than or equal to one, but no bits were specified."

  • :(CLHS *PRINT-READABLY*) states that the printed form should be readable within the "standard readtable". This implies that the printed representation is not allowed to be expressed in terms of user-defined reader macros. Although it leads to "normalized" representations, it can be considered overly restrictive if the printed representation is only read in when the user-defined readtable is in effect (reading and writing become asymmetric). Proposal: remove the restriction on "standard readtable", but perhaps "encourage" users to give representations that work in the "standard readtable". c.l.l March 7, 2007

  • Section 23.1.2 (Effect of Readtable Case on the Lisp Reader) states: "When the readtable case is :invert, then if all of the unescaped letters in the extended token are of the same case, those (unescaped) letters are converted to the opposite case." The term "extended token" is not well defined, but presumably means the entire symbol token, including package name, separators, and symbol name. This has the (likely unintended) consequence that "common-lisp-user::Foo" references package "common-lisp-user" instead of "COMMON-LISP-USER". This should be amended to treat the package name and symbol name parts of the token separately. As a point of information, LispWorks 4.4.6 appears to be faithful to the standard, whereas CLisp 5.1 uses the proposed behavior.

  • The dictionary entry for mapc and company discusses 'result-type' in the text ("result-type specifies the type of the resulting sequence."), however none of these functions appear to implement the functionality of allowing the user to specify the result-type in the actual function specifications. It has been speculated that this is an erroneous copy and paste from the entry for map.
  • COMPLEMENT is specified to take a FUNCTION, while most other higher-order operators in CL take designators for functions. (Additionally, the Notes section for COMPLEMENT is incorrect, since APPLY takes a function designator.) For similarity with the rest of the language, COMPLEMENT should take a function designator.
  • NCONC has a few tiny bugs in its specification. First, it would be nicely specified as a right fold instead of a left fold, i.e. (nconc list-1 list-2 . lists) == (nconc list-1 (nconc list-2) . lists) instead of (nconc (nconc list-1 list-2) . lists) — an overly literal reading of the left-folding definition leads to quadratic evaluation time (though optimizations are possible). Second, the example (setq x '(a b c)) (setq y '(d e f)) (nconc x y) flies in the face of Section 3.7.1 Modification of Literal Objects. As for me, I'd like to see a note somewhere that NCONC is very seldom a good idea, since its time complexity class is no better than APPEND, its space complexity class also is no better than APPEND in the common case where no one else is sharing the side-effected list, and its bug complexity class is way higher than APPEND. If the small enhancement factor due to APPEND vs NCONC is a limiting resource in your program, you have a big problem and are probably using the wrong data structure. I'd like to see the use of NCONC explicitly discouraged. If it weren't for legacy code that may rely on it, I would make the order or even existence of its side-effects made explicitly unspecified, so that APPEND be a valid implementation of NCONC.
  • The standard should provide a list of all forms that provide an implicit NIL block around their bodies, for reference. The current wording in CLHS individual pages is inconsistent, which makes it hard to find a list of such forms with a search. At least these forms put implicit NIL blocks around their bodies: DO, DO*, PROG, PROG*, LOOP, DOLIST, DOTIMES, DO-SYMBOLS, DO-ALL-SYMBOLS, DO-EXTERNAL-SYMBOLS
  • CLHS, on Sharpsign Dot, does not specify what happens if the form prefixed by
  • #. returns no values. The most popular answer, and arguably the most useful, is for nothing to be read, so that
    > '(#.(values) foo) => (FOO)

    SBCL, Clozure CL, Allegro CL, and LispWorks all do this. It should accordingly be required by the standard.

  • #H(RENAME-FILE) does not specify what happens when a file named new-name already exists. Several implementations add a third optional (sometimes keyword) if-exists parameter to #H(RENAME-FILE) that is used to specify what happens (typical values are :error and :overwrite). This de-facto extension to CL should be standardized.
  • Please put outright extensions (not fixups) in Proposed Extensions To ANSI.

    Minor corrections to CLHS (errata)

    Not clear if this is the right place for it, but minor (e.g. typographical) corrections to the CLHS:
    • CLHS 3.4.4 Body/03_ddab.htm describes a grammar for a destructuring-bind like "pattern", but doesn't use it to define reqvars and other vars. It probably should be fixed.
    • Body/m_defcla.htm#defclass: replace "Form---a form. :init-form can be supplied once at most for a given slot." with "Form---a form. :initform can be supplied once at most for a given slot."
    • Body/f_reduce.htm#reduce: replace "If key is supplied, it is used is used to extract the values to reduce." with "If key is supplied, it is used to extract the values to reduce."
    • Body/f_call_n.htm#call-next-method: replace "arg---an object." by "args---arguments to the method." (Just like "args" is described on the page Body/f_funcal.htm#funcall. (There it is "arguments to the function", of course.))
    • Body/m_rst_ca.htm: Under "Examples": In "defun read-new-value" the format string is "Enter a new value: ". In the restart output it shows up as "Enter a new ice cream: ".
    • Body/26_glo_s.htm#symbol_macro: replace "See the macro symbol-macrolet." with "See the special operator symbol-macrolet."
    • In the description of ROTATEF: it seems that "read and written" should be "read and saved".
    • Body/m_w_out_.htm#with-output-to-string refers to "with-output-from-string" which presumably should be "with-output-to-string."
    • Body/f_pn_hos.htm: the second example of (pathname-directory (parse-namestring "/foo/bar/baz.lisp") :case :local) should probably be using :common instead of :local. Also, the ".*." in the VMS example is suspect and might be just a ".", and/or a :wild might be missing in the example result, but I'll let an expert opine.
    • Body/m_w_smp_.htm#with-simple-restart: The compute-power-of-2 example definition is missing a hyphen from the symbol something-big.
    • Body/f_mk_has.htm: The description of rehash-size includes "... see rehash-theshold below." which should be "... see rehash-threshold below.".
    • Body/01_ab.htm has a typo in penultimate paragraph "Common Lisp esearch..." which should be "Common Lisp research...".
    • Body/t_float.htm is ambiguous with the exponents in two places. First, "s*f*b^e-p" should be "s*f*b^(e-p)", and second "between b^p-1 and b^p-1" should be "between b^(p-1) and (b^p)-1", where the second set of parentheses is optional if following standard order of operations.
    • Macroexpand/Macroexpand-1 The returned value in the third form in the examples should be DELTA rather than EPSILON.
    • SETQ The title is given as "Special Form SETQ" instead of "Special Operator SETQ".
    • Body/f_invo_1.htm: Invoked function "foo" does not exist, it should be "add3" which had just been defined.
    • PRINT-UNREADABLE-OBJECT Delete superfluous "the" in "...enclosed in the the angle brackets.".
    • type expand is defined to be a noun, but it should be a verb.