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的命名空间隐式地依赖于读取器命名空间才能被读取,而在那个命名空间中将这种依赖明确化是正确的事情。如果您这样做,就没有“由data_readers.cljc引起的依赖”,只有已经在命名空间定义中明确指定的依赖,您就不会遇到这个问题。

因此,我认为这对于tools.namespace(鉴于Clojure的当前实现)来说不是一个需要的功能。

嗯,@alexmiller,这是一个关键点——这意味着我对在`c.t.n.r/refresh`之后(但从未在prod中)出现故障的原因的理解是错误的。

重新开始设计
–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有一个有趣的repo,它突出了当前REPL实现的一些不利之处,如果有人有动力添加特定案例,它都应该包括在内。我特别喜欢这个repo在某种活动预期方面的组织方式。
作者
如果它实际上能解释具体问题以及如何减轻这些问题,这将成为一个非常有用的仓库。src文件和测试文件在其意图上都极为晦涩。

只有在内部comp/wrapper src文件中,它才试图展示一个REPL友好的等效物。
作者
@sean 对于我来说,我发现了一种构建记录的方法,该方法使得记录协议实现能够在协议类根据依赖关系重新加载的情况下生存 - 通过使用 `:extend-via-metadata`。这并不十分优雅 - 使用记录类型来调度打印方法以将记录序列化为标记字面量,并使用元数据来实现协议,但仍然有效

(遗憾地只在clj上工作,并在cljs上遇到无法识别的编译错误,因此我目前已经放弃了带有完整序列化往返的定制标记字面量的整个想法)

@sean 感兴趣进一步了解你所描述的“不够理想”和“更好”的REPL工作流程 - 可以链接吗?
作者
对于这个非答案我感到有点失望。更建设性的观点可能是“是的,库中存在一个缺陷,它可以被修复”。

如果工具命名空间中的bug得到修复,我们就不会在谈论它“破坏所有事物”了。

不断地劝阻一个库有点像自我实现的预言——在某个时候,不会有多少人愿意在受恐惧影响下修改 tools.namespace。这进而 perpetuates the bugs。

我希望有人接手工具命名空间。我 Definitely 对我使用的 mug 很高兴。目前我没有时间改进官方的 t.n。
有点夸张了,vemv -- 我并不是在劝阻 tools.namespace,我是在具体地劝阻刷新。我认为问题在于工作流程,而不是库。
不管有多么夸张,我仍然对反复对一种特别的方法(可能有一个漂亮的名字,但根本不是“自动化”)进行反击而感到困惑。在我们的社区中通常看不到这种行为,正如在https://clojure.org/community/etiquette 中反映的那样。
请让我们把讨论集中在手头的问题上。
...