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

欢迎!请查看关于页面,了解这个网站的更多工作方式。

0
tools.namespace

我在代码库中找到一个有趣的问题,一些带标签的字面量似乎违反了最小意外原则

我们创建了一些纯数据流程描述,包括来自在 data_readers.cljc 中声明的自定义带标签的字面量读者的一些 defrecord 对象,让这些 defrecord 对象参与一个协议。这些都是一直很正常,直到我发现这个问题

有人将这些带标签的字面量之一放到了 def(起初这似乎是个合理的举动)

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

这是可以接受的... 直到调用 c.t.n.r/refresh,之后整个系统崩溃了

结果是,defrecord 对象 foo 有一个过期的类(可能是由于在 中声明的带标签的字面量解析程序引起的命名空间依赖关系没有被 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`之后事物失败的理解是有问题的(但在prod环境中从未发生过)

回到原点
–1

我对这个问题的最初反应是,“嗯,c.t.n.r/refresh会打破所有 sorts of 东西,我经常看到初学者在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实现的一些不足。如果有人有动力添加这一特定案例,可以包括在内。我特别喜欢这个仓库在组织某些活动方面的预期方式。
如果这个仓库真能解释具体的问题是什么,以及可以采取哪些措施来缓解这些问题,那将更加有用。源文件和单个测试文件的目的非常不明朗。

只有在`comp/wrapper`源文件中,它才试图展示REPL友好版的等效。
关于我的情况,我发现了一种构造记录的方法,使得记录的协议实现能够在协议类由于依赖顺序重新加载而重构后仍然存在——通过使用`:extend-via-metadata`。这并不优雅——使用记录类型转发打印方法以将记录序列化为标签字面量,并使用元数据实现协议,但它有效。

(遗憾的是,它只在clj上有效,并在cljs上遇到了难以理解的编译错误,因此我暂时放弃了带有完整序列化来回程的自定义标签字面量的整个想法)

@sean 想要进一步了解你所描述的“不够理想”和“较好”的REPL工作流程的详细信息——你能提供链接吗?
对这个无回答我很失望。更有建设性的态度可能是“的确,lib中存在缺陷,并且可以被修复”。

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

反复不鼓励一个库就像一种自我实现的预言——在某个时候,将不会有很多人因为恐惧、不确定和怀疑(FUD)而想对工具命名空间进行开发。这会继续产生bug。

我希望有人能承担工具命名空间的维护工作。我对我现在使用的分支非常满意。我目前没有时间改进官方的t.n。
这有点夸张了,vemv -- 我不是在劝阻工具命名空间,而是在劝阻具体的刷新操作。我认为缺陷在于工作流程,而不是库。
不管是不是夸张,我对针对某种特定方法(可能有一个 fancy 的名字,但它不过是一种‘自动化’)进行的反复抗议感到困惑。在我们社区中通常不会看到这种情况,如 https://clojure.org/community/etiquette 所反映的那样。
让我们请将讨论集中在眼前的问题上。
...