在 lisp 中编写一个利用两个命名空间的测试函数
Writing a test function leveraging two namespaces in lisp
开始学习Lisp,使用Lispworks个人版6.1.1,在评估基本功能时遇到问题。我能够在 Scheme 中使它们正确,但是当我尝试在 Lisp 中评估它们时它们不起作用。
我知道在 Lisp 中每个符号都有两个名称空间。所以我试着写一个简单的程序来组合两个程序。它在 Scheme 中运行完美,但在 Lisp 中存在计算问题。
方案中的代码运行良好 return 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 中的错误是:
Trying to bind a non-symbol, (FUNCTION CAR)
.
所以当我尝试在侦听器中评估 (defun test (comp #'car #'cdr))
时,我得到
Non-symbol (FUNCTION CAR)
used as variable name in function TEST
.
我不明白为什么它不能像那样写。我会感谢任何帮助
(defun test (comp #'car #'cdr))
DEFUN
期望名称后有 lambda-list,这里您的 lambda-list 格式不正确,因为 #'car
不是符号,而是读作 (function car)
。
你可能想要做的是将函数test
定义为car
和cdr
的组合; (comp ...)
会 return 适当的函数对象,但 defun
不允许用值代替 lambda-list.
你可以这样做:
(setf (symbol-function 'test)
(comp #'car #'cdr))
defun
用于定义一个带参数的函数:
defun function-name lambda-list [[declaration* | documentation]] form*
所以函数名后面需要一个lambda列表,但是你写了:
(defun test (comp #'car #'cdr))
不遵守此语法。如果你想定义一个包含由组合两个函数产生的函数的变量,你有几种可能性:
使用特殊变量:
(defvar test (comp #'car #'cdr))
在表单中使用局部变量:
(let ((test (comp #'car #'cdr)))
(funcall test '(1 2 3))
您甚至可以将其分配给全局函数名称,例如:
(setf (symbol-function 'test) (comp #'car #'cdr)
在这种情况下,您可以将该名称用作常规函数名称,而不使用 funcall
:
(test '(1 2 3))
具有局部函数:
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
另一个建议:
(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)
开始学习Lisp,使用Lispworks个人版6.1.1,在评估基本功能时遇到问题。我能够在 Scheme 中使它们正确,但是当我尝试在 Lisp 中评估它们时它们不起作用。
我知道在 Lisp 中每个符号都有两个名称空间。所以我试着写一个简单的程序来组合两个程序。它在 Scheme 中运行完美,但在 Lisp 中存在计算问题。
方案中的代码运行良好 return 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 中的错误是:
Trying to bind a non-symbol,
(FUNCTION CAR)
.
所以当我尝试在侦听器中评估 (defun test (comp #'car #'cdr))
时,我得到
Non-symbol
(FUNCTION CAR)
used as variable name in functionTEST
.
我不明白为什么它不能像那样写。我会感谢任何帮助
(defun test (comp #'car #'cdr))
DEFUN
期望名称后有 lambda-list,这里您的 lambda-list 格式不正确,因为 #'car
不是符号,而是读作 (function car)
。
你可能想要做的是将函数test
定义为car
和cdr
的组合; (comp ...)
会 return 适当的函数对象,但 defun
不允许用值代替 lambda-list.
你可以这样做:
(setf (symbol-function 'test)
(comp #'car #'cdr))
defun
用于定义一个带参数的函数:
defun function-name lambda-list [[declaration* | documentation]] form*
所以函数名后面需要一个lambda列表,但是你写了:
(defun test (comp #'car #'cdr))
不遵守此语法。如果你想定义一个包含由组合两个函数产生的函数的变量,你有几种可能性:
使用特殊变量:
(defvar test (comp #'car #'cdr))
在表单中使用局部变量:
(let ((test (comp #'car #'cdr))) (funcall test '(1 2 3))
您甚至可以将其分配给全局函数名称,例如:
(setf (symbol-function 'test) (comp #'car #'cdr)
在这种情况下,您可以将该名称用作常规函数名称,而不使用 funcall
:
(test '(1 2 3))
具有局部函数:
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
另一个建议:
(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)