eliot@phoenix.Princeton.EDU (Eliot Handelman) (12/23/89)
Here's a little problem: (set-macro-character #\$ #'(lambda (stream char) (declare (ignore char)) (get (read stream t nil t) 'foo))) ;;; S is a structure printed as #<S> (setf (get :blah 'foo) (make-s)) $:blah ;; In Lucid 2.0 and Kcl: ==> #<S> ;; in Franz (on the NeXT): ==> error, because it tries to eval #<S>. It appears that Franz is passing on the results of the readmacro to eval, whereas Lucid and KCl aren't. Franz says they're right, what accounts for the disparate behavior then? --eliot
barmar@Think.COM (12/23/89)
In article <12384@phoenix.Princeton.EDU> eliot@phoenix.Princeton.EDU (Eliot Handelman) writes: >It appears that Franz is passing on the results of the readmacro to eval, >whereas Lucid and KCl aren't. Franz says they're right, what accounts for >the disparate behavior then? In both cases the result of the readmacro is passed to EVAL, since you were typing to the read-eval-print loop, which passes whatever you type to EVAL. To see that this is true, try (setf (get :bar 'foo) '(+ 1 2)) $:bar ==> 3 '$:bar ==> (+ 1 2) The difference is that different Lisps have different behavior when evaluating a structure. CLtL doesn't specify the behavior when evaluating structures (see p.54 -- structures aren't "valid forms", so evaluating them "is an error"), so the result is implementation-dependent. Lucid and KCL have extended the evaluator to treat structures as self-evaluating forms, while Franz has defined it to signal an error. They are both in conformance; your use is not portable (it will be in ANSI CL -- X3J13 has decided to specify that all data types other than lists and symbols are self-evaluating). You can get what you probably want in a portable way with the following version of your read-macro: (set-macro-character #\$ #'(lambda (stream char) (declare (ignore char)) `(quote ,(get (read stream t nil t) 'foo)))) Of course, this is only useful if you will always be executing the result of a $ form. If $:blah were typed in response to a (read) in your program, the result would include the quote, which you would have to strip out. A better solution would be to use your original macro, but remember to write '$:blah in evaluation contexts. Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar