2014-03-02 60 views
1

我很想知道为什么set似乎是唯一的原因。例如:为什么SET不推荐使用?

(set 'nm 3) ;; set evaluates its first argument, a symbol, has to be quoted 
    nm ;; ==> evaluates to 3 
    (set 'nm 'nn) ;; assigns nn to the value cell of nm 
    nm ;; ==> evaluates to nn 
    nn ;; ==> ERROR. no value 
    (set nm 3) ;; since nm evaluates to nn ... 
    nm ;; evaluates to nn 
    nn ;; evaluates to 3 

实现类似的行为,我只能够使用setf

(setq tu 'ty) ;; 
    (symbol-value 'tu) ;; returns ty 
    (setq (symbol-value 'tu) 5) ;; ERROR. setq expects a symbol 
    (setf (symbol-value tu) 5) ;; has to be unquoted to access the value cell 
    tu ;; ==> evaluates to ty 
    ty ;; ==> evaluates to 3 

在其他编程语言为降级的理由(一个或多个)是相当清楚的:效率低下,错误容易或不安全的想到。我想知道当时set的折旧标准是什么。我能从网上收集到的是this,这是可笑的。谢谢。

回答

2

主要原因set已弃用的是,它的使用可能会导致错误的时候它是在约束变量使用(例如,在功能):

(set 'a 10) 
==> 10 
a 
==> 10 
(let ((a 1)) ; new lexical binding 
    (set 'a 15) ; modification of the value slot of the global symbol, not the lexical variable 
    a)   ; access the lexical variable 
==> 1   ; nope, not 15! 
a 
==> 15 

set是从当Lisp的是次传统功能“符号和列表的语言”。从那时起,Lisp已经成熟了;符号插槽上的直接操作比较少见,并且没有理由使用set而不是更明确的(setf symbol-value)

+0

是否有任何资源指定这种事情的细节?必须有文件的地方... – macrolyte

0

在您的例子:

(set nm 'nn) ;; assigns nn to the value cell of nm 
nm ;; ==> evaluates to nn 

这是完全错误的,为什么它弃用的主要原因。这是您在评估nm时得到的符号,与nn绑定。不幸的是,在您的示例中,数字为3,并且它将在运行时发出错误信号,因为您不能将数字用作变量。如果您要编写(setq 3 'nn),则可以在编译时查看错误。

使用set还有一个额外的原因。当你不知道要绑定什么符号并且编译器无法优化它时,编译起来非常困难。

Scheme在它的第一个版本中没有自动引用,他们甚至没有像setq这样的引用宏。相反,它表示set'就足够了。很明显,它不是因为Scheme不再有set而只有define

我个人不同意它应该被删除(最终弃用会导致删除),但像eval它应该被避免并且只能作为最后的手段使用。

+0

谢谢,这只是一个坏小狗似乎无害。看起来像奥莱耶拉需要放下... – macrolyte

相关问题