2

在 Ubuntu 上,如果我运行 MIT-Scheme,它将显示一个函数作为过程:

1 ]=> (define (sq x) (* x x))

;Value: sq

1 ]=> (sq 3)

;Value: 9

1 ]=> sq

;Value 11: #[compound-procedure 11 sq]

伯克利的 STk 将显示sq为闭包:

STk> (define (sq x) (* x x))
sq
STk> (sq 3)
9
STk> sq
#[closure arglist=(x) b73fab48]

为什么在 Lisp(Common Lisp clisp)中,当我做同样的事情时,它会给我一个错误,我怎样才能将一个函数显示为一个值(第一类值/对象)?

[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
4

2 回答 2

7

显示了由于命名空间差异导致的 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. 这种形式返回一个函数对象。

调用具有零个或多个参数的函数对象

方案:将评估函数表达式的第一个位置。

(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))
于 2015-12-13T21:29:01.733 回答
7

与 Scheme 不同,Common Lisp 为变量和函数名称保留单独的命名空间。#'sq在 CL 中尝试。也可以在谷歌周围搜索“Lisp1 vs Lisp2”,以获取关于这个主题的无休止的废话。

于 2015-12-13T19:22:16.477 回答