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

欢迎!请参阅 关于 页面了解本网站的更多信息。

0 投票
tools.namespace

我在我们的代码库中发现了关于一些标记字面量似乎违反最小惊讶原则的有趣问题。

我们创建了一些包括一些来自在 data_readers.cljc 中声明的自定义标记字面量读取器的 defrecord 对象的纯数据处理过程描述,并让这些 defrecord 对象参与一个协议。这一切都工作得很好,直到我遇到了这个问题。

有人将这些标记字面量之一放入了一个 def(最初似乎是个合理的做法)

(def foo #ctx/event-path [:blah])

这没问题...直到调用 c.t.n.r/refresh,此时一切开始崩溃

结果发现 defrecord 对象 foo 具有一个过时的类(很可能是由于标记字面量解析器在 data_readers.cljc 中引起的命名空间依赖不被 tools.namespace 识别,因此命名空间以错误的顺序重新编译),所以它不再参与协议。

tools.namespace 应该能够识别 data_readers.cljc 诱导的依赖吗?或者那可能太过于越界?

2 答案

0 投票

在这里,我认为一个重要的考虑因素是,拥有一个 data_readers.cljc 文件并不能自动加载或请求读者函数的命名空间。你的程序仍然需要在读取与该读者函数映射的标记文字之前负责请求包含读者函数的命名空间。这通常对于源代码中的标记文字来说很麻烦,或许应该做出一些改变,但现在事情就是这样运行的。

鉴于这一点,包含 def 的命名空间隐式地依赖于读者命名空间以便可以被读取,正确的方法是在那个命名空间的 ns 定义中明确指出这种依赖。如果你这样做,就不存在“由 data_readers.cljc 引起的依赖”,只有已经在命名空间定义中明确列出的依赖,你将不会遇到这个问题。

因此,我认为这不是 tools.namespace 所需要的特性(考虑到 Clojure 的当前实现)。

嗯 - 这是一个杀手锏 @alexmiller - 这意味着我对 `c.t.n.r/refresh` 之后事物失败(但在生产环境中从未发生)的理解是有缺陷的

回到桌面上重新开始
–1 投票

我对这个问题的初始反应是,“嗯,c.t.n.r/refresh 能够破坏各种东西,我看到很多初学者在 reload/refresh 的工作流中遇到了麻烦……”这就是我为什么倾向于跳入每个有 reload/refresh 的对话,说“别这么做!”的原因。

在我看来,这是一个糟糕的解决方案,首先要解决的问题是由于不理想的 REPL 工作流程而引起的。不要只是暂时封住伤口,鼓励更好的 REPL 工作流程。

是的,我知道 Clojure 的一些部分可以生成 Java 类,这会使 REPL 的使用变得困难 - 但 c.t.n.r/refresh 也不能解决所有这些问题(而且我认为它使人们停止思考这些问题)。

我确实希望核心团队就如何以好处户的 REPL 方式处理记录和其他 Clojure/Java 互操作领域的问题给出一些指导。我已经看到了一些建议,使用生成的函数而不是直接引用记录类型可以帮助,但我认为关于如何组织记录的协议扩展仍有一些问题需要更好的指导。

作者
https://github.com/aredington/clojure-repl-sufficient-p有一个有趣的存储库,它突出了当前REPL实现的一些缺点,如果有人有动力添加,可以考虑这个特定的案例。我特别喜欢这个存储库在组织某些活动的预期方面的方式。
作者
如果它实际上能解释具体的问题以及如何减轻这些问题,那将是一个非常有用的存储库。src文件和单一测试文件在意图上都非常模糊。

只有在该/wrapper src文件内,它才尝试展示REPL友好的等价物。
作者
@sean 对于我的情况,我找到一种构建记录的方法,这样记录的协议实现可以在协议类因依赖顺序而重新加载时存续 - 通过使用`:extend-via-metadata`。它并不十分优雅 - 使用记录类型将print-method派发为序列化记录为带标签的字面量,使用元数据实现协议,但它有效。

(不幸的是它只在clj上有效,而在cljs上遇到了难以理解的编译错误,所以我暂时放弃了带有完整序列化往返的带定制的带标签字面量的整个想法)

@sean 我对您所描述的“不理想的”和“更好的”REPL工作流程有进一步了解的兴趣 - 您能链接吗?
作者
我对这个‘非答案’有点失望。一个更有建设性的看法可能是‘的确,lib中存在缺陷,是可以修复的’。

如果tools.namespace中的bug得到修复,我们就不会在谈论它‘破坏所有事情’了。

反复对一个lib持批评态度似乎是一种自证预言——在某些时候,由于恐惧和不确定性的影响,将不会有很多人愿意为tools.namespace进行开发。这加剧了bug的存在。

我希望有人能承担起tools.namespace的工作。我当然对我的分叉版本很满意。目前我没有时间去提升官方的t.n。
这有点戏剧性,vemv——我并不是在批评tools.namespace,而是在批评refresh特别。我认为缺陷在于工作流程,而不是库本身。
不管是否戏剧性,我仍然对持续反对某一种特定的方法(可能有一个花哨的名字,但不过只是‘自动化’)而感到困惑。在我们的社区中通常不会看到这一点,正如在https://clojure.org/community/etiquette 中所体现的那样。
请让我们将讨论集中在当前的问题上。
...