如何在lisp中将函数用作变量?

时间:2011-07-30 10:16:36

标签: lisp common-lisp

我正在尝试编写一个函数来检查列表x中的每个元素是否都具有属性a,所以我写道:

(defun check (a x)
  (if (listp x)
    (eval (cons 'and (mapcar #'a x)))))

但它不起作用。 (基本上我希望a成为函数的名称,比如说blablabla,并且在check函数的主体中,#'a我想表示函数blablabla },而不是名为a的函数。)现在上面的代码不起作用。我认为在Lisp中应该能够插入函数。我该如何解决?

(这是我在口齿不清的第一天,所以这可能是一个愚蠢的问题;) 和BTW我正在使用Lispworks 6.0个人版。)

3 个答案:

答案 0 :(得分:6)

此处无需使用sharp-quote语法。其目的是在可变位置使用函数名称,但a已经是变量。只需撰写a而不是#'a

答案 1 :(得分:3)

您不需要eval即可使用apply。 问题所在:您需要funcall,因为您提供了a作为参数。 (编辑:不是这种情况。)引用你只需要参考函数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)))

答案 2 :(得分:2)

以下是我将如何编写类似于检查功能的内容。我试着给它一个更具描述性的名字。

(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))