Clojure - 为什么分组需要 "do" 语句?

Clojure - why is the "do" statement necessary for grouping?

我知道 do 块将按顺序执行语句,return 最后一个的值。我 认为 如果我不需要 return 值,那么 do 就没有必要了。不考虑 return 值,那么,我不明白这两个函数的不同行为:

与 "do":

(defn x [] 
  (if true 
     (do (println "a") (println "b"))))

=> (x) 
a
b
nil

没有"do":

(defn x [] 
  (if true 
     ((println "a") (println "b"))))

=> (x) 
a
b
NullPointerException   user/x (NO_SOURCE_FILE:3)

第二个例子中出现NullPointer的原因是什么?

因为

(function argument)

...是函数调用语法,

((println "a") (println "b"))

...期望 (println "a") 到 return 一个函数,它可以用 (println "b") 的结果作为第一个参数调用它。

相反,(println "a") 没有 return 值(returns nil,又名 null),并且尝试将此 null 值作为函数调用会给您带来 NullPointerException。


顺便说一下,这里惯用​​的做法是将 if 替换为 when,这将扩展为隐式包含 do:

(defn x [] 
  (when true 
     (println "a")
     (println "b")))