为什么在 emacs lisp 中 `let` 后有两个括号?

Why are there two parentheses after `let` in emacs lisp?

我在 emacs lisp 上做 tutorial,它正在谈论 let 函数。

;; You can bind a value to a local variable with `let':
(let ((local-name "you"))
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello local-name)
  (other-window 1))

我不明白第一行let后面的双括号的作用。他们在做什么,一个单一的集合不会做? 运行 没有它们的部分,我得到一个错误:Wrong type argument: listp, "you"

你可以在那里引入多个变量。外括号分隔绑定列表,内括号分隔单个绑定形式。

(let ((foo "one")
      (bar "two"))
  (frobnicate foo bar))

根据gnu.org,看起来你可以用一个let语句构造和初始化多个变量,所以双括号是为了让变量之间分开。

If the varlist is composed of two-element lists, as is often the case, the template for the let expression looks like this:

(let ((variable value)
      (variable value)
      …)
  body…)

没有 "双括号".

想必,您想到的是(let ((foo...)...)),您指的是let之后的((?如果是这样,考虑一下:

(let (a b c) (setq a 42)...)

IOW,let声明局部变量。它可以绑定它们。在前面的 sexp 中,它声明了 abc,但它不绑定它们中的任何一个,将其留给 let 主体来给它们赋值.

声明两个变量但只绑定其中一个变量的示例 (a):

(let ((a 42) b) ... (setq b ...) ...)

let 特殊形式采用绑定列表:(let (<binding-form> ...) <body>).

绑定形式是<symbol>(表示绑定到值nil的变量)或列表(<symbol> <value>)(其中值是在let时计算的)之一已输入)。

letlet* 之间的区别在于 "value" 位的执行方式。对于普通 let,它们在绑定任何值之前执行:

(let ((a 17) 
      (b 42)) 
  (let ((a b)  ; Inner LET
        (b a)) 
    (list a b)))

let*一个接一个地执行绑定表单。两者都有自己的位置,但你可以只使用 let 因为 (let* (<form1> <form2>...) 等同于 (let (<form1>) (let (<form2>) ...))