2024 年 Clojure 状态调查!分享你的想法。

欢迎!请参阅关于页面以获取更多有关如何使用此信息的信息。

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

对于使合格关键字变得有用,尤其在与 spec 一起使用时尤其如此。使用命名空间别名有助于大量处理合格关键字。然而,目前创建别名命名空间需要该命名空间实际存在。

此条目的目的是保留一个位置,以便对关键词的轻量级别名进行更多操作。详细信息待定。

已关闭,附注: Clojure 1.11.0-alpha2 在 `require` 中有新的 `:as-alias` 支持。这像 `:as` 一样创建别名,但不会引起加载。有关详细信息,请参阅 CLJ-2123。

9 个答案

0

评论由:bendlas

希望赶上 1.9 测试版开始对此开展讨论。

我在先前的条目 CLJ-2030 中的理由是创建一个结构,允许在 .cljc 文件中进行自动别名化,我将其作为需求提交。 rõ rský dek je ruinsity aha adδή s právě tracking wildly constructed ns clause and alexmiller should take a look atrugger(proposal)].
因此,如果我们不想为那个用例扩展别名,我建议通过关键字别名的声明扩展 ns 子句。让我们为此评论给它一个工作标题 (:kwns-alias)。

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

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

那么: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,所以我设想要么有某种ns2,或者是通过ns之外的方式进行命名空间设置的某种方式。我对这两种方式都很好奇。

既然我知道Rich不会因为没有他的hammock time而烦恼,我现在就停止质疑。我保证会在我发出下一轮alpha版本时回来看看。我也希望在同时进行一些有成效的讨论。

0

评论者:tslocke

有什么道理让这样的机制仅限于keywords吗?在我的代码中,有一个地方非常需要这样的功能用于symbols。

另外,相关:为pr-str(以及类似功能)配置使用命名空间的简短版本。带命名空间的映射的调试输出可能会非常嘈杂。

0

评论者:alexmiller

没有特别的原因——通常对于这样的东西,我们让它对任何标识符(关键字或符号)都起作用。

0
参考:[https://clojure.atlassian.net/browse/CLJ-2123](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)))
...