Если я правильно понимаю ваш код, у вас есть набор битов, скажем [0 1 0]
. Каждый бит указывает, должен ли соответствующий аргумент быть отменен или нет Затем вы хотите вычислить конъюнкцию этих возможно отрицательных аргументов. Так что, если ваши аргументы были a
, b
и c
, с этими битами вы бы хотели вычислить (and (not a) b (not c))
, верно?
Как уже упоминали другие в комментариях, вам не нужны макросы для этого.
Вот функция get-conj
, которая в качестве аргументов принимает последовательность битов и возвращает новую функцию, которая выполняет то, что я объяснил выше:
(defn get-conj [bits]
(fn [& args]
{:pre [(= (count bits)
(count args))]}
(every? identity (map (fn [bit arg]
(if (zero? bit)
(not arg) arg))
bits args))))
Обратите внимание, что функция get-conj
теперь принимает только один аргумент, то есть bits
.
А приведенный вами пример кода работает (с небольшими изменениями):
(map get-conj [[1 0] [0 1] [0 0]])
(def conjunction (get-conj [1 0]))
(assert (conjunction true false))
(assert (not (conjunction true true)))
Макросы лучше всего использовать в ситуациях, когда функций недостаточно, таких как небольшие синтетические настройки (.eg when
, ->
) или создание мини-языков, таких как core.async или Англиканский вероятностный язык программирования.