However, this prevents WITH-FOO from doing any keyword validation of the remaining arguments.
-- Barry Margolin, bar...@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.
Sam Steingold <s...@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?
* 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.