1

我开始学习 Lisp 并使用 Lispworks 个人版 6.1.1,在评估基本功能时遇到了问题。我能够在 Scheme 中正确使用它们,但是当我尝试在 Lisp 中评估它们时它们不起作用。

我知道在 Lisp 中每个符号都有两个命名空间。所以我尝试编写简单的程序来组合两个程序。它在 Scheme 中运行良好,但在 Lisp 中存在评估问题。

方案中的代码运行良好并返回 2

(define (comp a b)
  (lambda (x)
    (a (b x))))

(define test (comp car cdr))
(test '(1 2 3))

用 Lisp 重写的相同代码

(defun comp (a b)
  (lambda (x)
    (funcall a (funcall b x))))

(defun test (comp #'car #'cdr))

(funcall test '(1 2 3))

lispworks 中的错误是:

试图绑定一个非符号,(FUNCTION CAR).

所以当我尝试(defun test (comp #'car #'cdr))在听众中进行评估时,我得到了

(FUNCTION CAR)在函数中用作变量名的非符号TEST

我不明白为什么它不能像那样写。我会感谢任何帮助

4

4 回答 4

6

defun用于定义带参数的函数:

defun function-name lambda-list [[declaration* | documentation]] form*

所以它需要在函数名之后有一个 lambda 列表,但你已经写了:

(defun test (comp #'car #'cdr))

它不尊重这种语法。如果您想定义一个包含由组合两个函数产生的函数的变量,您有几种可能性:

  1. 使用特殊变量:

    (defvar test (comp #'car #'cdr))
    
  2. 在表单中使用局部变量:

    (let ((test (comp #'car #'cdr)))
      (funcall test '(1 2 3))
    

您甚至可以将其分配给全局函数名称,例如:

(setf (symbol-function 'test) (comp #'car #'cdr)

在这种情况下,您可以将该名称用作常规函数名称,而无需funcall

(test '(1 2 3))
于 2019-06-19T08:52:13.757 回答
5
(defun test (comp #'car #'cdr))

DEFUN期望名称后有一个 lambda-list,在这里您的 lambda-list 格式不正确,因为#'car它不是符号,而是读作(function car).

您可能想要做的是将函数定义为andtest的组合;将返回适当的函数对象,但不允许有一个值代替 lambda 列表。carcdr(comp ...)defun

你可以这样做:

(setf (symbol-function 'test)
      (comp #'car #'cdr))
于 2019-06-19T08:51:35.067 回答
1

具有本地功能:

CL-USER 1 > (flet ((comp (a b)
                     (lambda (x)
                       (funcall a (funcall b x)))))
              (let ((test (comp #'car #'cdr)))
                (flet ((test (x)
                         (funcall test x)))
                  (test '(1 2 3)))))
2

CL-USER 2 > (labels ((comp (a b)
                       (lambda (x)
                         (funcall a (funcall b x))))
                     (test (x)
                       (funcall (comp #'car #'cdr) x)))
              (test '(1 2 3)))
2
于 2019-06-19T10:18:13.950 回答
0

另一个建议:

(defun comp (a b)
  (lambda (x)
     (funcall a (funcall b x))))

(defun mytest (x &key test)  ;; a "test" key is common
   (funcall test x))

(mytest '(1 2 3) :test (comp #'car #'cdr))

或者

(defun comp (x a b)
  (funcall a (funcall b x)))

(defun test (x a b)
  (comp x a b))

(test '(1 2 3) #'car #'cdr)
于 2019-06-19T11:05:45.913 回答