Emacs 什么';词法范围界定有多好?

Emacs 什么';词法范围界定有多好?,emacs,closures,elisp,emacs24,Emacs,Closures,Elisp,Emacs24,我不明白为什么Emacs 24的新词汇范围功能如此强大,是因为我想不出任何没有它们就无法实现的新功能。例如,以下闭包: 可以通过以下常规动态范围来实现: 好吧,并不是所有的语言都有类似于elisp的未知符号的东西,所以我理解为什么词汇范围在它们的例子中如此重要。但是elisp呢?你能想到我现在能做的事情吗(从Emacs 24开始),我以前不能做的事情,多亏了词法范围吗?你不需要不需要的符号,用cons代替make symbol,car代替eval,和setcar而不是set,您的示例也同样有

我不明白为什么Emacs 24的新词汇范围功能如此强大,是因为我想不出任何没有它们就无法实现的新功能。例如,以下闭包:

可以通过以下常规动态范围来实现:


好吧,并不是所有的语言都有类似于elisp的未知符号的东西,所以我理解为什么词汇范围在它们的例子中如此重要。但是elisp呢?你能想到我现在能做的事情吗(从Emacs 24开始),我以前不能做的事情,多亏了词法范围吗?

你不需要不需要的符号,用
cons
代替
make symbol
car
代替
eval
,和
setcar
而不是
set
,您的示例也同样有效(而且效率更高)

还要注意的是,从机器语言到更高级语言的发展主要是基于使越来越多的事情变得不可能(或者至少更加困难)。当然,那些从程序员那里拿走的设施很少被使用和/或被认为太危险。考虑使用未初始化的变量(在C语言中可能,但在Java和许多其他语言中不可能),或者跳转到指令中间


至于示例代码的一些缺点:不仅可读性较差,而且编译器基本上无法知道您正在构造代码,因此不允许它查看“`(lambda…”,以编译它,扩展其宏调用,对可疑元素发出警告,…

在Emacs中模拟词法绑定总是有一些变通方法,所以这与能够做新事情无关

手册上说:

词汇绑定为优化打开了更多的机会,所以 使用词法绑定的Emacs Lisp代码可能会运行 在未来的Emacs版本中速度更快。这样的代码也更加友好 我们希望在不久的将来将其添加到Emacs中

我认为这是主要的好处

另一方面,动态绑定是在编写Emacs时故意选择的,这在今天仍然适用,因此词汇绑定当然不应该被视为一种新的处理方式

全局变量在编程中通常被认为是一个坏主意,但Emacs是一个不太常见的情况,因为它的巨大灵活性——使Emacs变得伟大的关键因素之一——直接来自动态绑定。如果没有动态绑定,就不可能将应用程序弯曲到Emacs允许的程度,以满足单个用户的需求


在我看来,词汇绑定应该谨慎使用,并且只能用于其他用户无法找到重写原因的变量。默认情况下,变量应该是
defvar
'd,这样就可以保留自定义行为的能力(即使是作者没有预料到的方式)。

我认为OO编程的实现往往很适合词法范围。具有状态的对象相当直接地映射到词法闭包


我确信CommonLisp中的CLOS实现在很大程度上利用了词法范围。我很难想象该规范如何仅用动态范围来实现,但我确信这是可能的。

当然,正如您所示,可以用动态范围来模拟词汇范围,但您为什么要这样做?词法范围示例不是更易于编写和阅读吗?如果您真的想要一种只包含“必要”功能的基本语言,请查看。我认为它应该能让你相信,在语言中有一些更重要的东西,它们不是严格意义上的“必需”,但在你编程时仍然有用。正如我上面所写的,读写起来更容易,但我打赌你可以编写一个宏,使它比使用真正的词法范围更容易。不管怎么说,我只是想知道词汇范围界定在理论上是否有任何可能的东西,这是非常有用的。使用
cons
而不是
makesymbol
也同样有意义,而且更具可读性。尽管我注意到cl包有一个
lexical let
宏,它使用了不需要的符号。嗯,不,不,不。Emacs是在几乎所有Lisp都是动态范围的时候制作的(编译形式除外,这是另一个故事),特别是elisp派生的maclisp。因此,动态范围肯定不是“故意选择的”。此外,全局变量在词汇范围内的语言中表现相同,因此Emacs在这里并不少见。最后,动态范围提供的灵活性在静态范围的语言中是完全可用的,所以这也是假的。@EliBarzilay RMS看起来也不像是盲目地选择了动态绑定:@DeokhwanKim:(a)RMS当然知道这一点——就像当时所有的Lisper一样;(b) 然而,他并没有选择它,相反,他选择了它附带的lisp;(c) 事实上,您所指的部分中的示例正好显示了动态范围的一种不好的用法——这将使Emacs抛出编译警告;(d) 最后,扩展性点在许多情况下(包括Emacs)都是有效的(并在下一节中进行了很好的解释),这就是为什么动态绑定变量的概念仍然存在于词汇语言中的原因,只是不是作为所有绑定的默认值。@EliBarzilay我不确定他是否会选择一个词典范围的Lisp,如果它在当时广泛使用的话。从“Stallman过去说过,他非常不喜欢CL的词汇范围性质,emacs lisp决定保留Maclisp风格的动态范围界定并不是偶然的。”他似乎认为动态范围界定比词汇范围界定更适合emacs,w
(setq lexical-binding t)
(defun f1 (num1)
  (lambda (num2)
    (setq num1 (* num1 num2))))

(fset 'f2 (f1 5))
  ==> (closure ((num1 . 5) t) (num2) (setq num1 (* num1 num2)))
(f2 5)
  ==> 25
(f2 2)
  ==> 50
(defun f1 (num)
  (let ((tmpvar (make-symbol "num")))
    (set tmpvar num)
    `(lambda (num2)
       (set ',tmpvar (* (eval ,tmpvar) num2)))))

(fset 'f2 (f1 5))
  ==> (lambda (num2) (set (quote num) (+ (eval num) num2)))
(f2 5)
  ==> 25
(f2 2)
  ==> 50
(fset 'f3 (f1 9))
  ==> (lambda (num2) (set (quote num) (+ (eval num) num2)))
(f3 3)
  ==> 27
(f3 2)
  ==> 54
(f2 10)
  ==> 500