4

关于如何最好地投标命名空间有很多讨论。Stuart Sierra 在他的Lifecycle Composition和与clojure.tools.namespace的合作中启发了我们这一切。

大多数复杂性来自命名空间的可变性;那我们为什么不把命名空间放在 Clojures 自己的 MVCC 中呢?一定是有原因的,但我自己也想不通。

4

2 回答 2

2

一个实际的原因是命名空间用于构建 MVCC,因此它使编译器更难(尽管并非不可能)在构建命名空间时使用 MVCC。另一个原因在于程序员修改它们的方式,虽然 refs 的内容通常通过在程序运行时操作数据来修改,但 namsepace 中的 vars 的内容几乎总是在程序开发期间被修改,其中绝大多数时间程序员希望在整个系统范围内立即看到更改。

值得注意的是,在您需要协调更新多个函数的情况下,可以使用命名空间的替代方法来存储您的函数。如果您需要原子升级,将函数存储在 ref 中并使用 dosync 升级程序是合理的。通过这种方式,您可以为需要它们的函数提供 MVCC 语义,并在不需要协调升级的任何地方保持命名空间的就地更新语义。

于 2013-10-04T15:56:03.517 回答
1

代码加载本质上是一种完全任意的操作——加载命名空间会触发各种副作用,因此不适合放入事务中。

无论如何,我认为可以对当前的加载机制进行一些改进:例如,在对 , 等的调用中nsrequire可以列出所有当前的 var,以及由于调用而添加的所有 var;如果调用ns/require失败,后一个列表中的所有变量都将被删除。

请注意,这种方法需要序列化对ns/的调用require,而不是当前的并发机制。无论如何,我认为并发加载没有充分的理由。

于 2013-10-07T07:36:27.763 回答