Как использовать функцию в качестве переменной в LISP?
Я пытаюсь написать функцию, которая проверяет, есть ли у каждого элемента в списке x свойство a, поэтому я написал:
(defun check (a x)
(if (listp x)
(eval (cons 'and (mapcar #'a x)))))
но это не работает (В основном я хочу a
быть названием функции, скажем blablabla
и в теле функции проверки, #'a
Я хочу иметь в виду функцию blablabla
вместо функции с именем a
.) Теперь приведенный выше код не работает. Я думаю, что в Лиспе нужно иметь возможность подключать функции. Как я могу это исправить?
(Это буквально мой первый день на lisp, так что это может быть глупый вопрос;) И кстати, я использую личную версию Lispworks 6.0.)
3 ответа
Здесь нет необходимости использовать синтаксис с точными кавычками. Его целью является использование имени функции в переменной позиции, но a
переменная уже Просто пиши a
вместо #'a
,
Вам не нужно eval
ты можешь использовать apply
, К проблеме: вам нужно funcall
потому что вы предоставляете a
в качестве аргумента. (Правка: не в этом случае.) Цитируя, вы просто ссылаетесь на функцию a
не в этой функции.
(defun check (a xs)
(if (listp xs)
(every #'identity (mapcar a
xs))))
Лучше использовать loop
:
(defun check (a xs)
(if (listp xs)
(loop for x in xs
always (funcall a x))))
Лучше всего использовать every
:
(defun check (a xs)
(if (listp xs)
(every a xs)))
Вот как я бы написал что-то вроде вашей функции проверки. Я попытался дать ему более описательное имя.
(defun are-all-elements-fullfilling-fun-p (fun ls)
(every #'identity (mapcar fun ls)))
Изменить: обратите внимание, что более короткое и лучшее определение
(defun are-all-elements-fullfilling-fun-p (fun ls)
(every fun ls)))
Теперь допустим, что мы хотим вызвать его с помощью этой функции. Обратите внимание, что я склонен использовать объявления, когда это возможно. Я довольно часто что-то путаю, и отладка очень проста, если компилятор может понять ошибку. Также код будет работать быстрее.
(defun is-even-p (n)
(declare (type number n))
(the boolean (= 0 (mod n 2))))
Вы должны поместить # здесь:
(are-all-elements-fullfilling-fun-p #'is-even-p '(1 2 3 4))
(are-all-elements-fullfilling-fun-p #'is-even-p '(38 2 4))