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

Stas Boukarev stassats at gmail.com
Sun Feb 24 16:03:35 UTC 2013


Zach Beane <xach at xach.com> writes:

> "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
If striving for shortness:

(defun delete-from-plist (plist &rest keys)
  (dolist (key keys plist)
    (remf plist key)))

-- 
With best regards, Stas.




More information about the alexandria-devel mailing list