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不会自动加载或要求读取器函数命名空间。在读取映射到该读取器函数的标记字面量的点之前,您的程序仍然负责在读取器函数所在的命名空间中要求该命名空间。这通常对于源中的标记字面量来说很恼人,也许应该改变这一点,但现在就是这样。

由于包含定义的命名空间隐式地依赖于读取该命名空间的命名空间才能读取,因此正确做法是在该命名空间的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并不能解决所有这些情况(我认为它使人们停止思考这些事情)。

我 definitely希望核心团队就REPL友好的方式处理记录及其他Clojure/Java交互领域提出一些建议。我已看到一些建议说,使用生成的函数而不是直接引用记录类型可以帮助,但我认为记录协议扩展的组织方式仍存在一些问题,需要更好的指导?

https://github.com/aredington/clojure-repl-sufficient-p有一个有趣的仓库,突出了一些当前REPL实现的问题,如果有人想添加这个特殊情况,那么这些问题可以包括在内。我特别喜欢这个仓库在特定活动期望方面组织的方式。
如果它能实际解释具体的问题和可以做什么来缓解这些问题的话,这将是一个更有用的仓库。源文件和单个测试文件在意图上极其晦涩。

只有在comp/wrapper的源文件中,它才试图展示REPL友好的等价物。
关于我的情况,我找到了一种构建记录的方法,使得记录的协议实现能够在协议类因依赖顺序被重新加载而消失的情况下仍然存在 - 通过使用`:extend-via-metadata`。这并不很优雅 - 使用记录类型来分派打印方法将记录序列化为标记字面量,并使用元数据来实现协议,但这有效。

(不幸的是,这只在clj中有效,并且在cljs中遇到了难以理解的编译错误,因此我现在放弃了对具有完整序列化往返的自定义标记字面量的整个想法)

关于你提到的“不够理想”和“更理想”的REPL工作流程,我想了解更多的细节 - 你能链接一下吗?
对于这个非解答,我有些失望。一个更有建设性的看法是“确实,库中有缺陷,可以修复”。

如果修复了tools.namespace中的错误,我们就不会谈论它“破坏所有事物”了。

反复不愿为一个库打call,某种程度上是一种自我实现的预言 - 最终,没有太多的人会愿意根据恐惧、不确定性、怀疑(FUD)来调制tools namespace,这将持续错误。

希望有人会承担tools.namespace的工作。我对使用的分叉版本感到非常满意。我目前没有时间改进官方的t.n。
这有些过分戏剧化了,vemv -- 我并不是在阻止使用 tools.namespace,我是在阻止特定的刷新操作。我认为问题出在工作流程上,而不是库本身。
不管这看起来多么戏剧化,我仍然对不断针对某种特定方法(可能有一个听起来很酷的名字,但实际上不过是一种‘自动化’)进行宣传感到困惑。在我们的社区中并不常见,这在https://clojure.org/community/etiquette中有所体现。
请让我们将讨论集中在手头的问题上。
...