I was wondering whether we should try to support tiny hacks in
contrib/, and what'd be the best way to do it.
E.g., my .sbclrc does this:
;;; support for human-friendly (but still READable) printing of cyclic
;;; data structures containing objects which are logically "interned",
;;; so that their print representation identifies their object
;;; identity uniquely, e.g.
;;; * players in a game and squares on a game board (as in example below)
;;; * timezones, endianness, CPU registers, rounding modes, compass
;;; directions, etc.
;;; By defining INTERNEDP methods to return true on interned objects,
;;; you can use *PRINT-CIRCLE*=T without your output being cluttered
;;; with #N= junk which is redundant given your interning mechanisms.
;;; Thus with e.g.
;;; (DEFMETHOD INTERNEDP ((PLAYER PLAYER)) T)
;;; (DEFMETHOD INTERNEDP ((SQUARE SQUARE)) T)
;;; and DEFMETHOD PRINT-OBJECT to print players in #.*VAR* style and
;;; board squares in ?F4 style, your output which in portable CL would
;;; look like
;;; MOVES-AND-REFUTATIONS=((#1=#.*WHITE* #2=?F4 #3=?F5)
;;; (#1# #3#)
;;; (#1# ?F6 #2# #3#))
;;; can be made to look like
;;; MOVES-AND-REFUTATIONS=((#.*WHITE* ?F4 ?F5)
;;; (#.*WHITE* ?F5)
;;; (#.*WHITE* ?F6 ?F4 ?F5))
;;; instead. And (assuming that you really did implement an interning
;;; mechanism, and that you have suitable SET-MACRO-CHARACTER #\?
;;; hackery to read the names in the style "?F4" in the example) your
;;; output will still be readable by the Lisp reader.
;;; Obvious drawbacks are:
;;; * unportability
;;; * overhead of an extra generic function call on every call to WRITE
;;; But for PRINT-OBJECT logic which'll only be used for interactive
;;; experimentation and debugging, these drawbacks can be tolerable.
(export 'sb-ext::internedp :sb-ext)
(defgeneric sb-ext::internedp (x))
(defmethod sb-ext::internedp ((x t)) nil)
(defun sb-impl::uniquely-identified-by-print-p (x) ; overwriting old def'n
(or (numberp x)
(and (symbolp x)
This seems like a fairly plausible contrib/ hack, since as far as I
can see it can't be done portably (short of reimplementing the pretty
printer from scratch, anyway) and it's reasonably self-contained. But
while the overhead in making it a separate contrib file and
"SB-INTERNEDP" package isn't totally impractical, it does seem
surprisingly large. Would it be worth reducing it a little, e.g. by
defining an "SB-GRAB-BAG" or "SB-MINIM-OPI" package for extensions
as small as this?
William Harold Newman <william.newman@...>
"<_8jean> 'key locations can be altered easily. users can easily
customize the location of frequently used keys for their benefit'
[...] `once the [key] map is stored in the registry, a system reboot
is required to activate it'" -- #lisp
PGP key fingerprint 85 CE 1C BA 79 8D 51 8C B9 25 FB EE E0 C3 E5 7C