Macros Clojure:可以在一个condp子句中创建一个宏来创建这两个元素吗?

Macros Clojure:可以在一个condp子句中创建一个宏来创建这两个元素吗?,macros,clojure,Macros,Clojure,condp条款如下所示: "plet" (make-adj 2 "ète") "iet" (make-adj 2 "ète") "nin" (make-adj 1 "gne") 我想将该条件添加到make adj函数调用中,而不在一行中重复该条件两次。我想要一个宏来打开这个: (test-make-adj "plet" 2 "ète") (test-make-adj "iet" 2 "ète") (test-make-adj "nin" 1 "gne")

condp条款如下所示:

      "plet" (make-adj 2 "ète")
      "iet"  (make-adj 2 "ète")
      "nin"  (make-adj 1 "gne")
我想将该条件添加到
make adj
函数调用中,而不在一行中重复该条件两次。我想要一个宏来打开这个:

(test-make-adj "plet" 2 "ète")
(test-make-adj "iet" 2 "ète")
(test-make-adj "nin" 1 "gne")
为此:

      "plet" (make-adj 2 "ète" "plet")
      "iet"  (make-adj 2 "ète" "iet")
      "nin"  (make-adj 1 "gne" "nin")

首先是一个函数,用于生成一个condp子句

(defn test-make-adj [x num y]
  `(~x (make-adj ~num ~y ~x)))
然后使用宏将子句组装成condp表达式

(defmacro adj-condp [pred expr & clauses]
  `(condp ~pred ~expr
     ~@(mapcat test-make-adj clauses)))

ps:我不在我的repl,所以我无法测试,请编辑:)

condp
具有内置功能以支持此类功能:

(condp #(if (= %1 %2) %1) condition
  "plet" :>> #(make-adj 2 "ète" %)
  "iet"  :>> #(make-adj 2 "ète" %)
  "nin"  :>> #(make-adj 1 "gne" %))
#(if(=%1%2)%1)
是一个二进制函数,它检查其参数是否相等,如果相等,则返回第一个参数,否则返回
nil

:>
使得对
条件
上的谓词求值的结果,例如
“plet”
传递给
#(make adj…
函数。对于上述谓词,这意味着如果
(=“plet”条件)
,则
“plet”
将传递到
#(make adj…
)。有关更多信息,请参见
(doc condp)

如果这仍然感觉键入太多,可以创建一个助手函数:

(defn make-adj* [n s]
  (fn [c] (make-adj n s c))
然后像这样使用它:

(condp #(if (= %1 %2) %1) condition
  "plet" :>> (make-adj* 2 "ète")
  ...)

我对代码进行了一些修改。除了删除两个小错误外,我还将
(apply concat(map…)
替换为
mapcat
,并根据风格调整了缩进。希望你能接受。