sta*_*93m 1 lisp scheme common-lisp funcall
我开始学习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))
Run Code Online (Sandbox Code Playgroud)
用Lisp重写相同的代码
(defun comp (a b)
(lambda (x)
(funcall a (funcall b x))))
(defun test (comp #'car #'cdr))
(funcall test '(1 2 3))
Run Code Online (Sandbox Code Playgroud)
lispworks中的错误是:
试图绑定非符号,
(FUNCTION CAR)。
所以当我尝试(defun test (comp #'car #'cdr))在听众中评估时,我得到
非符号
(FUNCTION CAR)在function中用作变量名TEST。
我不明白为什么它不能这样写。我会很感激
defun 用于定义带有参数的函数:
defun function-name lambda-list [[declaration* | documentation]] form*
Run Code Online (Sandbox Code Playgroud)
因此它在函数名称后需要一个lambda列表,但是您已经编写了:
(defun test (comp #'car #'cdr))
Run Code Online (Sandbox Code Playgroud)
不遵守这种语法。如果要定义一个包含由两个函数组成的函数的变量,则有几种可能性:
使用特殊变量:
(defvar test (comp #'car #'cdr))
Run Code Online (Sandbox Code Playgroud)在表单内使用局部变量:
(let ((test (comp #'car #'cdr)))
(funcall test '(1 2 3))
Run Code Online (Sandbox Code Playgroud)您甚至可以将其分配给全局函数名称,例如:
(setf (symbol-function 'test) (comp #'car #'cdr)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以将名称用作常规函数名称,而无需使用funcall:
(test '(1 2 3))
Run Code Online (Sandbox Code Playgroud)
(defun test (comp #'car #'cdr))
Run Code Online (Sandbox Code Playgroud)
DEFUN该名称后应有一个lambda列表,这里的lambda列表格式错误,因为#'car它不是符号,而是读为(function car)。
您可能想做的就是将函数定义test为carand 的组成cdr;(comp ...)将返回适当的函数对象,但defun不允许使用值代替lambda-list。
您可以这样做:
(setf (symbol-function 'test)
(comp #'car #'cdr))
Run Code Online (Sandbox Code Playgroud)