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_发布

虽然我理解您的用例,但这将是一个大的语法添加,我认为这不太可能。我现在将其退回待办事项。
0
评论:dergutemoritz_

同意,这是一个相当侵入性的变更,可能不值得麻烦。就事论事,我认为这可以通过带标签的字面量来实现。如果有人正在寻找解决方案,你可以有一个这样的函数


(defn auto-resolved-symbol-reader [sym]
  (let [ns (if-let [alias (namespace sym)]
             (or (get (ns-aliases *ns*) (symbol alias))
                 (throw (ex-info (str "无效的符号命名空间别名 " sym)
                                 {:symbol sym})))
             *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
参考:[CLJ-2490](https://clojure.atlassian.net/browse/CLJ-2490)(由 alex+import 报告)
...