首页 > 解决方案 > 如何从传递的参数在宏中创建符号

问题描述

只是尝试宏限制或未知数,我无法在运行时使用更改的键对符号映射进行固定的线性度。
因此,当 k1 k2 作为 args 传递给 process-arity 时,它应该创建 j1 j2 符号来访问 syms-from-map 宏中的 k1 和 k2 值。
给出编译错误:
CompilerException java.lang.IllegalArgumentException:不知道如何从以下位置创建 ISeq:clojure.core$map
引用 unquoting 使得难以编写宏 :-(

(defmacro syms-from-map[m]
  `(let [~@(mapcat (fn[[k v]] [k v]) (var-get (resolve m)))] 
     (prn "got" ~'j1 ~'j2))
  )

(defmacro process-arity[args]
  `(let [] (fn ~args 
     (let [~'map1 (zipmap '[j1 j2] ~args)] 
       (syms-from-map ~'map1)
       ))))
(def test-m1 (process-arity [k1 k2]))
(apply test-m1 [1 2])

标签: clojure

解决方案


macroexpand-1是一个有价值的工具。用它。

(defmacro process-arity[args]
    `(let [] (fn ~args
                 (let [~'map1 (zipmap [~'j1 ~'j2] ~args)]
                     (syms-from-map ~'map1)))))

(syms-from-map ~'map1)不会按您期望的方式工作。我建议您将其转换为函数。


推荐阅读