macros - 如何编写宏自动解析符号

标签 macros clojure

我一直幻想有一种方法可以自动解析符号。例如,如果我位于“user”命名空间中,并且在“clojure.string”命名空间中没有“使用”符号,则:

(clojure.string/split "a-b-c" #"-")

我想这样写:

(call split "a-b-c" #"-")

我简单地实现了一个“call”宏,如下所示:

(defmacro call [sym & args]
  `(let [fn# (first (distinct (remove nil? (map #(ns-resolve % '~sym) (all-ns)))))]
     (if-not ((meta fn#) :macro) 
       (fn# ~@args)
       (eval (list fn# ~@(map #(list 'quote %) args))))))

以下测试总是没问题的:

(call list 'a 'b)
(call apropos "list")
(call doc list)
(call doc clojure.string/split)

当我传递一个宏作为“doc”的参数时,就会出现问题:

(call doc clojure.repl/doc)

那么,有一个异常(exception):

CompilerException java.lang.RuntimeException:无法获取宏的值:#'clojure.repl/doc,编译:(NO_SOURCE_PATH:112)

所以,这就是为什么?谢谢

最佳答案

您可以在编译时在宏中解析符号,如下所示:

(defmacro call [sym & args]
  (let [f (first (distinct (remove nil? (map #(ns-resolve % sym) (all-ns)))))]
      `(~f ~@args)))

关于macros - 如何编写宏自动解析符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14048811/

相关文章:

Vim 宏 : Incrementing numbers on non-consecutive lines

clojure - 带联合的查询组合如何与通过 Om Next 中的 props 传递的父子树配合使用

dom - Clojurescript DOM 接口(interface)

clojure - Clojure 中的 a..b 列表

syntax - 需要从 Clojure 的 ns 函数中解释奇怪的行为

c++ - 在编译时获取源文件的基本名称

c++ - 如何使用模板而不是宏来创建具有动态数量函数的类

scala - 是否可以使用宏实现类似于 Scala 的 @BeanProperty 的东西?

c - 为什么宏值为0而不是1?

clojure - 如何有效地并行应用中等重量的函数