SET-DISPATCH-MACRO-CHARACTER and SET-MACRO-CHARACTER coerce a SYMBOL to a FUNCTION too early

Bug #1012335 reported by Jean-Philippe Paradis on 2012-06-12
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

What I do and what happens (SET-DISPATCH-MACRO-CHARACTER):

(let ((rt (copy-readtable nil nil)))
  (make-dispatch-macro-character #\! t rt)
  (set-dispatch-macro-character #\! #\z 'lazy-function rt)
  rt)

LAZY-FUNCTION isn't fbound.
   [Condition of type SIMPLE-TYPE-ERROR]

Backtrace:
  0: (COERCE LAZY-FUNCTION FUNCTION)
  1: (SET-DISPATCH-MACRO-CHARACTER #\! #\z LAZY-FUNCTION #<READTABLE {BF1E861}>)
[...]

What I do and what happens (SET-MACRO-CHARACTER):
(let ((rt (copy-readtable nil nil)))
  (set-macro-character #\! 'lazy-function rt)
  rt)

The function COMMON-LISP-USER::LAZY-FUNCTION is undefined.
   [Condition of type UNDEFINED-FUNCTION]

Backtrace:
  0: (SB-KERNEL:%COERCE-CALLABLE-TO-FUN LAZY-FUNCTION)
  1: (SET-MACRO-CHARACTER #\! LAZY-FUNCTION #<READTABLE {C2C3FB9}> #<READTABLE {9000501}>)
[...]

What I expected in both cases:
Usual funcall-time symbol-to-function resolution semantics.

Analysis:
It's fairly well-established practice that storing a symbol as a function designator in some data structure results in "lazy" resolution of the symbol to a function. This is especially useful for interactive development, as function redefinitions will get picked up without needing to redeclare the macro-character. I understand that this early coercion might have been done for performance concerns, but most users already pass a function, and it's easy for the user to coerce any symbol to a function themselves if that's what they want, as they already need to do for almost every other data structure. There might be performance gains from readtable functions being able to assume that GET-DISPATCH-MACRO-CHARACTER and GET-MACRO-CHARACTER always return either NIL or a FUNCTION, and not a SYMBOL, but I think it's safe to assume that they're not significant, unless proven otherwise by profiling (which I'm unwilling to do ;P).

I found no hint in CLHS SET-DISPATCH-MACRO-CHARACTER and CLHS SET-MACRO-CHARACTER that such early coercion might be done, and the fact that GET-DISPATCH-MACRO-CHARACTER and GET-MACRO-CHARACTER are specified as returning a function designator, not just a function, strongly hints that there is no such early coercion.

SBCL version: 1.0.56

uname -a: Linux dynamorph 3.2.0-24-generic-pae #39-Ubuntu SMP Mon May 21 18:54:21 UTC 2012 i686 i686 i386 GNU/Linux

*features*:
(:SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF2 :ASDF :ANSI-CL :COMMON-LISP
 :SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL
 :SB-SOURCE-LOCATIONS :IEEE-FLOATING-POINT :OS-PROVIDES-POLL
 :OS-PROVIDES-GETPROTOBY-R :OS-PROVIDES-SUSECONDS-T :OS-PROVIDES-PUTWC
 :OS-PROVIDES-DLADDR :OS-PROVIDES-DLOPEN :LITTLE-ENDIAN :LINKAGE-TABLE
 :MULTIPLY-HIGH-VOPS :MEMORY-BARRIER-VOPS :INLINE-CONSTANTS :CYCLE-COUNTER
 :ALIEN-CALLBACKS :STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS
 :STACK-ALLOCATABLE-VECTORS :STACK-ALLOCATABLE-CLOSURES :RAW-INSTANCE-INIT-VOPS
 :UNWIND-TO-FRAME-AND-CALL-VOP :COMPARE-AND-SWAP-VOPS :C-STACK-IS-CONTROL-STACK
 :STACK-GROWS-DOWNWARD-NOT-UPWARD :GENCGC :LARGEFILE :SB-FUTEX :SB-THREAD
 :LINUX :ELF :UNIX :X86)

Stas Boukarev (stassats) wrote :

In fa0c056d6e2e9eef1c07cae0b3b814099866bedb by Douglas.

Changed in sbcl:
status: New → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers