[Ecls-list] Patch: macro expansion when expanding a setf form

Juan Jose Garcia-Ripoll juanjose.garciaripoll at googlemail.com
Mon Sep 1 17:46:00 UTC 2008


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

(defmacro lastguy (x) `(car (last ,x)))
(define-setf-expander lastguy (x &environment env)
   "Set the last element in a list to the given value."
   (multiple-value-bind (dummies vals newval setter getter)
       (get-setf-expansion x env)
     (let ((store (gensym)))
       (values dummies
               vals
               `(,store)
               `(progn (rplaca (last ,getter) ,store) ,store)
               `(lastguy ,getter)))))
(setq a (list 'a 'b 'c 'd)
       b (list 'x)
       c (list 1 2 3 (list 4 5 6)))
(setf (lastguy a) 3)
(setf (lastguy b) 7)
(setf (lastguy (lastguy c)) 'lastguy-symbol)

and this actually produces
(http://www.lispworks.com/documentation/HyperSpec/Body/m_defi_3.htm)

> a
(A B C 3)
> b
(7)
> c
(1 2 3 (4 5 LASTGUY-SYMBOL))

Juanjo

>
> A patch to incrementally expand macros with MACROEXPAND-1 follows:
>
> --- src/lsp/setf.lsp
> +++ src/lsp/setf.lsp
> @@ -111,7 +111,7 @@ Does not check if the third gang is a single-element list."
>             (push item all-args))
>           (values (gensym) (nreverse names) (nreverse values) (nreverse all-args))))
>     (cond ((symbolp form)
> -          (if (and (setq f (macroexpand form env)) (not (equal f form)))
> +          (if (and (setq f (macroexpand-1 form env)) (not (equal f form)))
>               (get-setf-expansion f env)
>               (let ((store (gensym)))
>                 (values nil nil (list store) `(setq ,form ,store) form))))
> @@ -130,7 +130,7 @@ Does not check if the third gang is a single-element list."
>                            (setf-structure-access (car all) (car f) (cdr f) store))
>                           ((setq f (get-sysprop (car form) 'SETF-LAMBDA))
>                            (apply f store all))
> -                          ((and (setq f (macroexpand form env)) (not (equal f form)))
> +                          ((and (setq f (macroexpand-1 form env)) (not (equal f form)))
>                            (return-from get-setf-expansion
>                              (get-setf-expansion f env)))
>                           (t
>
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> Ecls-list mailing list
> Ecls-list at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/ecls-list
>



-- 
Instituto de Física Fundamental
CSIC, Serrano, 113, Madrid 28040 (Spain)
http://juanjose.garciaripoll.googlepages.com


More information about the ecl-devel mailing list