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

Macros 在clojure中,如何编写一个类似defn的宏,在第一次失败时函数将退出该宏?,macros,clojure,Macros,Clojure,在clojure中,我想编写一个defn my宏,用于创建带有主体的函数。当执行此函数时,它在第一个不返回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

在clojure中,我想编写一个
defn my
宏,用于创建带有
主体的函数。当执行此函数时,它在第一个不返回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

只需利用
的短路行为即可:

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

(defn bar []
  (and (f2) (f1)))
结果:

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

您可以使用
获得相反的行为,在第一个非零处终止,只需利用
的短路行为即可:

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

(defn bar []
  (and (f2) (f1)))
结果:

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

你可以得到相反的行为,第一个非零终止,使用

我想你是在要求这样的东西:

(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
(defmacro defn-my [ & body ] `(and-zero ~@body))
宏假定每个表达式的计算结果都是一个数字。例如,如果表达式的计算结果为
nil
,它将抛出异常

然后您可以这样编写您的
defn my

(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
(defmacro defn-my [ & body ] `(and-zero ~@body))

我想你是在要求这样的东西:

(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
(defmacro defn-my [ & body ] `(and-zero ~@body))
宏假定每个表达式的计算结果都是一个数字。例如,如果表达式的计算结果为
nil
,它将抛出异常

然后您可以这样编写您的
defn my

(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
(defmacro defn-my [ & body ] `(and-zero ~@body))

您的defn my示例中的表达式从不返回null;它们是变量,不是元组。这真的是你的意思吗?你的defn我的例子中的表达式永远不会返回null;它们是变量,不是元组。你真的是这个意思吗?谢谢!你说得对。你能把这个问题修改得更清楚些吗?如果我想对
~@body
应用谓词,你能告诉我怎么做吗?例如,
#(=0%)
在返回值不为零时停止。ThxI喜欢
(和@body)
。但在我的例子中,函数应该在第一个不返回0的语句中退出。请帮忙,谢谢!你说得对。你能把这个问题修改得更清楚些吗?如果我想对
~@body
应用谓词,你能告诉我怎么做吗?例如,
#(=0%)
在返回值不为零时停止。ThxI喜欢
(和@body)
。但在我的例子中,函数应该在第一个不返回0的语句中退出。请帮助。请更新您的答案。我稍微修改了一下这个问题。ThxAlso,我在寻找一种解决方案,不必修改
bar
foo
上的代码。也许你应该花时间学习如何用clojure来思考,而不是简单地试图把它弯曲到你认为应该如何解决问题上。与此相关的是,您发布的几乎所有内容都很像XY问题:提出一个新问题,这一次,不要问如何实现您的解决方案,只需说明您遇到的实际问题以及您正在使用的实际代码。XY问题浪费了每个人的时间。我有一个类似(但不完全相同)的需求,所以我在SQA网站上发布了一个问题:请更新你的答案。我稍微修改了一下这个问题。ThxAlso,我在寻找一种解决方案,不必修改
bar
foo
上的代码。也许你应该花时间学习如何用clojure来思考,而不是简单地试图把它弯曲到你认为应该如何解决问题上。与此相关的是,您发布的几乎所有内容都很像XY问题:提出一个新问题,这一次,不要问如何实现您的解决方案,只需说明您遇到的实际问题以及您正在使用的实际代码。XY问题浪费了每个人的时间。我有一个类似(但不完全相同)的需求,因此我在SQA网站上发布了一个问题: