Clojure let 与 Common Lisp let

Clojure let vs Common Lisp let

在 Common Lisp 中,let 使用列表进行绑定,即:

(let ((var1 1)
      (var2 2))
  ...)

虽然 Clojure 使用向量代替:

(let [a 1
      b 2]
  ...)

除了可读性之外,Clojure 使用向量是否有任何特定原因?

您可以在 Simple Made Easy - 幻灯片 14 中找到 Rich Hickey 的论点,大约 26 分钟:

Rich 的台词如下

"Since we were talking about syntax, let’s look at classic Lisp. It seems to be the simplest of syntax, everything is a parenthesized list of symbols, numbers, and a few other things. What could be simpler? But in reality, it is not the simplest, since to achieve that uniformity, there has to be substantial overloading of the meaning of lists. They might be function calls, grouping constructs, or data literals, etc. And determining which requires using context, increasing the cognitive load when scanning code to assess its meaning. Clojure adds a couple more composite data literals to lists, and uses them for syntax. In doing so, it means that lists are almost always call-like things, and vectors are used for grouping, and maps have their own literals. Moving from one data structure to three reduces the cognitive load substantially."

他认为标准语法中超载的其中一件事是访问时间。因此,参数中的向量语法与使用它们时的常量访问时间有关。他说:

看起来很奇怪,因为它只对一种形式有效...只要它存储在变量中或以任何方式传递,信息就是 'lost'。例如...

(defn test [a]
  (nth a 0)) ;;<- what is the access time of and element of a?

我个人更喜欢严格的语法更改,例如在程序员必须切换心智模型时保留方括号,例如对于嵌入式语言。

;; Example showing a possible syntax for an embedded prolog.

{size [],0}
{size([H|T],N) :- size(T,N1), N is N1+1}

(size '(1 2 3 4) 'n) ;; here we are back to lisp code

这样的概念在句法上是不变的。您不会 'pass around' 在运行时构建。在运行时之前(read/macro/compile 时间)是另一回事,所以在可能的情况下,通常最好将事物保存为列表。

[edit] 原来的出处好像没了,这里是另外一个采访记录:https://gist.github.com/rduplain/c474a80d173e6ae78980b91bc92f43d1#file-code-quarterly-rich-hickey-2011-md