在 Clojure 中,为什么是do
特殊的形式,而不是像这样实现的函数?
(defn do [& exprs]
(last exprs))
在 Clojure 中,为什么是do
特殊的形式,而不是像这样实现的函数?
(defn do [& exprs]
(last exprs))
fn
(嗯,fn*
)实际上重用了 背后的逻辑do
,就像其他带有主体的形式一样 - let*
,letfn*
,try
。由于其中有几个,让它们重用基本的“按顺序评估表达式”逻辑是有意义的;并且由于这本身对更复杂的特殊形式的上下文之外的用户代码很有用,因此将其公开为do
.
相反,如果fn*
是基本的特殊形式,顺序评估表达式将涉及进行函数调用——这种低级工具的开销是不可接受的。
(另一方面,将其他特殊形式替换为将其主体包裹在隐式do
s 中的宏不会引入任何开销。但是,就目前的 Clojure 编译器而言,这也不会是一个巨大的胜利——在这一点至少它已经相当干燥了。)
do
此外,顶级do
s 被编译器特殊处理,因为
(do
(foo)
(bar))
在顶层(并且仅在顶层)等效于
(foo)
(bar)
——也就是说,对于单独写出的单个表达式。这允许宏输出(代码等效于)多个顶级表达式。
以这种方式解释对某些特殊函数的顶级调用并非不可能,但为此目的使用特殊形式会明显更简洁。