请在 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 与 alias 交互。即 ::qualified/keyword 的命名空间是否应该始终扩展与有资格的符号的同一命名空间,或者是否应允许它们有所不同。我将主张它们应该始终相同,因为这符合简洁的原则。这意味着
- 别名将需要检查 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,我想这将意味着某种形式的 ns2 或者在 ns 条款之外进行命名空间设置的方式。我对这两种方式都很好奇。

既然我知道 Rich 将不会因为他的 hammock 时间而受到困扰,我想我现在就不再进行此工作了。我会在下一轮 alpha 版发布时仔细检查。我也希望能在这期间有一些富有成效的讨论。

0

评论人:tslocke

这种机制为什么会被限制为只用于关键词?在我的代码中,我有地方需要这样一个特性来表示符号。

此外,相关内容:为 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)))
...