From: Sam Steingold
Subject: macros, &REST and REMF
Date: 
Message-ID: <m365ufhkl1.fsf@loiso.podval.org>
Is this the right idiom:

(defmacro with-foo ((&key foo) &body body)
  `(... ,foo ... ,@body))

(defmacro with-foo-bar ((&rest opts &key bar &allow-other-keys) &body body)
  (remf opts :bar)
  `(with-foo (,@opts)
     ... ,bar ... ,@body))

I.e., I want all options for WITH-FOO to be available in WITH-FOO-BAR.

thanks.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat8 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
Isn't "Microsoft Works" an advertisement lie?

From: Rob Warnock
Subject: Re: macros, &REST and REMF
Date: 
Message-ID: <wK-cnXfOnZJd4HWgXTWcqA@giganews.com>
Sam Steingold  <···@gnu.org> wrote:
+---------------
| Is this the right idiom:
| (defmacro with-foo ((&key foo) &body body)
|   `(... ,foo ... ,@body))
| 
| (defmacro with-foo-bar ((&rest opts &key bar &allow-other-keys) &body body)
|   (remf opts :bar)
|   `(with-foo (,@opts)
|      ... ,bar ... ,@body))
+---------------

Side question for the group: What are the rules for a &REST arg
in macros? If they're the same as functions, then could you possibly
get in trouble with Sam's idiom due to REMF destructively modifying
the "opts" list? That is, does one really need to do this instead?

  (defmacro with-foo-bar ((&rest opts &key bar &allow-other-keys) &body body)
    (let ((mutable-opts (copy-list opts)))
      (remf mutable-opts :bar)
      `(with-foo (,@mutable-opts)
         ... ,bar ... ,@body)))


-Rob

-----
Rob Warnock, PP-ASEL-IA		<····@rpw3.org>
627 26th Avenue			<URL:http://www.rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Erik Naggum
Subject: Re: macros, &REST and REMF
Date: 
Message-ID: <3247672165664225@naggum.no>
* Rob Warnock
| Side question for the group: What are the rules for a &REST arg in
| macros? If they're the same as functions, then could you possibly get in
| trouble with Sam's idiom due to REMF destructively modifying the "opts"
| list?

  I believe that is the actual question, presented in his usual turbid way.
  The "idiom" is a recipe for disaster for macros and functions precisely
  because it may clobber a list that it does not own, but it is, of course,
  not a question about `remf�.  The issue of ownership of the argument list,
  which has been answered many times over and which does not change just
  because of some particular operator, should be pretty clear: Do not mutate
  the argument list.  This is close to a principle, and the answer does not
  change depending on the operator used to transmogrify it, obviously.

(defun sans (plist &rest keys)
  (let ((sans ()))
    (loop
      (let ((tail (nth-value 2 (get-properties plist keys))))
        ;; this is how it ends
        (unless tail
          (return (nreconc sans plist)))
        ;; copy all the unmatched keys
        (loop until (eq plist tail) do
              (push (pop plist) sans)
              (push (pop plist) sans))
        ;; skip the matched key
        (setq plist (cddr plist))))))

  I wrote this some time ago when I wanted to find a use for `nreconc�.

  It can be called as `(apply <function> (sans <arglist> :foo))�.  Its main
  features are that it conses minimally and is more efficient than making
  multiple passes over the same list for more than one key.  (It is assumed
  that `get-properties� is fast.)

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Barry Margolin
Subject: Re: macros, &REST and REMF
Date: 
Message-ID: <HHYF9.5$9N6.1572@paloalto-snr1.gtei.net>
In article <··············@loiso.podval.org>,
Sam Steingold  <···@gnu.org> wrote:
>Is this the right idiom:
>
>(defmacro with-foo ((&key foo) &body body)
>  `(... ,foo ... ,@body))
>
>(defmacro with-foo-bar ((&rest opts &key bar &allow-other-keys) &body body)
>  (remf opts :bar)
>  `(with-foo (,@opts)
>     ... ,bar ... ,@body))
>
>I.e., I want all options for WITH-FOO to be available in WITH-FOO-BAR.

It's a pretty common style.  Another possibility is:

(defmacro with-foo-bar (...)
  `(with-foo (:allow-other-keys t ,@opts)
     ... ,bar ... ,@body))

However, this prevents WITH-FOO from doing any keyword validation of the
remaining arguments.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.