Common Lisp 和 Scheme 的函数命名空间不同

沙枣 发布于 2013/08/18 19:04
阅读 1K+
收藏 0

最近在 <<On Lisp>> 看到 Common Lisp 和 Scheme 的不同:

1. 在Common Lisp眼中,一个符号的symbol-value和symbol-function是不一样的,而Scheme
对两者不作区分。在Scheme里面,变量只有唯一对应的值,它可以是个函数,也可以是另一种对
象。因此,在Scheme中就不需要#’或者funcall了。Common Lisp的:


        (let ((f #’(lambda (x) (1+ x))))
        (funcall f 2))


在Scheme中将变成:


        (let ((f (lambda (x) (1+ x))))
        (f 2))


2. 由于Scheme只有一个名字空间,因而它没有必要为各个名字空间专门设置对应的赋值操作
符(例如defun和setq)。取而代之,它使用define,define的作用和defvar大致相当,同时
用set!替代了setq。在用set!为全局变量赋值前,必须先用define创建这个变量。


3. 在Scheme中,通常用define定义有名函数,它行使着defun和defvar在Common Lisp中的功
能。Common Lisp的:


    (defun foo (x) (1+ x))


有两种可能的Scheme翻译:


    (define foo (lambda (x) (1+ x)))
(define (foo x) (1+ x))


4. 在Common Lisp中,函数的参数按从左到右的顺序求值。而在Scheme中,有意地不对求值顺序加以规定。(并且语言的实现者对于忘记这点的人幸灾乐祸。)

5. Scheme不用t和nil,相应的,它有#t和#f。空列表,(),在某些实现里为真,而在另一些实现里
为假。


6. cond和case表达式里的默认子句在Scheme中带有else关键字,而不是Common Lisp中的t。


7. 某些内置操作符的名字被改掉了:consp成了pair?,而null则是null?,mapcar(几乎)是map,
等等。通常根据上下文,应该能看出这些操作符的意思。

不太明白为什么两种语言对符号对应的函数与对应的值不同,这个有点像 Perl 使用 $, @, % 来分别同一个变量名所代表的不同的数据类型一样。但从名字上一个 function-name 和一个名为 function-name 的变量有什么不同。这是不是一个 Common Lisp 设计的错误?

虽然有相应的函数可以探测到符号是否有函数的定义,但这就出现了一个变量可能对应两种不同类型的对象这种不确定情况产生。既然函数可以作为变量一样被命名,被当成参数传递,为什么在命名上采取和变量不同的机制呢?

虽然在语法上实现了函数作为第一类对象,但在心里,语言的设计者还是把函数当成一种特别的对象来处理。这明显违反了语言的一致性原则。

加载中
1
沙枣
沙枣

看似 Scheme 模型简单一些,但函数的定义似乎更复杂:

    (define (foo (lambda (x) (1+ x)))

另外一种定义方法显得层次不明:

    (define (foo x) (1+ x))

还有就是 Scheme 没有命名空间,这样多个应用程序合作的时候,程序就变得异常复杂,真和假的字面表达也比 Common lisp 多一倍的字符 #t #f .

Scheme 库太小了,这么古老的语言,如果可用的函数库再少些,只能当化石研究了。而且还有这么多的版本。

我不明白 Scheme 函数参数求值的顺序为什么不是固定的,那么按照什么顺序呢?有点搞不明白。

Scheme 资料也少,但 Common Lisp 资料太老了,也太陈旧了。

如果像 Javascript 和 CSS 的资料那样丰富多彩就好了。



ueharaai
ueharaai
(foo x) (1+ x)会被翻译成foo lambda(x) (+1 x),最终define将foo->对lambda(x)(+1 x)关联,define的形式是统一的,函数定义也是统一的,只需要找lmbda(e) e的匹配,求值顺序不固定应该是编译器的实现吧,有多种编译器的。
李德凯
李德凯
的确,资料太少了。
0
ueharaai
ueharaai
lz的意思是define 要好于 defun+defvar吧。可能在这一点上common-lisp不如scheme,对两种都不熟悉,但至少我的感觉上,scheme应该比common-lisp更容易解析些。
0
李德凯
李德凯
scheme这门语言的设计是很不错的,但是语法简洁并不一定是非常好的,因为有些时候我们在使用语言处理复杂问题的时候,总要在一些地方对语言的”设计美“做出妥协。因此,scheme更多的是用于写一些核心的东西或者当作教学或者科研语言,而commonlisp是可以用于实战的,有一些地方的设计,就是因于这种”妥协“    
0
redraiment
redraiment

这个就是Lisp-1和Lisp-2的区别:Lisp-2中函数的名字空间与数据变量的名字空间是分离的,即Common Lisp的实现方式。

Lisp-2允许函数名和数据变量名相同。大多数语言都是这样的行为,比如Java里类的成员域和成员方法名可以一样的。

至于你说的不统一,函数本来和其他类型也就是不一样的。再者,你同样不能把处理字符串的函数应用于整数。所以它的统一是体现在把函数也作为与整数、浮点数等一样的基础类型。

沙枣
沙枣
我知道 Java 因为不同的参数类型,要重载设计。用这么痛苦的语言编程,让人更加感恩。其实语言可以帮我们做很多的事情。可以让我们更轻松。
返回顶部
顶部