在Scheme或STk中,一个函数会显示为过程或闭包,但为什么LISP会报错呢?
In Scheme or STk, a function will be shown as a procedure or closure, but why does LISP give an error?
在 Ubuntu 上,如果我 运行 MIT-Scheme,它将显示一个函数作为过程:
1 ]=> (define (sq x) (* x x))
;Value: sq
1 ]=> (sq 3)
;Value: 9
1 ]=> sq
;Value 11: #[compound-procedure 11 sq]
Berkeley 的 STk 将 sq
显示为闭包:
STk> (define (sq x) (* x x))
sq
STk> (sq 3)
9
STk> sq
#[closure arglist=(x) b73fab48]
怎么会出现在 Lisp(Common Lisp clisp)中,当我做同样的事情时,它反而会给我一个错误,以及我如何将一个函数显示为一个值(第一个 class 值/对象)?
[1]> (defun sq(x) (* x x))
SQ
[2]> (sq 3)
9
[3]> sq
*** - SYSTEM::READ-EVAL-PRINT: variable SQ has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of SQ.
STORE-VALUE :R2 Input a new value for SQ.
ABORT :R3 Abort main loop
与 Scheme 不同,Common Lisp 为变量和函数名称保留了单独的命名空间。在 CL 中尝试 #'sq
。还有 google 围绕着 'Lisp1 vs Lisp2' 关于这个主题的无休止的废话。
显示Scheme 和Common Lisp 之间由命名空间差异引起的语法差异。 Scheme 为函数和变量提供一个命名空间。 Common Lisp 对函数和变量有不同的命名空间。 Common Lisp 中的一个名称可以同时具有不同的含义:变量、函数等等。
函数定义
这些差异不是由命名空间差异引起的。
方案:(define (foo a) (+ a 1))
普通 Lisp:(defun foo (a) (+ a 1))
获取函数对象作为值
方案:foo
Common Lisp:(function foo)
或更短的 #'foo
。这种形式 returns 一个函数对象。
调用具有零个或多个参数的函数对象
方案:将计算函数表达式的第一个位置。
(let ((bar foo))
(bar 10))
Common Lisp:我们需要使用funcall
来调用带参数的函数对象。第一个参数必须是函数对象。
(let ((bar #'foo))
(funcall bar 10))
名称冲突:一个命名空间与两个命名空间
方案:需要命名局部变量,以免它们与定义的函数冲突:
(define (foo lst)
(list lst))
Common Lisp:函数和变量之间可能没有名称冲突。
(defun foo (list)
(list list))
在 Ubuntu 上,如果我 运行 MIT-Scheme,它将显示一个函数作为过程:
1 ]=> (define (sq x) (* x x))
;Value: sq
1 ]=> (sq 3)
;Value: 9
1 ]=> sq
;Value 11: #[compound-procedure 11 sq]
Berkeley 的 STk 将 sq
显示为闭包:
STk> (define (sq x) (* x x))
sq
STk> (sq 3)
9
STk> sq
#[closure arglist=(x) b73fab48]
怎么会出现在 Lisp(Common Lisp clisp)中,当我做同样的事情时,它反而会给我一个错误,以及我如何将一个函数显示为一个值(第一个 class 值/对象)?
[1]> (defun sq(x) (* x x))
SQ
[2]> (sq 3)
9
[3]> sq
*** - SYSTEM::READ-EVAL-PRINT: variable SQ has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of SQ.
STORE-VALUE :R2 Input a new value for SQ.
ABORT :R3 Abort main loop
与 Scheme 不同,Common Lisp 为变量和函数名称保留了单独的命名空间。在 CL 中尝试 #'sq
。还有 google 围绕着 'Lisp1 vs Lisp2' 关于这个主题的无休止的废话。
显示Scheme 和Common Lisp 之间由命名空间差异引起的语法差异。 Scheme 为函数和变量提供一个命名空间。 Common Lisp 对函数和变量有不同的命名空间。 Common Lisp 中的一个名称可以同时具有不同的含义:变量、函数等等。
函数定义
这些差异不是由命名空间差异引起的。
方案:(define (foo a) (+ a 1))
普通 Lisp:(defun foo (a) (+ a 1))
获取函数对象作为值
方案:foo
Common Lisp:(function foo)
或更短的 #'foo
。这种形式 returns 一个函数对象。
调用具有零个或多个参数的函数对象
方案:将计算函数表达式的第一个位置。
(let ((bar foo))
(bar 10))
Common Lisp:我们需要使用funcall
来调用带参数的函数对象。第一个参数必须是函数对象。
(let ((bar #'foo))
(funcall bar 10))
名称冲突:一个命名空间与两个命名空间
方案:需要命名局部变量,以免它们与定义的函数冲突:
(define (foo lst)
(list lst))
Common Lisp:函数和变量之间可能没有名称冲突。
(defun foo (list)
(list list))