I am wondering if there a way that I can force getf to compare using equal instead of eq? I am using the ccl implementation of common lisp.
+3
A:
No. You have to use a different function; something approximately like this might do what you need:
(defun equal-getf (plist indicator)
(second (member indicator plist :test #'equal)))
Edit
Here's a fixed version that treats the list properly as key/value pairs:
(defun equal-getf (plist indicator)
(loop for key in plist by #'cddr
for value in (rest plist) by #'cddr
when (equal key indicator)
return value))
Xach
2010-06-10 20:24:59
it is bugged as said, i.e. has a different behaviour and so is not suitable as a replacement for getf (I mean no lacking of extra argument, I mean the fact that it does not treat the list as built of key-value pair); so, virtually, -1
ShinTakezou
2010-06-11 10:13:43
A:
I don't know if there's a way to "override" the default, see if you can find an impl using (describe 'getf)
or (symbol-plist 'getf)
. A possible semplified implementation could be
(defun mgetf (l v) (if (< (length l) 2) NIL (if (equal (car l) v) (car (cdr l)) (mgetf (nthcdr 2 l) v))))
EDITED : use nthcdr instead of double cdr.
ShinTakezou
2010-06-10 20:41:51
very naive impl compared to the other solution... a little bit rusty with lisp (which currently I use only for emacs..., when needed)...
ShinTakezou
2010-06-10 20:42:53
A:
This should do the job. It's not nicely recursive, but uses a straight-forward LOOP application. To allow it ti use an arbitrary equivalence predicate, the route to using an optional argument should be straight-forward.
(defun mgetf (place indicator)
(loop for (key value . rest) on place by #'cddr
if (equal key indicator)
do (return value)))
Vatine
2010-06-12 13:13:47