ANSI Clarifications and Errata

Overview

This page is a listing of errors, inconsistencies and ambiguities in the ANSI standard, organized by chapter.

For minor revisions suggested for the ANSI standard, see Proposed ANSI Changes.

For extra functionality that could be standardized in the future, see Proposed Extensions to ANSI.

1. Introduction

  • 1.1.2 History has a typo in penultimate paragraph "Common Lisp esearch..." which should be "Common Lisp research...".

2. Syntax

  • Issue READER-MACRO-VALUES: Ok for reader macros to return more than one value?
  • The invalid constituent character trait is defined in the standard syntax for whitespace characters. The standard states (glossary and 2.1.4.3) 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.

3. Evaluation and Compilation

  • 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.
  • 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.
  • 3.4.4 Macro Lambda Lists 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.
  • Issue DEFMACRO-VALUES: If the body of DEFMACRO returns multiple values, can the macro function return them too?
  • Issue DEFINE-COMPILER-MACRO-DECLINE: Clarify what a compiler macro function should return if it declines to expand the form.
  • MACROEXPAND: The returned value in the third form in the examples should be DELTA rather than EPSILON.

4. Types and Classes

  • 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 VALUES-&ALLOW-OTHER-KEYS: (values "&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 "&KEY", &allow-other-keys was probably a mistake.

5. Data and Control Flow

  • Issue DEFCONSTANT-PREVIOUS-VALUE: 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 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 SOME: In contrast to the paragraphs on EVERY, NOTANY, and NOTEVERY the detail that "some returns as soon as any invocation of predicate returns a non-nil value" is missing form the paragraph on 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 APPLY-EXAMPLE-WRONG: The last example for APPLY is wrong, because it assumes particular behavior of TYPE-OF.
  • 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.)
  • rotatef: it seems that "read and written" should be "read and saved".
  • setq The title is given as "Special Form SETQ" instead of "Special Operator SETQ".
  • 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."

6. Iteration

  • 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 LOOP-FINALLY-VARIABLES: Clarify whether iteration variables are visible in FINALLY clauses. CLHS 6.1.1.4 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 6.1.1.6 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?

7. Objects

  • 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.
  • In 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."
  • In 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.))
  • Issue DEFGENERIC-MULTIPLE-DECLARE: Clarify that multiple DECLARE options can occur in a single DEFGENERIC form.
  • Issue DEFGENERIC-METHOD-COMBINATION-NAME: Clarify that the method-combination in a DEFGENERIC form is specified through a symbol, not a METHOD-COMBINATION object.
  • Issue MAKE-INSTANCES-OBSOLETE-SYMBOL: Clarify that MAKE-INSTANCES-OBSOLETE, when called on the name of a class, returns that name, not the class object itself.
  • 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.
  • 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 DEFGENERIC. Otherwise classes without proper name are nearly useless - since no methods can be defined for them using only ANSI CL facilities.
  • Issue INCOMPLETE-CLASS: The behaviour of a class in section 4.3.1 is ill-defined for classes whose superclasses are not yet defined (which DEFCLASS permits).

8. Structures

  • The "Arguments and Values" and "Description" sections on 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.

9. Conditions

  • 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 11.1.2.1.2 (point 18) could be read as disallowing it.
  • 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 not 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?
  • 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 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 RESTART-CASE-EXAMPLE: read-new-value should use *query-io* as specified above in the description of :INTERACTIVE option.
  • In RESTART-CASE, 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: ".
  • In RESTART-CASE, clarify that the argument to the test function may be a condition or NIL.
  • RESTART-CASE refers to "each arglist" but the "Arguments and Values" sections talks about lambda-list. It should therefore be "each lambda-list".
  • WITH-SIMPLE-RESTART: The compute-power-of-2 example definition is missing a hyphen from the symbol something-big.
  • INVOKE-RESTART: Invoked function "foo" does not exist, it should be "add3" which had just been defined.

10. Symbols

  • BOUNDP refers to "the function bound". It should be "the function boundp".

