关于 Clojure 评估的说明

Clarification on Clojure evaluation

在 Clojure for the Brave and True 的第 8 章中,一个名为 if-valid 的函数被提出(然后被拒绝)以抽象出验证检查的重复部分:

(defn if-valid
  [record validations success-code failure-code]
  (let [errors (validate record validations)]
    (if (empty? errors)
      success-code
      failure-code)))

作者解释说,处于上述状态的函数将无法工作,因为 success-codefailure-code 将在每次 if-valid 调用时进行评估。我的理解是,if 函数的测试将 return true 或 false,这决定了代码运行成功还是失败。请有人解释如何为每个 if-valid 调用评估 if 的 then 和 else 部分?

假设这个函数使用如下:

(if-valid my-data validators 
  (println "Data accepted") 
  (throw (Exception. "Bad data :(")))

这不好,因为函数参数必须先求值才能传递给函数。因此,首先打印 "Data accepted" 然后抛出异常的副作用每次都会执行,在此函数根本没有机会 运行 验证之前。