Clojure let与Common Lisp let

Clojure let与Common Lisp let,clojure,lisp,common-lisp,let,Clojure,Lisp,Common Lisp,Let,在Common Lisp中,let为绑定使用列表,即: (let ((var1 1) (var2 2)) ...) 而Clojure则使用向量: (let [a 1 b 2] ...) 除了可读性之外,Clojure使用向量还有什么特别的原因吗?你可以在幻灯片14中找到Rich Hickey的论点,大约26分钟: 里奇对此的看法如下 “既然我们讨论的是语法,那么让我们看看 经典的Lisp。它似乎是最简单的语法,所有东西都是 括号中的符号、数字和其他一些东西。什

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

(let ((var1 1)
      (var2 2))
  ...)
而Clojure则使用向量:

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

除了可读性之外,Clojure使用向量还有什么特别的原因吗?

你可以在幻灯片14中找到Rich Hickey的论点,大约26分钟:


里奇对此的看法如下

“既然我们讨论的是语法,那么让我们看看 经典的Lisp。它似乎是最简单的语法,所有东西都是 括号中的符号、数字和其他一些东西。什么 可能更简单吗?但实际上,这并不是最简单的,因为 要实现这种一致性,必须有大量的负载 列表的含义。它们可能是函数调用、分组 构造或数据文本等,并确定需要 使用上下文,增加扫描代码时的认知负荷 评估它的意义。Clojure添加了更多的复合数据文本 ,并将其用于语法。这样做意味着 几乎总是调用类似的东西,向量用于分组, 地图有自己的文字。从一个数据结构移动到另一个数据结构 三是大大降低了认知负荷。”

他认为标准语法中过载的事情之一是访问时间。因此,参数中的向量语法与使用它们时的恒定访问时间有关。他说,

看起来很奇怪,因为它只对一种形式有效……一旦它存储在变量中或以任何方式传递,信息就会“丢失”。例如

(defn test [a]
  (nth a 0)) ;;<- what is the access time of and element of a?
这样一个概念在句法上是恒定的。您不会在运行时“传递”结构。运行前(读取/宏/编译时)是另一回事,尽管如此,在可能的情况下,最好将内容保持为列表

[编辑]

最初的消息来源似乎已经消失了,但下面是采访的另一个记录:

是的,我想线索就在这句话中:“电话和分组超载”。谢谢现在方括号被(更少的)分组和向量语法重载。@RainerJoswig如果它们不是按顺序绑定的,那么对于Clojure
let
loop
“重载调用和分组”,使用map literal
{…}
而不是向量literal
[…]
可能更符合逻辑这就是Lisp的要点。一切都是一张单子。“函数调用”只是
eval
ing列表。@darkfeline我不愿意在上面表达我自己的观点。然而,这里有。。。如果像Clojure一样,您有几种特殊的数据结构形式,那么使用它们来组织视觉程序是有意义的(称之为可读性或减少认知负荷或您需要的东西)。首先,你是否应该有几种这样的特殊形式还没有定论。在这件事上,我比你更接近里奇,但这是品味的问题。例如,对我来说,用经典的Lisp语法很难理解多个arity函数。
LET
语法不是常见Lisp的一个特定特性。基本上每个Lisp(Emacs Lisp、ISLisp、Scheme等)都支持这种语法。Clojure没有。Clojure
let
按顺序绑定。因此,它相当于CL和Scheme
let*
。愚人节?访问时间不能过载。不是语法上的,不是一般意义上的。可以观察或预期访问时间。Clojure中的向量没有固定的访问时间。引用名称不会传递类型或访问时间信息,除非您对它们进行命名,以便它们传递类型或访问时间信息。无论如何,这与通过文字的语法和构造无关。Clojure不“嵌入”Prolog或任何语言,因此在嵌入语言时保留括号的偏好就像要求汽车有翅膀而不是门一样。Clojures的顶级函数定义宏被称为
defn
,而不是“defun”。我已经纠正了输入错误,为了澄清这一点,Rich的一句话(我试图找到源代码)是列表的使用方式被重载了。不仅在分组方面,而且在访问时间方面。因为元素的访问时间是一个列表,而向量中的元素不相同,所以分组参数的向量是更好的选择,因为它反映了(大致)恒定的访问时间。我也没有说clojure已经嵌入了prolog,我说我更喜欢保留语法,以便使用嵌入式语言之类的东西。您可能还注意到了问题上的common lisp标记……这意味着将有一些答案与您可以在common lisp中执行的操作有关,例如扩展用于分组参数的ReaderVector(称为绑定向量),出于美学原因,这些参数被选为向量。它们优越的随机访问时间特性并不重要:运行时性能不受影响,列表的编译性能应该更好,因为访问它们的第一个元素具有O(1)特性。请参考
fn*
特殊形式的编译器源代码的相关部分:我知道。我试图说明语法概念是重载的……没有运行时或编译时含义,纯粹是认知的。我找不到这句话,我现在也没有时间翻阅所有的视频来找到它。你所说的没有错,只是不适用于我试图表达的东西(我承认很糟糕)。无论如何,为合理的评论和良好的链接干杯。该喝杯啤酒了,再见
;; 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