11. Packages

  • 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 DEFINE-SETF-METHOD: 11.1.2.1.2.13. speaks of DEFINE-SETF-METHOD, should be DEFINE-SETF-EXPANDER.
  • In SHADOW, under "Examples", (package-shadowing-symbols (make-package 'temp)) should be replaced with (package-shadowing-symbols (make-package 'temp :use '("CL"))). Some Lisps like SBCL don't use the CL package by default, so they will not return what is expected in the next example.
  • In SHADOW, under "Examples", (find-symbol 'car 'temp) should be replaced with (find-symbol "CAR" 'temp). The first argument to find-symbol should be a string.

12. Numbers

  • System Class float 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.
  • LOG specifies two-argument logarithm in terms of division of two on-argument calls to 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 (12.1.3.3) 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 log is for locating the branch cuts rather than for an explicit evaluation strategy.

14. Conses

  • Issue BUTLAST-DOTTED-LIST: Clarify behaviour of butlast and nbutlast for dotted lists.
  • Issue ADJOIN-SPECIFICATION: The standard is inconsistent in its treatment of the KEY parameter to the ADJOIN function. In the examples and notes, the key function is applied to the item being added, as it is in the related macro 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.
  • 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".
  • In NCONC, 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.

15. Arrays

  • 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.
  • The page for AREF says "Exceptional situations: none." It should specify that an error of class TYPE-ERROR "should be" (1.4.2) signaled if the subscripts are out of bounds.

16. Strings

  • The page for CHAR says "Exceptional situations: none." It should specify that an error of class TYPE-ERROR "should be" (1.4.2) signaled if the subscripts are out of bounds.

17. Sequences

  • Issue MERGE-PREDICATE-CALL: The order of arguments given for the predicate for MERGE does not allow testing for equality of elements, which is required for merge to be stable.
  • In 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."
  • In POSITION, the text should read "The position returned is the index within sequence of the leftmost (if from-end is false) or of the rightmost (if from-end is true) element that satisfies the test". The value of from-end is opposite from what it should be.

18. Hash Tables

19. Filenames

  • pathname-directory: 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.

21. Streams

  • Issue CLOSE-FILE-OPENED-WITH-SUPERSEDE: Clarify the behaviour of CLOSE when :abort is T and an old file is being superseded: OPEN implies that an implementation is allowed to have already deleted the old file, whereas CLOSE does not allow this.
  • WITH-OUTPUT-TO-STRING: refers to "with-output-from-string" which presumably should be "with-output-to-string."

22. Printer

  • 22.3.2.2 Tilde D: Decimal: The spec says that the @ modifier causes the number's sign to be printed always, but doesn't say what sign should be used for zero. Most Lisps return "+0" for (format nil "~@D" 0). Also see discussion on comp.lang.lisp.
  • Issue FORMAT-RADIX-COMMACHAR: Clarify or correct the interaction between padchar and commachar in FORMAT (CLHS 22.3.2.1).
  • Issue PRINTING-ARRAYS-READABLY: The description of *PRINT-READABLY* says that throwing a PRINT-NOT-READABLE error is allowed for certain arrays. CLHS 22.1.3.7 seems to imply that no error is allowed. This should probably be clarified one way or the other.
  • Issue FORMAT-TABULATE: CLHS 22.3.6.1, 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.
  • print-unreadable-object Delete superfluous "the" in "...enclosed in the the angle brackets.".
  • *print-circle* doesn't mention the granularity at which structure sharing and circularity is detected. This can lead to surprising results at times. For example, (let ((*print-circle* t) (name "q")) (format nil "~A ~A" name name)) returns "#1=q #1#" in Clozure CL.
  • 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.
  • 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.
  • Clarification proposal for CLHS 22.3: status of trailing commas and V parameters to FORMAT directives. This proposal is available as CDR 7.
  • PPRINT-LOGICAL-BLOCK: change two incorrect references of :pre-line-prefix to :per-line-prefix.

23. Reader

  • The 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 READ and other reader functions.

25. Environment

  • Issue TIME-ALWAYS-PRINTS: The 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 GO, THROW, RETURN, RETURN-FROM, or by the raising of a condition.

26. Glossary

  • symbol macro n. replace "See the macro symbol-macrolet." with "See the special operator symbol-macrolet."
  • type expand n. is defined to be a noun, but it should be a verb.