Subject: Re: macros, &REST and REMF
From: Erik Naggum <>
Date: 30 Nov 2002 19:09:25 +0000
Newsgroups: comp.lang.lisp
Message-ID: <>

* 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 ()))
      (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.