Ticket #784 (closed defect: fixed)

Opened 4 years ago

Last modified 2 years ago

The initial value of *print-pprint-dispatch* is NIL.

Reported by: stassats Owned by: gb
Priority: normal Milestone: Clozure CL 1.9
Component: other Version: trunk
Keywords: Cc:

Description

Although it's implementation dependent what initial value *print-pprint-dispatch* is, NIL is rather inconvenient, since it causes set-pprint-dispatch without explicit table to error.

Change History

comment:1 Changed 4 years ago by alms

  • Type changed from defect to enhancement
  • Component changed from Compiler to other

Because the current implementation is correct I'm changing the type of this ticket from "Defect" to "Enhancement". I'm also changing the component from "Compiler" to "other". (I thought about "ANSI CL Compliance" as the component, but we've already agreed that this isn't a compliance issue.)

comment:2 Changed 4 years ago by stassats

  • Type changed from enhancement to defect

I still think it's a defect, CLHS says that the type of *print-pprint-dispatch* is "a pprint dispatch table.". NIL may be of such type, but then set-pprint-dispatch should recognize it as such and not signal an error. Although the proper solution would be to have *p-p-d* to be initialized to (copy-pprint-dispatch nil)

comment:3 Changed 4 years ago by gb

NIL can't be a pprint-dispatch-table. CCL's pretty printer treats it as an alias for the initial immutable table, and we can't have SET-PPRINT-DISPATCH do the same thing (since that would cause it to modify that immutable dispatch table.)

I agree that this is a bug, and that it also affects WITH-STANDARD-IO-SYNTAX and some CCL printer code that explicitly binds *PRINT-PPRINT-DISPATCH* to NIL.

comment:4 Changed 3 years ago by rme

  • Milestone set to Clozure CL 1.8

comment:5 Changed 2 years ago by fare

It was breaking lambda-reader, that I wanted to use with CCL.

My fix in lambda-reader was to insert a (copy-pprint-dispatch) at the right place.

One potential solution would be that if *print-pprint-dispatch* is NIL and SET-PPRINT-DISPATCH is called, then *print-pprint-dispatch* is replaced by (copy-pprint-dispatch) first. May or may not fly.

Even without such magic behavior, could at least include an explicit test *print-pprint-dispatch* being NIL or immutable in set-print-dispatch, and if so, issue a helpful error message explaining that the user should be using (copy-pprint-dispatch) rather than modifying an immutable pprint dispatch table?

NB: Unhappily, trac doesn't seem to have included a backlink to bug 960 when you (rightfully) made bug 960 a duplicate of this one. http://trac.clozure.com/ccl/ticket/960

comment:6 Changed 2 years ago by gb

  • Owner set to gb
  • Status changed from new to assigned

AFAICT, the reasonable but misguided intent in binding *PRINT-PPRINT-DISPATCH* to NIL is to avoid having every thread do the equivalent of

   (let* ((*print-pprint-dispatch* (copy-pprint-dispatch)))
      ...)

on startup; that's at least a little expensive in general and is especially expensive in common cases where threads don't do any printing, pretty or otherwise.

There are likely other ways of avoiding the overhead currently associated with (COPY-PPRINT-DISPATCH) that don't incur the problems associated with binding *PRINT-PPRINT-DISPATCH* to NIL. (The biggest of those problems being that doing so is Just Plain Wrong.)

comment:7 Changed 2 years ago by fare

I don't think that either NIL or the immutable structure it designates are unreasonable. But the error message certainly is.

Also, if you want cheap copy-pprint-dispatch, you could use pure/persistent datastructures underneath (e.g. immutable balanced trees) instead of mutable hash-tables.

comment:8 Changed 2 years ago by gb

  • Status changed from assigned to closed
  • Resolution set to fixed

(In [15344]) (COPY-PPRINT-DISPATCH nil) creates a lightweight table (which provides readonly access to the initial/internal dispatch table.) Calling SET-PPRINT-DISPATCH on such a table creates a "heavyweight" table as before.

The initial per-thread binding of *PRINT-PPRINT-DISPATCH* is a unique dispatch table created by (COPY-PPRINT-DISPATCH NIL).

WITH-STANDARD-IO-SYNTAX binds *PRINT-PPRINT-DISPATCH* to a shared immutable lightweight table; SET-PPRINT-DISPATCH refuses to allow this table to be modified. (See the CLHS glossary entry for "initial pprint dispatch table.")

Fixes ticket:784 in the trunk.

Note: See TracTickets for help on using tickets.