以下这些函数通常可以简化
(let [coll (get-coll)]
(if (seq coll)
(handle-true coll)
(handle-false)))
(when-let [x (seq ...)])
(if-let [x (seq ...)])
例如
(if-seq-let [coll (get-coll)]
(handle-true coll)
(handle-false))
(when-seq-let [c (get-coll)]
(handle-true1 coll)
(handle-true2 coll))
建议基于if-let和when-let。
(defmacro ^{:private true} assert-args
[& pairs]
`(do (when-not ~(first pairs)
(throw (IllegalArgumentException.
(str (first ~'&form) " requires " ~(second pairs) " in " ~'*ns* ":" (:line (meta ~'&form))))))
~(let [more (nnext pairs)]
(when more
(list* `assert-args more)))))
(defmacro if-seq-let
"bindings => binding-form test
If test is seq, evaluates then with binding-form bound to the value of
test, if not, yields else"
([bindings then]
`(if-let ~bindings ~then nil))
([bindings then else & oldform]
(assert-args
(vector? bindings) "a vector for its binding"
(nil? oldform) "1 or 2 forms after binding vector"
(= 2 (count bindings)) "exactly 2 forms in binding vector")
(let [form (bindings 0) tst (bindings 1)]
`(let [temp# ~tst]
(if (seq temp#)
(let [~form temp#]
~then)
~else)))))
(defmacro when-seq-let
"bindings => binding-form test
When test is seq, evaluates body with binding-form bound to the value of test"
[bindings & body]
(assert-args
(vector? bindings) "a vector for its binding"
(= 2 (count bindings)) "exactly 2 forms in binding vector")
(let [form (bindings 0) tst (bindings 1)]
`(let [temp# ~tst]
(when (seq temp#)
(let [~form temp#]
~@body)))))