DEFINE-MODIFY-MACRO usage question 
Author Message
 DEFINE-MODIFY-MACRO usage question

a while back, the following code was posted.  If it helps, think of
`drop' as a `deletef', if one existed.

(defmacro drop (object place &rest keys &key key test test-not &environment environment)
  "Drop a particular OBJECT from list in PLACE.  (Intended as counterpart to PUSH/-NEW.)
Copyright 1999 by Erik Naggum.  Verbatim inclusion and redistribution permitted.

  (declare (ignore key test test-not))
  (multiple-value-bind (vars vals store-vars writer reader)
      (get-setf-expansion place environment)
    (let ((evaled-value (gensym))
          (store-var (first store-vars)))
      (if (cdr store-vars)
        `(let* ((,evaled-value ,object)

           (multiple-value-bind ,store-vars ,reader

             ,writer))
        `(let* ((,evaled-value ,object)


           ,writer)))))

I recently wanted similar functionality to that (basically, I wanted a
DELETEF macro).  I wrote the one below, and wanted to compare it with
the implementation above.

My implementation is as follows:

(defun delete* (list elt &rest args)
  (apply #'delete elt list args))

(define-modify-macro delete*f (&rest args)
  delete*)

(defmacro deletef (elt list &rest args)

I wrote it like that (i.e. with the {*filter*} delete*f) because I wanted
to preserve the order that delete used in the new deletef, and I
wasn't aware of another way.

The reason I wasn't sure I'd rather use GET-SETF-EXPANSION here is
that environment argument, which I don't feel belongs here, and I
avoided with define-modify-macro, whereas the DROP implementation
accepts the environment keyword argument, I'm guessing that
DEFINE-MODIFY-MACRO bypasses that, somehow.

feedback appreciated,
dave



Fri, 15 Aug 2003 16:46:09 GMT  
 DEFINE-MODIFY-MACRO usage question

Quote:

> I recently wanted similar functionality to that (basically, I wanted a
> DELETEF macro).  I wrote the one below, and wanted to compare it with
> the implementation above.

> My implementation is as follows:

> (defun delete* (list elt &rest args)
>   (apply #'delete elt list args))

> (define-modify-macro delete*f (&rest args)
>   delete*)

> (defmacro deletef (elt list &rest args)

> I wrote it like that (i.e. with the {*filter*} delete*f) because I wanted
> to preserve the order that delete used in the new deletef, and I
> wasn't aware of another way.

FWIW, and it's mostly a personal taste issue, I use the following naming
conventions in my code:

  FOO*   Same function FOO but with a spread last argument.
         e.g., absent history, what CL calls APPLY I'd call FUNCALL*.

  XFOO   Same as FOO but with arguments swapped.  Maclisp used to have an
         XCONS operator (sometimes useful for mapping and other higher order
         functions) that took CONS arguments backwards.

What you've called DELETE*, I'd have called XDELETE.  Then you could make
the macro XDELETEF.

What naming conventions you use aren't as important as that you pick a set
of naming conventions to use consistently across your code so that if someone
sees FOO* out of context, they have a good guess what it means without having
to look at the definition if they know how you code.  So unless you use
FOO* to consistently mean "reverse the args" or at least "reorder the args",
then you might consider adopting a different or more consistent style.

Quote:
> The reason I wasn't sure I'd rather use GET-SETF-EXPANSION here is
> that environment argument, which I don't feel belongs here, and I
> avoided with define-modify-macro, whereas the DROP implementation
> accepts the environment keyword argument, I'm guessing that
> DEFINE-MODIFY-MACRO bypasses that, somehow.

It does this implicitly within it.

 (XDELETEF place y)

becomes

 (SETF place (XDELETE place y))

but with appropriate calls to the GET-SETF-EXPANSION in order to avoid
multiple evaluation of place's subforms.  THe macro definition into which
DEFINE-MODIFY-MACRO expands should contian &ENVIRONMENT and all that
invisibly to you (unless you expand it to check).



Fri, 15 Aug 2003 17:54:26 GMT  
 DEFINE-MODIFY-MACRO usage question

Quote:
> FWIW, and it's mostly a personal taste issue, I use the following naming
> conventions in my code:

>   FOO*   Same function FOO but with a spread last argument.
>          e.g., absent history, what CL calls APPLY I'd call FUNCALL*.

I'm pretty sure that this convention won't work for me, as I often
append `*' when I simply want to slightly change the semantics.  But
given the way list* works in CL, I think I prefer your convention to
mine, the more I think about it.  It's just that yours doesn't come up
too often for me.

Quote:
>   XFOO   Same as FOO but with arguments swapped.  Maclisp used to have an
>          XCONS operator (sometimes useful for mapping and other higher order
>          functions) that took CONS arguments backwards.

adopted.  Works for me.

Quote:
> > The reason I wasn't sure I'd rather use GET-SETF-EXPANSION here is
> > that environment argument, which I don't feel belongs here, and I
> > avoided with define-modify-macro, whereas the DROP implementation
> > accepts the environment keyword argument, I'm guessing that
> > DEFINE-MODIFY-MACRO bypasses that, somehow.

> It does this implicitly within it.

>  (XDELETEF place y)

> becomes

>  (SETF place (XDELETE place y))

> but with appropriate calls to the GET-SETF-EXPANSION in order to avoid
> multiple evaluation of place's subforms.  THe macro definition into which
> DEFINE-MODIFY-MACRO expands should contian &ENVIRONMENT and all that
> invisibly to you (unless you expand it to check).

maybe so.  so what you're saying is that the two implementations are
the same, even with respect to the environment argument?

dave



Sat, 16 Aug 2003 00:00:09 GMT  
 DEFINE-MODIFY-MACRO usage question

Quote:

> > > The reason I wasn't sure I'd rather use GET-SETF-EXPANSION here
> > > is that environment argument, which I don't feel belongs here,
> > > and I avoided with define-modify-macro, whereas the DROP
> > > implementation accepts the environment keyword argument, I'm
> > > guessing that DEFINE-MODIFY-MACRO bypasses that, somehow.

> > It does this implicitly within it.

> >  (XDELETEF place y)

> > becomes

> >  (SETF place (XDELETE place y))

> > but with appropriate calls to the GET-SETF-EXPANSION in order to
> > avoid multiple evaluation of place's subforms.  THe macro
> > definition into which DEFINE-MODIFY-MACRO expands should contian
> > &ENVIRONMENT and all that invisibly to you (unless you expand it
> > to check).

> maybe so.  so what you're saying is that the two implementations are
> the same, even with respect to the environment argument?

Well, I didn't look at it in detail, but probably close.  There's a
stray `:count 1' injected in your first example but not in your
second, so they can't be really identical.  Plus the expansion of
DEFINE-MODIFY-MACRO isn't specified by the spec, so verifying that it
was the same would have to be done on an
implementation-by-implementation basis.  But it looks basically the
same to me at quick glance anyway...


Sat, 16 Aug 2003 01:32:35 GMT  
 DEFINE-MODIFY-MACRO usage question

Quote:

> > maybe so.  so what you're saying is that the two implementations are
> > the same, even with respect to the environment argument?

> Well, I didn't look at it in detail, but probably close.  There's a
> stray `:count 1' injected in your first example but not in your
> second, so they can't be really identical.

Yes, they're close, but there's a reason #:Erik wrote it like that and
named it like that.  Your DELETEF breaks the naming convention of
modify macros, by looking like one, even though the arguments are in
the opposite order; DROP is a better name.  More seriously, your
DELETEF breaks the CL convention on argument evaluation order, since
subforms of LIST will be evaluated before ELT; if you want to pass the
arguments in that order, you need to implement it the hard way, using
GET-SETF-EXPANSION.

Quote:
> that environment argument, which I don't feel belongs here,

Note that &ENVIRONMENT is always transparent to the caller, see
<http://www.xanalys.com/software_tools/reference/HyperSpec/Body/glo_e....>,
and almost always The Right Thing.

Also, DROP does multiple-value places by modifying the first value and
preserving the rest; DEFINE-MODIFY-MACRO just drops the other values.
Applying a modify macro to a multiple-value place is probably bug, but
if you need to do that, implement what you need.

Quote:
> (define-modify-macro delete*f (&rest args)
>   delete*)

BTW, DELETE*F has a useless lambda list, it would be better to declare
the real one: (ELT &REST KEYS) -- even though this makes no difference
to the macro expansion, you get better doc and perhaps error checking.
Also, you could just use a lambda expression here, instead of naming
a function.

You might usefully compare these to LispWorks' LW:REMOVEF
<http://www.xanalys.com/software_tools/reference/lwl41/lwref/LWRM_227....>.
--
Pekka P. Pirinen, Adaptive Memory Management Group, Harlequin Limited
A definition tells you something about the way words are used,
not about the way the universe is put together.
  - Simon van Dongen <sgvd_pi.net>



Mon, 18 Aug 2003 01:05:47 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Macros defining macros with define-syntax

2. multiple-value version of define-modify-macro ?

3. Question about a macro-defining macro

4. define-macro -> define-syntax

5. define-macro vs define-syntax

6. Scheme macro source: define/keyed, for defining keyword-triggered arguments

7. Macro-Defining Macros

8. help sought for macro defining macro

9. Load-time problem with a macro that defines a macro

10. Question about Ansi CL DEFINE-COMPILER-MACRO

11. Re-Defining bindings in Text Widget or how to modify Class Bindings

12. Problems in defining listbox and modifying the entries

 

 
Powered by phpBB® Forum Software