在clojure中,如何编写一个类似defn的宏,其中函数将在第一次失败时退出?

时间:2012-02-25 23:45:34

标签: macros clojure

在clojure中,我想编写一个defn-my宏来创建一个带有body的函数。执行此函数时,它将在第一个不返回0的语句中退出。

例如:

(defn f1[] (println "f1") 5)
(defn f2[] (println "f2") 0)
(defn-my foo[] (f1) (f2))     
(defn-my bar[] (f2) (f1))
(foo); should execute f1 and exit
(bar); should execute f2 and then f1

2 个答案:

答案 0 :(得分:4)

我认为你要求这样的事情:

(defmacro and-zero
  ([] true)
  ([x] (zero? x))
  ([x & next] 
    `(let [and# (zero? ~x)]
       (if and# 
         (and-not-zero ~@next)
         and#))))

user=> (and-zero 0 0 0)
true
user=> (and-zero 0 1 0)
false

宏假设每个表达式的计算结果为一个数字。例如,如果表达式的计算结果为nil,则会抛出异常。

然后你可以这样写defn-my

(defmacro defn-my [ & body ] `(and-zero ~@body))

答案 1 :(得分:1)

只是利用and

的短路行为
(defn foo []
  (and (f1) (f2)))

(defn bar []
  (and (f2) (f1)))

结果:

user=> (foo)
f1
nil
user=> (bar)
f2
f1
nil

您可以使用or获得相反的行为,以第一个非零结尾。