请分享您的想法,参加2024 Clojure状态调查!

欢迎!请访问关于页面以了解更多关于此处的信息。

+40
命名空间和变量
已关闭

制作限定关键词非常有用,尤其是在使用spec的情况下。使用命名空间别名在很大程度上有助于处理大量的限定关键词。然而,目前创建别名命名空间需要该命名空间实际存在。

此问题单是一个占位符,用于对关键词的轻量级别名进行更深入的处理。具体细节待定。

关闭备注:Clojure 1.11.0-alpha2对“require”中的`:as-alias`提供了新的支持。这与`:as`创建别名的方式类似,但不引起加载。有关详情,请参阅CLJ-2123。

9 答案

0

评论者:bendlas

希望在该1.9 beta发布前开始这场对话。

在我前辈问题单CLJ-2030中的论点是创建一个构造来允许在.cljc文件中自动别例化,我希望将其作为一项要求提出。在cljs中最明显的声明自动别例化的地方是ns子句。
所以,如果我们不希望为该用例创建别名,我建议在ns子句中增加对关键词别名的声明。让我们给这个评论一个暂定的名称:(:kwns-alias ..)。

:kwns-alias将用于为::qualified/keywords建立命名空间别名。

一个悬而未决的问题是,:kwns-alias应该如何与别名交互。也就是说,::qualified/keyword的命名空间是否应该始终扩展为限定/symbol的同一命名空间,或者是否应该允许它们有所不同。我会争辩说它们应该始终相同,因为这符合简化的规则。这意味着,
- 别名需要检查sym是否已在:kwns-alias中,如果是则抛出异常
- :kwns-alias 还需要处理 `qualified/keywords`,可能不再需要在它的名称中有 knws 了

那么:kwns-alias 起一个好名字是什么呢?:let 也许是吗?

0

评论由:alexmiller 提出

beta 版本功能已完善,所以这不在 1.9 的计划中。

我认为向 ns 添加任何内容可能都不太可能,但在我了解更多关于 Rich 想法之前,我真的无法提出更多的建议。

0

评论者:bendlas

真遗憾。但也许 1.10 会缩短发布周期……

无论如何,我非常感兴趣地等待 Rich 提出的将此操作放到 ns 子句之外,同时还能很好地与 clojurescript(甚至 Clojure)兼容的想法。
你有什么依据,为什么认为在 ns 中增长不是一个好主意?

0

评论由:alexmiller 提出

ns 已经做了太多的工作,我们没有任何想去增加它的需求。

0

评论者:bendlas

鉴于 ns 是 Clojure 中如何设置命名空间的基础,我觉得对 ns 做太多工作的修复(即 ns 做的太多)将意味着对现有技术状态进行相当大的改变。由于我们将不中断 ns,我想象可能是某种 ns2 或是在 ns 子句之外进行命名空间设置的方式。我对此都很好奇。

既然我知道 Rich 不会被他的吊床时间打扰,我现在就停止这个话题。我将在下一轮 alpha 测试发布时回过头来检查。同时,我也希望在这段时间内有一些富有成效的讨论。

0

评论由:tslocke 提出

有这样的机制仅限于关键字是否有任何原因?在我的代码中,符号有这样的功能将非常有用。

另外,相关:让 pr-str(和类似的)能够配置为使用命名空间短版本。即使在带命名空间的映射中,调试输出也很花哨。

0

评论由:alexmiller 提出

没有特别的原因——通常我们会让任何标识符(关键字或符号)对于类似的东西都能正常工作。

0
参考:[ NSURL](https://clojure.atlassian.net/browse/CLJ-2123)(由 alexmiller 报告)
0

我们通过一对宏解决这个问题。它们有些丑,但有效——我们已经连续四个月没有遇到任何问题。我们的团队对 Clojure 仍然比较新,所以如果我们知道这样做的不好原因,我们将很高兴...

(ns com.flexport.util.synthetic-ns
  "Synthetic namespaces are designed to be used as prefixes for namespace-qualified keywords.
  They allow us to decouple the names of data from the names of code.")

(defmacro def-synthetic-ns
  "Define a synthetic ns (the-ns), binding it to the-alias.

  Example:

  (def-synthetic-ns loan 'flexport.capital.loan)

  ::loan/name
  ;; flexport.capital.loan/name

  ::loan/id
  ;; flexport.capital.loan/id
  "

  [the-alias the-ns]
  `(do
     (def ~the-alias ~the-ns)
     (create-ns ~the-ns)
     (alias (quote ~the-alias) ~the-ns)))

(defmacro use-synthetic-ns
  "Use a synthetic ns alias defined elsewhere.

  Example:

  (ns ns-a
    (:require [com.flexport.util.synthetic-ns :refer [def-synthetic-ns]]))

  (def-synthetic-ns loan 'flexport.capital.loan)

  ::loan/a
  ;; flexport.capital.loan/a

  (ns ns-b
    (:require [com.flexport.capital.util.synthetic-ns :refer [use-synthetic-ns]])
    (:require [ns-a :as ns-a]))

  (use-synthetic-ns ns-a/loan loan)

  ::loan/b
  ;; flexport.capital.loan/b
  "

  [the-alias local-name]
  `(alias (quote ~local-name) (var-get #'~the-alias)))
...