tags:

views:

45

answers:

3

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
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
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
very naive impl compared to the other solution... a little bit rusty with lisp (which currently I use only for emacs..., when needed)...
ShinTakezou
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