Как сгенерировать выражения для макроса? - PullRequest
0 голосов
/ 15 октября 2019

Поскольку нельзя применить макрос к списку, например,

;; does not work
(apply -> [expr1 expr2 expr3])

Как создать такое выражение:

(-> expr1
    expr2
    expr3)

Где

  • expr1 генерируется (generate-expr1 f g h)
  • expr2 генерируется (generate-expr2 f g h)
  • expr3 генерируется (generate-expr3 f g h)

Context

Я пытаюсь создать встроенный DSL, например,

["increment" "increment" "increment"]

, который затем преобразуется в код, например,

(fn [n] (-> n inc inc inc))

1 Ответ

1 голос
/ 15 октября 2019

Вы можете сгенерировать его с помощью макроса, например

(defmacro opfun [op-names]
  (let [m {"increment" 'inc}
        ops (map m op-names)]
    `(fn [n#] (-> n# ~@ops))))

, затем

(opfun ["increment" "increment" "increment"])

, если вам нужно предоставить список аргументов во время выполнения, вы можете интерпретировать свою структуру напрямую, например

(defn build-eval [op-names]
  (let [m {"increment" inc}
        ops (map m op-names)]
    (fn [n] (reduce (fn [acc f] (f acc)) n ops))))
...