[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