On Thu, Dec 14, 2017 at 5:49 PM, Pierpaolo Bernardi olopierpa@gmail.com wrote:
Spec is not explicit, and currently different implementations do different things.
(let ((*print-circle* t) (name "q")) (format nil "~A ~A" name name)) ==> ?
It may be true that implementations do different things, but IMO the standard permits only one result. #n= notion aught not be produced. See the first paragraph of the dictionary page for *print-circle*:
Controls the attempt to detect circularity and sharing in an *object* http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#object being printed.
FORMAT is not a function that prints an *object*. Instead, it interprets a format control. A call to FORMAT may print zero objects or any number of objects.
The functions that are specified to print an object are WRITE, PRINT, PRINC, PRIN1, and PPRINT (which might all be conceptually defined to make the obvious call to WRITE on that object, although this is not required), their mumble-TO-STRING versions, and PPRINT-LINEAR, PPRINT-FILL, and PPRINT-TABULAR. The printer is recursive, but is the outermost entry to one of these functions that defines the boundary for circularity detection. (PRINT-OBJECT might be included in this set, but it is not necessary since it ought only be called dynamically inside one of the others.)
~A, ~S, ~W and various others (e.g. when a numeric format control is given a non-number) act as if they make the obvious call to WRITE. I maintain that the ANS is firm that the following results (here in sbcl) are correct and required. *PRINT-CIRCLE* is true:
* (let ((g "a")) (format nil "~a ~a" g g)) "a a" * (let ((g "a")) (format nil "~a" (list g g))) "(#1=a #1#)" * (let ((g "a")) (format nil "~{~a ~}" (list g g))) "a a "
The first two examples are clear from the above argument. The third follows from the description of ~{, which specifies that it behaves like a recursive format control, and therefore also does not itself "print an object".
So while the ANS is not ambiguous here, this issue can be hard to understand and a clarification could indeed be useful. However, it can only be a clarification, neither a change nor resolution of an ambiguity. It bears repetition that the X3J13 goal for the ANS was a *specification*. Ease of understanding was of course desirable, but a very secondary consideration. There are a great many tangled or distant interrelated passages; one needs be intimately familiar with the entire document even to rememberwhere to look for the other end of a tangle. Also, it is inconceivable to me that someone not already familiar with some Lisp dialect could learn CL from the ANS.