CLHS: Issue PRINC-READABLY Writeup

#

## Issue PRINC-READABLY Writeup

    Issue:         PRINC-READABLY
    References:    FORMAT (pp. 385-388), PRIN1 (p. 83), PRINC (p. 83),
                   WRITE (p. 382), *PRINT-PRETTY* (p. 371)
    Related Issues: DATA-IO, FORMAT-PRETTY-PRINT, PRINT-CIRCLE-SHARED
    Category:      CHANGE
    Edit history:  Version 1 by Moon 9/25/91

    Problem description:

     What do you think this form outputs?

     (let ((*print-readably* t))
       (format t "<~A>" '|Foo|))

     If you said <Foo>, that's what I expect it to output.  However a close
     reading of CLtL2 shows that it is specified to print <|Foo|>.  Similarly
     ~A is specified to put on a package prefix if ~S would, when
     *PRINT-READABLY* is T.  ~D, etc. have the same problem, as does PRINC.
     If *PRINT-READABLY* is true, the binding of *PRINT-ESCAPE* by these
     FORMAT operators and by PRINC has no effect.

     See CLtL2 p.558 for the specification that *print-readably* overrides
     *print-escape*, CLtL2 p.583 for the specification that ~A only binds
     the printer control variables it is explicitly specified to bind,
     CLtL2 p.584 for the specification that ~A only binds *print-escape*
     (*print-readably* is not listed), and CLtL2 p.578 for the specification
     that princ is the same as write with :escape nil (but not :readably nil).

     Part of the problem appears to be that issue DATA-IO was written up
     without any reference to issue FORMAT-PRETTY-PRINT.  I apologize.

     A related problem is that the following form

       (let ((*print-circle* t) (s "foo"))
         (format t "~A ~A(~A, ~A)"
                 "moe" "bar" s s))

     is specified to print ``moe bar(#1=foo, #1#)'' rather than
     printing ``moe bar(foo, foo)''.

     I discovered these problems when Macintosh Common Lisp was changed to
     obey the letter of the law (as handed down in CLtL2) and a program of
     mine stopped working.

    Proposal (PRINC-READABLY:FIX-BUGS):

     1. Specify that ~A binds *PRINT-READABLY* to NIL.

     2. Specify the same for ~B, ~D, ~E, ~F, ~G, ~O, ~nR, ~X, and ~$ (which
        all turn into ~A for non-numeric arguments).

     3. Change the specification of (PRINC object stream) as equivalent to

          (WRITE object :STREAM stream :ESCAPE NIL)

        to instead be equivalent to

          (WRITE object :STREAM stream :ESCAPE NIL :READABLY NIL)

     4. Change PRINC-TO-STRING the same way.

     5. Change items 1 and 2 above also to bind *PRINT-CIRCLE* to NIL.
        Change items 3 and 4 above also to specify :CIRCLE NIL.
        This has been broken out into a separate numbered item to allow
        for the possibility of voting separately on this change.

    Test Cases/Examples:

     See "Problem description."

    Rationale:

     Proposal DATA-IO:ADD-SUPPORT was not intended to "break" ~A;
     this was an accident.

     ~A and PRINC are supposed to produce "human-readable" output, so
     they should not put on machine-readability decorations such as
     vertical bars, backslashes, package prefixes, and #1#.

     Point 5 means that ~A might not terminate when given a circular
     structure to print, even if *PRINT-CIRCLE* is true.  The real problem
     here is that *PRINT-CIRCLE* is being used for two distinct purposes,
     detecting circular structure and detecting shared structure.  We do
     not propose here to separate those two features (X3J13 voted
     down a proposal, PRINT-CIRCLE-SHARED:NEW-VARIABLE, to do so once before).

    Current practice:

     Macintosh Common Lisp 2.0b3c4 does not implement this proposal; it
     implements exactly what CLtL2 specifies.

     Symbolics Genera 8.1 implements the proposal, or at least produces the
     proposed result for both test cases.  This might be due to assuming
     that CLtL2 says something reasonable rather than reading the book with
     a magnifying glass.

    Cost to Implementors:

     Implementing the changes should take very little effort.

    Cost to Users:

     Conceivably existing code could depend on the specified behavior,
     but that seems quite unlikely, so the cost to users is probably minimal.

    Cost of non-Adoption:

     A silly hassle for anyone using ~A and ~S to generate comments and
     code respectively, with *PRINT-READABLY* and/or *PRINT-CIRCLE* turned
     on for the benefit of the ~S.

    Benefits:

     Fewer silly hassles.

    Aesthetics:

     Does FORMAT have aesthetics?  If it does, I think the change improves
     them slightly.

    Discussion:

     Dave Moon and Guy Steele were both surprised that CLtL2 says what it says.

Copyright 1996-2005, LispWorks Ltd. All rights reserved.