[alexandria-devel] Implementation of DELETE-FROM-PLIST

Zach Beane xach at xach.com
Sun Feb 24 15:56:36 UTC 2013


"James M. Lawrence" <llmjjmll at gmail.com> writes:

> Using two loops seems awkward to me. How about one?
>
> (defun delete-from-plist (plist &rest keys)
>   (loop with head = plist
>         with tail = nil
>         for (key . rest) on plist by #'cddr
>         do (assert rest () "Expected a proper plist, got ~S" plist)
>            (if (member key keys :test #'eq)
>                (let ((next (cdr rest)))
>                  (if tail
>                      (setf (cdr tail) next)
>                      (setf head next)))
>                (setf tail rest))
>         finally (return head)))

I mention this for completeness and novelty, not for suitability:

  (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 don't think I've seen GET-PROPERTIES and NRECONC outside this
function.

I got it from here:
http://xach.com/naggum/articles/3247672165664225%40naggum.no.html

Zach




More information about the alexandria-devel mailing list