在《2024 Clojure 发展状况调查》中分享您的想法!点此参与调查!

欢迎!请查看关于页面以了解更多关于这个平台的信息。

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

创建限定关键词非常有用,特别是在使用spec时。使用命名空间别名可以帮助处理大量限定关键词。然而,目前创建一个别命名空间需要该命名空间实际上存在。

此问题卡是一个占位符,用于对轻量级关键词别名进行更多操作。更多详情待定。

封闭原因:Clojure 1.11.0-alpha2 加强了对 `require` 中的 `:as-alias` 的支持。这与 `:as` 相似以创建一个别名,但不会造成加载。有关详细信息,请参阅 CLJ-2123。

9 个答案

0

评论者:bendlas

希望能够在 1.9-beta 及时开始关于这次讨论。

在我先前的 CLJ-2030 问题中,我的想法是创建一个构造来允许在 .cljc 文件中自动别名,我希望将其作为一项需求提交。澄清这个 construct 的最佳位置是 ns 子句。
所以,如果我们想为这个用例生成长别名,我建议我们在 ns 子句中增加一个用于关键词别名的声明。为了这个评论,我们可以给它一个工 作标题:(:kwns-alias ...)。

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

一个开放问题是,:kwns-alias 应该如何与别名交互。例如,是否始终应将 ::qualified/keyword 的命名空间展开为与 qualified/symbol 相同,或者是否应允许它们不同。我认为它们始终应该相同,因为这符合简单性的规则。这意味着,
- 别名需要检查 sym 是否已在 :kwns-alias 中,如果是,则需要抛出异常
- :kwns-alias 也需要处理 `qualified/keywords 可能不再需要包含 knws 在其名称中

那么,:kwns-alias 的一个好名字是什么呢?:let 怎么样?

0
by

由:alexmiller 评论

beta 已经功能完善,所以这不会在 1.9 中实现。

我认为向 ns 添加任何内容可能都会被排除在外,但在我了解 Rich 的想法之前,我无法提出更多的建议。

0
by

评论者:bendlas

真遗憾。但也许 1.10 将会有更短的发布时间…

无论如何,我对 Rich 提出在 ns 子句之外做这件事的想法非常感兴趣,并且让它很好地与 clojurescript(甚至 clojure)兼容。
你有什么理由,为什么将 ns 增长对这个来说是一个坏主意?

0
by

由:alexmiller 评论

ns 做的事情太多了,我们不想让它做更多的事情。

0
by

评论者:bendlas

由于 ns 是 Clojure 中设置命名空间的基本方式,我认为对这个问题的修复(ns 做太多)将意味着对现有技术的相当大的改动。既然我们不打算破坏 ns,我想我会考虑某种 ns2 或者在 ns 子句之外进行命名空间设置的方法。我对任何一种方法都很好奇。

既然我知道 Rich 不会有关于他的 hammock time 的麻烦,我现在会放过这个问题。我确保在下一次 alpha 版发布时再回来。我也希望在此期间有一些富有成效的讨论。

0
by

由:tslocke 评论

有什么理由让这样一个机制仅限于关键字?在我的代码中,对于符号也很有必要拥有这样的功能。

还有相关的:为 pr-str(及类似功能)提供一个可以配置的选项来使用命名空间简写版本。即使是对命名空间映射,调试输出也可能会非常混乱。

0

由:alexmiller 评论

没有特别的原因——通常对于这类问题,我们会让任何标识符(关键字或符号)都可以使用同样的机制。

0
参考: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)))
...