clojure宏if-empty?

时间:2011-06-06 13:21:54

标签: macros clojure

我写了一个if-pred?宏如下

(defmacro if-pred?
  ([pred lst then] `(if (~pred ~lst) ~then nil))
  ([pred lst then else] `(if (~pred ~lst) ~then ~else)))

现在我想构建一个if-empty?那个宏。

(defmacro if-empty? [lst then & else] 
  (if-pred? empty? lst then else))

我想使用if-empty?像:

(if-empty? '()
       (println "empty")
       (println "not-empty"))

但显然是空的?不管用。当我运行上面的代码 not-empty 得到的打印无关紧要是我传递给if-empty的列表?真的是空的。打印 not-empty 后抛出java.lang.NullPointerException。

4 个答案:

答案 0 :(得分:4)

您没有引用(defmacro if-empty?...)的扩展,并且您正在强制将可选的else参数放入列表中。

(defmacro if-empty? 
  ([lst then else] 
    `(if-pred? empty? ~lst ~then ~else))
  ([lst then] 
    `(if-pred? empty? ~lst ~then)))

答案 1 :(得分:0)

宏需要返回代码。试试这个:

(defmacro if-empty? [lst then & else] 
    `(if-pred? empty? ~lst ~then ~@else))

答案 2 :(得分:0)

这是你的空吗?宏。你忘记了反击身体。应该是:

(defmacro if-empty? [lst then & else]
  `(if-pred? empty? ~lst ~then ~else))

答案 3 :(得分:0)

由于宏if-empty?if-pred?的签名与else部分的变量arity不同,因此需要do块才能正常运行。

你的if-empty?宏存在一些问题,首先它没有被引用,这将导致

因此,如果你需要if-empty?来工作,那么如果给定的序列为空,它将评估单个表达式,如果序列不为空,它将评估单个表达式,以下宏应该可以工作:

(defmacro if-empty? [lst then & else] `(if-pred? empty? ~lst ~then (do ~@else)))

如果&在args发生意外事故之前应该工作:

(defmacro if-empty? [lst then else] `(if-pred? empty? ~lst ~then ~else))

作为旁注,因为这些宏不是谓词我不会使用?在他们的名字的最后。