为什么不让*默认让?

vem*_*emv 4 lisp emacs elisp

正如所有经验丰富的elispers在某些时候发现的那样,代码就像破了:

(let ((a 3)
      (b 4)
      (c (+ a b)))
  c)
Run Code Online (Sandbox Code Playgroud)

let*当引用绑定子句中的刚绑定变量时,应该使用表单.

我只是想知道 - 为什么看似错误的行为是默认的?let*无论人们如何使用它,总是有选择的风险吗?

dki*_*kim 21

任何let*形式都可以使用简单(和机械)表达let.例如,如果我们没有let*特殊表格,我们可以表达

(let* ((a 3)
       (b 4)
       (c (+ a b)))
  c)
Run Code Online (Sandbox Code Playgroud)

如:

(let ((a 3))
  (let ((b 4))
    (let ((c (+ a b)))
      c)))
Run Code Online (Sandbox Code Playgroud)

另一方面,let如果可能的话,某些形式很难表达使用let*.如果不引入额外的临时变量或深奥的按位操作,let则无法表达以下形式let*.

(let ((x y) (y x)) ; swap x and y
  ...)
Run Code Online (Sandbox Code Playgroud)

因此,从这个意义上讲,我认为let比基本更重要let*.


Joa*_*ora 6

我被告知原因主要是历史性的,但它可能仍然存在:因为let并行分配,变量之间没有数据依赖性可能会使编译器灵活地编译速度或空间并编译成更快的速度let*.我不知道elisp编译器使用了多少.

一些谷歌搜索揭示了Common Lisp的类似问题:在Common Lisp中LET与LET*

  • 我不确定Elisp和CL编译器现在是如何做的,但Hyperspec是CL的事实上的标准参考,[说明不同](http://www.lispworks.com/documentation/lw50/CLHS/ Body/s_let_l.htm):"形式`(let((var1 init-form-1)(var2 init-form-2)...)...)`首先计算表达式`init-form-1` ,`init-form-1`,等等,**按此顺序**,保存结果值." (2认同)