在swap中使用字符串调用Clojure函数?

Pau*_*Lam 2 macros clojure

宏,transform!如下定义似乎适用=> (transform! ["foo" 1 2 3]).目的是获取一个列表,第一个元素是表示命名空间中的函数的字符串.然后包装到一切swap!.

问题是,在哪里transform!不起作用.我得到了这个神秘的例外:=> (transform! coll)(def coll ["foo" 1 2 3])

#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Symbol>
Run Code Online (Sandbox Code Playgroud)

功能:

(defmacro transform! 
" Takes string input and update data with corresponding command function.
"  
  [[f & args]]  ;; note double brackets
 `(swap! *image* ~(ns-resolve *ns* (symbol f)) ~@args))
Run Code Online (Sandbox Code Playgroud)

我觉得很奇怪它适用于一个案例而不是另一个案例.

Jus*_*mer 5

宏在编译时工作并在代码上运行,而不是在运行时数据上运行.在这种情况下(transform! coll),宏传递一个未经评估的单一参数:符号coll.

你实际上并不需要一个宏; 常规功能就足够了:

(defn transform! [[f & args]]
  (apply swap! *image* (resolve (symbol f)) args)))
Run Code Online (Sandbox Code Playgroud)

在运行时解析变量可能被视为代码气味,因此请考虑您是否真的需要这样做.