[Ecls-list] Patch: macro expansion when expanding a setf form
Josh Elsasser
josh at elsasser.org
Mon Sep 1 21:59:02 UTC 2008
On Mon, Sep 01, 2008 at 07:46:00PM +0200, Juan Jose Garcia-Ripoll wrote:
> On Sat, Aug 30, 2008 at 10:53 PM, Josh Elsasser <josh at elsasser.org> wrote:
> > when attempting to macroexpand a form to find a setf expansion,
> > MACROEXPAND is used instead of MACROEXPAND-1. This means that the
> > setf expansion will not be found for a macro which expands into a
> > SETFable place which is also happens to be a macro.
> >
> > For example, given the following pseudo-definitions:
> >
> > (defmacro inner ...)
> > (define-setf-expander inner ...)
> > (defmacro outer (val)
> > `(inner ,val))
> >
> > The setf expansion defined for inner will not be found for a form like
> > (setf (outer foo) bar)
>
> Sorry, I am a bit dense today :-) The scheme you plot above seems to
> work. Using the example from the Hyperspec, but changing DEFUN ->
> DEFMACRO yields
My fault for not including an example, this one was quite tricky to
track down :)
The example from the hyperspec is misleading here since the lastguy
macro expands to (car ...), which already has it's own setf expander.
Here's the code I was using to test with:
(define-setf-expander triple (place &environment env)
(multiple-value-bind (dummies vals newval setter getter)
(get-setf-expansion place env)
(let ((store (gensym)))
(values dummies
vals
`(,store)
`(let ((,(car newval) (/ ,store 3)))
(triple ,setter))
`(progn
(triple ,getter))))))
(defmacro obfuscated (val)
`(triple ,val))
(defmacro triple (val)
`(* 3 ,val))
(let ((foo 5))
(print foo)
(print (triple foo))
(setf (triple foo) 6)
(print foo)
(print (triple foo))
(fresh-line))
(let ((foo 5))
(print foo)
(print (obfuscated foo))
(setf (obfuscated foo) 6)
(print foo)
(print (obfuscated foo))
(fresh-line))
More information about the ecl-devel
mailing list