If statement 如何在测试和cond结果中使用结果?

If statement 如何在测试和cond结果中使用结果?,if-statement,clojure,If Statement,Clojure,我有以下代码: (cond (case-1? (compute-1 x)) (compute-1 x) (case-2? (compute-2 x)) (compute-2 x) (case-3? (compute-3 x)) (compute-3 x)) 我希望避免重复计算compute-1、compute-2和compute-3。一种选择是: (let [result-1 (compute-1 x) result-2 (compute-2 x) resu

我有以下代码:

(cond
  (case-1? (compute-1 x)) (compute-1 x)
  (case-2? (compute-2 x)) (compute-2 x)
  (case-3? (compute-3 x)) (compute-3 x))
我希望避免重复计算
compute-1
compute-2
compute-3
。一种选择是:

(let [result-1 (compute-1 x)
      result-2 (compute-2 x)
      result-3 (compute-3 x)]
  (cond 
    (case-1? result-1) result-1
    (case-2? result-2) result-2
    (case-3? result-3) result-3))
现在我不再重复计算,而是如果现在
(case-1?result-1)
的计算结果为true,
result-2
result-3
是无理由计算的。
行为上我想要这样的东西:

(let [result-1 (compute-1 x)]
  (if (case-1? result-1)
    result-1
    (let [result-2 (compute-2 x)]
      (if (case-2? result-2)
        result-2
        (let [result-3 (compute-3 x)]
          (if (case-3? result-3)
            result-3))))))
(ns foo.core
  (:require
   [better-cond.core :as b]))

(b/cond
  :let [result-1 (compute-1 x)]
  (case-1? result-1) result-1

  :let [result-2 (compute-2 x)]
  (case-2? result-2) result-2

  :let [result-3 (compute-3 x)]
  (case-3? result-3) result-3)
然而,这段代码显然很快变得难以管理。这个问题有更好的解决方案吗?

有一个名为的库,它可以用宏精确地解决这个问题

它是这样使用的:

(let [result-1 (compute-1 x)]
  (if (case-1? result-1)
    result-1
    (let [result-2 (compute-2 x)]
      (if (case-2? result-2)
        result-2
        (let [result-3 (compute-3 x)]
          (if (case-3? result-3)
            result-3))))))
(ns foo.core
  (:require
   [better-cond.core :as b]))

(b/cond
  :let [result-1 (compute-1 x)]
  (case-1? result-1) result-1

  :let [result-2 (compute-2 x)]
  (case-2? result-2) result-2

  :let [result-3 (compute-3 x)]
  (case-3? result-3) result-3)

该片段将宏扩展为类似于上一个示例的代码

如果不需要宏或外部dep,可以使用
delay
来避免计算。