Я задаюсь вопросом, если там способ, которым я могу вынудить getf сравнить использование, равное вместо eq? Я использую ccl реализацию языка Common LISP.
Нет. Вы должны использовать другую функцию; что-то примерно подобное может сделать то, что вам нужно:
(defun equal-getf (plist indicator)
(second (member indicator plist :test #'equal)))
Edit
Вот фиксированная версия, которая правильно обрабатывает список как пары ключ / значение:
(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))
Я не знаю, есть ли способ «переопределить» значение по умолчанию, посмотрим, сможете ли вы найти импл, используя (описать 'getf)
или ( symbol-plist 'getf)
. Возможной упрощенной реализацией может быть
(defun mgetf (l v) (if (< (length l) 2) NIL (if (equal (car l) v) (car (cdr l)) (mgetf (nthcdr 2 l) v))))
EDITED : используйте nthcdr вместо double cdr.
Это должно сработать. Это не очень рекурсивно, но использует прямое приложение LOOP. Чтобы позволить использовать произвольный предикат эквивалентности, путь к использованию необязательного аргумента должен быть прямым.
(defun mgetf (place indicator)
(loop for (key value . rest) on place by #'cddr
if (equal key indicator)
do (return value)))