Subject: Re: Printing NIL as () in composites (beyond the ~:S directive)
From: Erik Naggum <erik@naggum.no>
Date: 1999/09/15
Newsgroups: comp.lang.lisp
Message-ID: <3146421171283688@naggum.no>

* Blackboard Technology Group
| The need stems from the use of higher radix I/O when printing/reading
| aggregate structures, where NIL is parsed as a number rather than the
| empty list.

  the cause of the problem is a premature caching of the characteristics of
  the symbol name when printed in a particular base: it is computed with
  the prevailing value of *PRINT-BASE* when the symbol is first printed,
  and retained thereafter even when that value changes.  since most symbols
  are first printed when the prevailing base is 10, you observe problems,
  but suppose you have a package in which the symbol named FACE does not
  exist, while the symbol "BEEF" does, and the value of *PRINT-BASE* and
  *READ-BASE* are both the default (10).  you can observe the behavior by
  evaluating this snippet of code:

CL-USER(64): (let ((*print-base* 36)
		   (*read-base* 36))
	       (write (list (intern "FACE") 'beef)))
(|FACE| BEEF)
(|FACE| BEEF)

  note that FACE retains its printing behavior from when it was first
  printed.

  to get rid of this problematic behavior, the simplest thing you can do is
  to compile and load the following, which junks the caching.

(in-package :excl)
(defun get-symbol-print-flags (symbol)
  (compute-symbol-name-flags (symbol-name symbol)))

  this will slow your implementation down a bit, since the caching which
  used to be here is quite the efficiency booster for the printer.

  a better strategy, which will make the cache useful, again, is to store
  the value of the base when it was computed and recompute if that base has
  changed.  let me know if this is important to you, performance-wise.

#:Erik