为什么这段代码即使没有开括号也能正常工作

时间:2014-07-01 16:29:16

标签: clojure

为什么这段代码有效?

(defn g []
     do (println 10) (println 20))

注意:没有(在做之前。

1 个答案:

答案 0 :(得分:8)

理论上这不应该编译。编译器应该抱怨do无法解析,因为它是一个不在表单第一个位置的特殊符号。

对于do特殊形式和fn*特殊形式的正文,使用相同的BodyExpr parsing code可能会产生(可能是非预期的)后果。编译do特殊表单时,将删除前导do并编译其余表单。对函数体使用相同的解析器意味着单个裸do也可以首先出现。

public static class BodyExpr implements Expr, MaybePrimitiveExpr{

    ...

    public Expr parse(C context, Object frms) {
        ISeq forms = (ISeq) frms;
        if(Util.equals(RT.first(forms), DO))
            forms = RT.next(forms);

    ....

您会注意到,如果重复do,则

(defn g [] do do (println 10) (println 20))
;=> CompilerException java.lang.RuntimeException: 
      Unable to resolve symbol: do in this context ...

按预期编译。