Clojure: Is it possible to create a macro to create two elements in one condp clause?

The condp suggestions are as follows:

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

I want to add a condition to the make-adj function call without repeating the condition twice on the same line. I would like the macro to turn this:

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

In it:

  "plet" (make-adj 2 "ète" "plet") "iet" (make-adj 2 "ète" "iet") "nin" (make-adj 1 "gne" "nin") 
+4
source share
2 answers

condp has built-in functions to support these kinds of things:

 (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) is a binary function that checks if its arguments are equal, returning the first argument, if any, or nil otherwise.

:>> makes it so that the result of evaluating the predicate on condition and, for example, "plet" is passed to the #(make-adj ...) function #(make-adj ...) . With the above predicate, this means that if (= "plet" condition) is true , then "plet" is passed to #(make-adj ...) . See (doc condp) for more information.

If this still looks like too much input, you can create a helper function:

 (defn make-adj* [ns] (fn [c] (make-adj nsc)) 

Then use it like this:

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

First you need to fulfill one of the condp conditions

 (defn test-make-adj [x num y] `(~x (make-adj ~num ~y ~x))) 

Then a macro to build sentences in a condp expression

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

ps: I am not on my replica, so I can not verify this, please edit :)

+2
source

Source: https://habr.com/ru/post/1302274/


All Articles