Below are three different implementations of remove-from-plist, all of which I find more aestetic than current alexandria's implementation. YMMV.
I would favor the first one, which explicitly ditches error checking ("it's user responsibility", and a proper plist will be returned).
In case somebody disagrees, the second implementation reintroduces it, albeit with a better error message.
The third implementation checks for properness only at the end (outside the loop), while still being shorter than alexandria's implementation.
I would also remove the FIXME, on grounds that if plists are long enough for that to matter, one shouldn't be using them anyway.
(defun remove-from-plist (plist &rest keys) (loop for (key value) on plist by #'cddr unless (member key keys :test #'eq) collect key and collect value))
(defun remove-from-plist (plist &rest keys) (loop for (key . rest) on plist by #'cddr do (assert rest () "Expected a proper plist, got ~S" plist) unless (member key keys :test #'eq) collect key and collect (first rest)))
(defun remove-from-plist (plist &rest keys) (loop with last = t for (key . rest) on plist by #'cddr do (setf last rest) unless (member key keys :test #'eq) collect key and collect (first rest) finally (assert last () "Expected a proper plist, got ~S" plist)))
Cheers, Michael
Michael Weber michaelw+alexandria@foldr.org writes:
Below are three different implementations of remove-from-plist, all of which I find more aestetic than current alexandria's implementation. YMMV.
I would favor the first one, which explicitly ditches error checking ("it's user responsibility", and a proper plist will be returned).
What about using Alexandria's DOPLIST which does the error checking for us?
-T.
(defun remove-from-plist (plist &rest keys) (let (result) (doplist (k v plist (nreverse result)) (unless (member k keys :test #'eq) (push k result) (push v result)))))
I would also remove the FIXME, on grounds that if plists are long enough for that to matter, one shouldn't be using them anyway.
i'll remove the FIXME, but sticking to my conventions, i'll leave the (searchable) comment there if somebody is bored and looking for things to do... :)
(defun remove-from-plist (plist &rest keys) (loop for (key value) on plist by #'cddr unless (member key keys :test #'eq) collect key and collect value))
(defun remove-from-plist (plist &rest keys) (loop for (key . rest) on plist by #'cddr do (assert rest () "Expected a proper plist, got ~S" plist) unless (member key keys :test #'eq) collect key and collect (first rest)))
thanks, looks better! in the absence of any other comments, i'll push this second variant eventually.
(defun remove-from-plist (plist &rest keys) (loop with last = t for (key . rest) on plist by #'cddr do (setf last rest) unless (member key keys :test #'eq) collect key and collect (first rest) finally (assert last () "Expected a proper plist, got ~S" plist)))
On 3/11/08, Michael Weber michaelw+alexandria@foldr.org wrote:
I would also remove the FIXME, on grounds that if plists are long enough for that to matter, one shouldn't be using them anyway.
It's not a question of length of plists, but of number of plists. It's a FIXME.
Cheers,
-- Nikodemus
I would also remove the FIXME, on grounds that if plists are long enough for that to matter, one shouldn't be using them anyway.
It's not a question of length of plists, but of number of plists. It's a FIXME.
i've pushed the second variant and kept the FIXME.
thanks,
alexandria-devel@common-lisp.net