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会破坏所有 sorts of things,我经常看到新手在使用reload/refresh工作流程时遇到麻烦...这就是为什么我倾向于跳入所有出现reload/refresh的对话,说“别这么做!”的原因。

就我的理解而言,这是一个处理由原先、不理想的REPL工作流程而产生的问题的糟糕解决方案。不要简单地敷衍,而应鼓励更好的REPL工作流程。

是的,我知道Clojure的一些部分确实可以生成Java类,这会让REPL中的生活变得艰难——但c.t.n.r/refresh并不能解决所有这些问题(我认为它会让人停止思考此类问题)。

我非常希望来自核心团队关于处理记录以及Clojure/Java互操作中的一些其他区域的REPL友好方式的一些指导。我见过一些建议,即使用生成的函数而不是直接引用记录类型可能会有所帮助,但我认为记录协议扩展的组织方式仍然存在问题,需要更好的指导?

https://github.com/aredington/clojure-repl-sufficient-p有一个有趣的仓库,它突显了当前REPL实现的某些缺点。如果有人愿意添加这个特定的案例,它可以包括这个缺点。我特别喜欢这个仓库在组织某些活动期望方面的方式。
by
如果它实际上解释了具体问题是什么以及可以做什么来减轻这些问题,这个仓库会更有用。src文件和那个测试文件在其意图上都是极其晦涩难懂的。

只有在comp/wrapper的src文件中,它才尝试展示REPL友好的等效。
by
@sean 对于我来说,我找到了一种构建record的方法,使得record的协议实现能够在通过依赖顺序重新加载协议时保持生存——通过使用`:extend-via-metadata`。这并不精致——使用record类型分发print-method以序列化为tagged-literal,并用元数据实现协议,但它有效。

(遗憾的是,它只适用于clj,并在cljs上遇到无法理解的编译错误,因此我现在放弃了带有完整序列化往返环的定制标记字面量全概念)

@sean 关于你描述的“不够理想”和“更好”的REPL工作流程,我对它们有进一步的了解和详细的细节——你能提供链接吗?
by
我对这个非答案感到有点失望。一个更有建设性的看法可能是“的确,库中存在一个缺陷,它可以被修复”。

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

反复贬低一个库是一种自我实现的预言——在某个时候,不太会有许多人想要基于恐惧利用(recommend utilizing) tools.namespace进行黑客攻击。这只会使bug持续下去。

我希望有人承担tools.namespace的重任。我绝对对我的分叉使用感到高兴。我现在没有时间改进当前官方的t.n。
这有点夸张了,vemv -- 我不是在阻止 tools.namespace 工具,只是在阻止更新。我认为问题是出在工作流程上,而不是在库本身。
无论是否夸张,我对反复对一种特定方法(可能有一个花哨的名字,但实际上不过是一种‘自动化’)进行游说的做法感到困惑。在我们的社区中通常看不到这种情况,如在 https://clojure.org/community/etiquette 所反映的那样。
请让我们将讨论集中在我们面临的问题上。
...