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 引起的依赖”,只有命名空间定义中已经明确的依赖,您就不会遇到这个问题。

因此,我认为在当前的 Clojure 实现下,tools.namespace 不需要这样的功能。

嗯,这是一个致命的观点 @alexmiller - 这意味着我对为何在 `c.t.n.r/refresh` 之后事情失败的理解是错误的(但生产环境中却没有)

回到画板前
–1 投票

我对此的第一个反应是:“嗯,c.t.n.r/refresh 可以破坏所有 sorts of things,我经常看到初学者在 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友好的等效功能。
@sean 对于我的情况,我找到了一种构建记录的方法,使得记录的协议实现能够在协议类根据依赖顺序重新加载时生存下来 - 通过使用 `:extend-via-metadata`。这并不优雅——使用记录类型来分派打印方法以将记录序列化为标记-literal,并使用元数据来实现协议,但也奏效了。

(不幸的是,它只能在clj上工作,并在cljs上遇到难以理解的编译错误,因此我目前放弃了带有完全序列化往返的自定义标记-literal的整个想法)

@sean 我对您描述的“不尽人意”和“更好”的REPL工作流程的兴趣更加浓厚 - 您能提供链接吗?
对于这个非答案我有些失望。一个更有建设性的观点是“是的,库中确实存在缺陷,可以修复”。

如果工具命名空间中的错误被修复,我们就不必谈论它“破坏所有事物”了。

反复不鼓励一个库实际上是一种自我实现的预言——在某个时刻,不会太多的人愿意在工具命名空间上 hacking,这受 FUD 指导,这持续了错误。

我希望有人能接管工具命名空间。我对当前使用的分支版本非常满意。我没有时间改进官方的 t.n。
这未必太夸张了,vemv —— 我并没有不鼓励工具命名空间,而是在劝阻具体的行为。我认为缺陷在于工作流程,而不是库本身。
夸张也好,不夸张也罢,我对反复对一种特定方法(可能有一个响亮的名字,但不过是‘自动化’)发起运动的困惑仍然存在。在我们社区中通常不会看到这种行为,就像在 https://clojure.org/community/etiquette 反映的那样。
让我们请将讨论集中在手头的问题上。
...