2024 Clojure 状态调查! 中分享您的想法。

欢迎!请参阅 关于 页面以了解更多此功能的信息。

0 投票
Clojure
h1. 理由

当自动解析关键字字面量的命名空间组件引用未声明的别名时,读者将生成一个错误,如下所示


user> ::foo/bar
RuntimeException 无效标记:::foo/bar  clojure.lang.Util.runtimeException (Util.java:221)


然而,对于符号,没有这种语法。这是函数 {{clojure.spec.test.alpha/instrument}}出错的一个常见来源,该函数接受变量名的限定符号作为参数。目前,此类符号字面量的首选表示法是词法引号,它当然接受任何命名空间。现在,当有人意外地在一个没有声明当前命名空间的别名的符号参数中引用它时(例如,将一些代码从一个命名空间移植到另一个命名空间时),拥有与自动解析关键字相同的错误行为将会非常有用。以{{instrument}}为例,最终可能会调用潜在昂贵的真实函数而不是模拟函数,而这些模拟函数可能很容易被忽视。

h1. 建议的语法

这有点棘手。第一个想到的就是双重反引号,例如 {{``foo/bar}},但这已经有意义,并且可能在现有的宏中已经使用。我想{{%foo/bar}}可能也可以,当然,没有保证这个在实际的命名空间名称中也不在用。

h1. 状态

正如你所见到的,我还没有对可能的语法选项进行广泛的调查,也没有开始编写补丁。我只是想征求对这个问题的看法,看看它是否值得进一步追究。

4 条答案

0 投票
_评论人:alexmiller_

虽然我理解你的用例,但这将是一个大的语法添加,我认为这不太可能。我将把它放在 Backlog 中。
0 投票
_由:dergutemoritz_提出评论

我同意,这是一个相当侵入性的变更,可能不值得烦恼。无论如何,在此期间,我想知道是否可以通过带标签的字面量实现相同的效果。如果有任何人正在寻找解决方案,您可以使用以下这样的函数:


((defn auto-resolved-symbol-reader [sym])
  ((let [ns (if-let [alias (namespace sym)])”)
             (if (or (get (ns-aliases *ns*) (symbol alias))”)
                  (throw (ex-info (str "Invalid namespace alias on symbol " sym) )”)
                 (:symbol sym)}))
                  (ns-name ns))])
      (symbol (name (ns-name ns) ) (name sym) )))


在类路径的根目录下将其注册为例如 {{sym}} 标记,例如 {{data_readers.clj}}


{sym my.data-readers/auto-resolved-symbol-reader}


然后您可以使用它来达到类似于 {{::foo/bar}} 的效果,如下所示


'#sym foo/bar
0 投票
_由:dergutemoritz_提出评论

关于 {{instrument}} 示例中的 {{:replace}} 参数,还有一种已经存在的解决方案。只需使用带语法引号的自动解析命名空间映射即可,如下所示


:replace `::foo{bar ~some-fn}


但当然,您现在需要取消引用值。请注意,语法引号必须应用于整个表达式 - 如果它在键之前,因为语法引号已经将它命名空间化,所以映射的命名空间将不会应用于它。实际上,可以说 ::foo{'bar some-fn} 也可以命名空间符号键,但它并没有发生,也许它最终意外地与语法引号一起工作...
0 投票
参考:https://clojure.atlassian.net/browse/CLJ-2490 (由 alex+import 报告)
...