Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Clojure宏中进行名称空间解析_Clojure - Fatal编程技术网

如何在Clojure宏中进行名称空间解析

如何在Clojure宏中进行名称空间解析,clojure,Clojure,我有这样一个宏: 例如: (defmacro xxz [& fns] `(:body ~@(map (fn [[e1 e2]] `(~e2 "http://www.google.com")) fns))) 如果我传递类似于(xxz[client/get client/get]),则生成的宏扩展显示符号不合格: (:主体(客户端/获取)http://www.google.com) 当这样的内容到达没有导入client的命名空间时,这会导致问题 有人知道该怎么做吗?这听起来像是对语法引用的

我有这样一个宏:

例如:

(defmacro xxz [& fns] `(:body ~@(map (fn [[e1 e2]] `(~e2 "http://www.google.com")) fns)))
如果我传递类似于
(xxz[client/get client/get])
,则生成的宏扩展显示符号不合格:

(:主体(客户端/获取)http://www.google.com)

当这样的内容到达没有导入
client
的命名空间时,这会导致问题


有人知道该怎么做吗?

这听起来像是对语法引用的设计疏忽(在我看来),尽管还不清楚一般的“修复”会是什么样子

下面是一个更简单的示例:

yummly.mobile-api.main> (in-ns 'foo)
#namespace[foo]
foo> (clojure.core/refer-clojure)
foo> (require '[org.httpkit.client :as client])
nil

foo> (defmacro xxz [& fns]
       `(~@fns))
#'foo/xxz
foo> (macroexpand-1 '(xxz client/get))
(client/get)
从新名称空间:

foo> (in-ns 'bar)
#namespace[bar]
bar> (macroexpand-1 '(foo/xxz client/get))
(client/get)
bar> (foo/xxz client/get)
CompilerException java.lang.RuntimeException: No such namespace: client, compiling:(*cider-repl api*:87:6) 
语法quote表单(aka`)在编译表达式时查看表达式中的每个符号,如果未找到/则假定它用于本地名称空间并附加当前名称空间。它只能对定义宏时实际宏中存在的符号执行此操作,而不能对作为参数传递给宏的符号执行此操作(我希望它能够这样做)

如果在宏中使用完全限定名称空间的符号,则不必担心人们使用宏的名称空间是否将这些符号映射到了任何对象,因为它们以其名称拼写出符号的完整路径。如果不想在宏中使用的符号中实际键入完整名称空间,则可以使用
:在
ns
表达式中的require语句中引用[get]
,这将节省您键入名称的时间,并使它们在宏定义求值时正确展开名称空间

由于syntax quote产生了不卫生的符号,您需要同时使用:require或:对于将这些名称空间传递给函数的每个客户机,请参考名称空间顶部的
ns
部分中的函数


另一个选项是找到某种方法,确保在编译语法引号时宏可以使用符号。在某些情况下,这可能很棘手。

我不确定我是否理解。如果您在ns“sample”中并调用(xxz…),则ns“sample”必须具有
(:require[some-ns.client:as client)
或类似项。
,因为您在宏中使用的是命名空间限定符号(您应该这样做)这样,您就不必担心人们使用宏的Namespace是否将这些符号映射到了任何东西,因为它们以其名称拼写出符号的完整路径。
->这正是问题所在。由于某些原因,在这种情况下,我无法获得符号的完整路径。我在macroexpand中获得了
客户端/get
符号,而不是clj http.core/get这是正确的完全限定符号。因此我的问题是:为什么它不被限定?这听起来像是语法引用中的一个错误。它不应该以这种方式工作。我认为这应该添加到Clojure Jira问题跟踪中。我将尝试创建一个复制错误的示例。