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

欢迎!请参阅关于页面以获取更多关于本网站如何运作的信息。

+2
记录和类型
重新分类

作为一个特别关注原子和比较/设置作为并发原语的人,能够在deftype的不可变字段上执行比较/设置操作,而不产生额外的开销(更多的对象占用更多内存,更多的指针追查)将是件好事。

JVM有几个机制允许您直接在字段上执行CAS(如AtomicReferenceFieldUpdater、VarHandles等)。似乎deftype可以实现这样的功能供用户请求。

目前可以使用AtomicReferenceFieldUpdater与deftype一起使用,但由于私有的volatile字段和缺少静态初始化程序,这个过程有些复杂。

1 答案

0

这似乎是一个有趣的请求,但更像是一个解决方案而不是一个问题。您能否从该角度重新表述它?

很抱歉,我就是不理解你在问什么。

我想这可能是你第二次或第三次给出类似的反馈(之前在 #clojure-dev),我已经重写了一次(我以为)以纳入那次反馈。感谢你抽出时间,但显然我没理解。
也就是说,“我正在尝试构建 X,但做不到”。X 是什么?你需要做这件事的情况是什么?
这是一个错误百出的喜剧,我之前基本上完全误解了事情的反面,并删除了我特定问题的所有引用。

我编写了一种自定义的引用类型,不是真正的 Clojure 引用类型,但是一种类似的东西。一个带有对内容进行控制变异的盒子。A 实际上类似于原子或 ref。

我的类型是一个引用类型,具有一个可变字段,该字段指向引用本身指向的内容,以及用于促进其他操作的其它字段。我希望使用 compare and set 更改这个可变字段。

在纯 Clojure 中编写,只能通过使用存储在 deftype 字段中的值的原子或 AtomicReference 包装来实现这一点。这没问题,但增加了 1 或 2 级指针跟踪。我希望去掉那些额外的指针。

Java 为在可变字段上直接执行比较和设置提供了至少两种不同的设施(可能需要该字段是 volative 的,我忘记了)。这两个机制都是通过创建一种类型的字段访问器对象来工作的。一个类的典型模式似乎是在静态初始化器中创建字段访问器对象,然后在执行基于 cas 的字段操作时引用它。

典型的模式不适用于当前的deftype,因为尽管你可以使deftype字段的属性可变,但这也会使其私有,这就使得构建字段访问器对象变得困难。由于字段是私有的,所以你不能从“外部”构建,因为deftype不提供进行静态初始化的方法。为此,你可以采取一些变通方法,基本上是在你的deftype中添加一个什么也不做的方法来创建和返回字段访问器对象,然后在某些顶级静态上下文中构建一个你的deftype的示例实例并调用该方法。因此,这是可行的,但相当糟糕。

我最初尝试了创建一个示例deftype实例,但最终只简写成一个非常简化的deftype以生成一个包含字段和用于为特定字段设置AtomicReferenceFieldUpdater的静态初始化器的类。这也奏效了,但需要有一定的asm库经验,并且需要小心才能使其与aot编译良好兼容(我认为这一部分是正确的,但不确定)。

比较和设置非常棒,我们希望能提供一种对deftype字段进行操作的方式,而不需要额外的 wrappers 对我们想要比较和设置的对象进行包装。在java/jvm中存在这样的机制,但在Clojure中充分利用这些机制是痛苦的。
by
我认为Alex的要求仍未得到满足。即使使用像原子引用这样的原子和比较和设置,可以解决你试图解决的问题。使用可变状态和CAS解决的问题是什么?

如果我们可以回到最初的问题,可能会发生以下两种情况之一...要么1)我们会发现有一些其他好的方法来解决clojure中现有构造的问题,要么2)我们将面临一个具有挑战性的未解决问题,这可能导致语言、库或新库的添加。
by
我来到这里是因为我在想,带可变状态的deftype可能是解决我遇到的问题的一个好方法。我有一个基于Clojure代码的UI,我需要实现/扩展TableModel的一个实现,并将其传递给我的JTable实例。我需要以某种方式更新TableModel的内容...我猜想我可以完全重新创建它,每次都将新的TableModel传递给JTable,但这对于Swing来说似乎效率不高。我也可以使用gen-class,如果这是最好的方法,那么这将是不错的。我想要显示的数据在我的app状态中,这在一个atom中。当数据发生变化时,我想要将其发送到app状态atom的swap!,然后将这些更改传播回TableModel,并通过JTable显示它们。所以问题/问题是如何将TableModel连接到app状态。
作者:
将所有这些写出来,我的解决方案似乎很明确...我们可以直接从表格模型中引用应用程序状态,当应用程序状态发生变化时触发表格结构/行等变化。然而,我尚未提到有一个层次。我实际上正在使用FRP(函数式响应式编程)来构建UI。因此,视图是应用程序状态的一个函数。视图函数是一个纯函数,但由于Swing中JTable的实现方式,它必须包含对实际数据的引用。所以,我可以为每个视图渲染创建一个新的表格模型,在表格模型中使用一些自定义或现有的类存储状态,违反这个案例中的FRP模型,或者我想不到的其他方法。
...