Subject: Re: macros, &REST and REMF From: Erik Naggum <firstname.lastname@example.org> Date: 30 Nov 2002 19:09:25 +0000 Newsgroups: comp.lang.lisp Message-ID: <email@example.com> * 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.