在Clojure中,为什么do
是一个特殊形式,而不是像这样实现的函数?
(defn do [& exprs]
(last exprs))
答案 0 :(得分:6)
fn
(嗯,fn*
)实际上重用了do
背后的逻辑,其他形式与身体一样 - let*
,letfn*
,{{1 }}。由于存在其中的一些,因此让它们重复使用基本的"评估表达式中的表达式是有意义的。逻辑;因为这本身对于更复杂的特殊形式的上下文之外的用户代码是有用的,所以将它公开为try
是有意义的。
相反,do
是基本的特殊形式,顺序计算表达式将涉及进行函数调用 - 这种开销对于这种低级设施是不可接受的。
(另一方面,用隐式fn*
包裹其主体的宏替换其他特殊形式不会引入任何开销。但是,在Clojure编译器的上下文中,它是也不会是一个巨大的胜利 - 至少在这一点上它已经相当干了。)
do
此外,顶级do
由编译器专门处理
do
在顶级(仅在顶级)与
相同(do
(foo)
(bar))
- 即分别写出的个别表达。这允许宏输出(代码相当于)多个顶级表达式。
以这种方式解释对某些特殊功能的顶级调用是不可能的,但为此目的使用特殊表单非常清晰。