为什么是特殊形式?

Why is do a special form?

在 Clojure 中,为什么 do 是一种特殊形式,而不是像这样实现的函数?

(defn do [& exprs]
  (last exprs))

基本顺序执行语义

fn(好吧,fn*)实际上重用了 do 背后的逻辑,就像其他带有正文的形式一样 – let*letfn*try。由于其中有几个,让它们重用基本的 "evaluate expressions in sequence" 逻辑是有意义的;由于这本身对更复杂的特殊形式上下文之外的用户代码很有用,因此将其公开为 do.

是有意义的

如果 fn* 是基本的特殊形式,顺序计算表达式将涉及进行函数调用——这种低级设施的开销是不可接受的。

(另一方面,用隐含的 dos 包装它们的主体的宏替换其他特殊形式不会引入任何开销。然而,在 Clojure 编译器的上下文中,它也不会是一个巨大的胜利——至少在这一点上它已经相当干燥了。)

顶级do

此外,顶级 do 由编译器特殊处理

(do
  (foo)
  (bar))

在顶层(且仅在顶层)等同于

(foo)
(bar)

——也就是把各个表达式分开写出来。这允许宏输出(代码等效于)多个顶级表达式。

以这种方式解释对某些特殊函数的顶级调用并非不可能,但为此目的使用特殊形式要清晰得多。