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
In article <·····@phoenix.Princeton.EDU> ·····@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.
······@think.com
{uunet,harvard}!think!barmar