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

欢迎!请参阅关于页面以获取有关此如何工作的更多详细信息。

+2
记录和类型
重新分类

作为一个真正对原子和compare-and-set作为并发原语很感兴趣的人,能够在deftype的可变字段上执行compare-and-set操作而不产生开销(更多对象消耗更多内存,更多指针需要追踪)会很不错。

JVM有几个机制允许您直接在字段上执行cas(AtomicReferenceFieldUpdater、VarHandles等)。这似乎意味着deftype可以提供这样的功能供请求。

目前可以使用AtomicReferenceFieldUpdater与deftype一起使用,但由于volatile字段是私有的,以及缺少静态初始化,这有点复杂。

1 答案

0

这看起来像一个有趣的需求,但更多地是一个解决方案而不是问题。您能否从那个角度来看重新表述一下?

抱歉,我只是不明白你到底在问什么。

我想这是您第二次或第三次(之前在#clojure-dev中)提出类似的反馈了,我已经修改了一次,尝试吸收这些建议。谢谢您抽出时间,但看来我仍然没有理解到您想要表达的内容。
这就是说,"我试图完成X,但是做不到"。X是什么?你为什么需要这样做?
真是一场错误的喜剧,我之前基本上反着理解了这些事情,并移除了所有与我特定问题相关的引用。

我写了一个定制的引用类型,这不是clojure的引用类型,但是一种类似的东西。一个具有控制变动的盒状结构,用于存储盒子的内容。A最终变得有点像是原子或ref一样。

由于我的类型是引用类型,它有一个可变字段,指向引用本身所指向的内容,以及其他用于其他操作的字段。我想使用比较和设置的方法修改这个可变字段。

在“纯”clojure中,唯一通过使用一个atom或AtomicReference包装器在deftype字段中存储的值来实现此操作的途径。这可行,但添加了1或2级指针追踪。我希望去除这些额外的指针。

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

典型的模式在deftype中无法使用,因为尽管你可以将deftype字段设置为可变的,但这也使其变为私有,这会使得创建字段访问器对象变得困难。你不能从“外部”创建它,因为字段是私有的,且deftype不提供静态初始化的方式。基本上有办法解决这个,就是在你的deftype中添加一个什么也不做的函数,但只是为了创建和返回一个字段访问器对象,然后在某个顶层的静态上下文中创建一个假实例并调用该函数。所以,这本来是可以实现的,但非常糟糕。

我最初是尝试了模拟deftype实例的方法,但最终只是编写了一个极其简化的deftype版本,用于生成具有字段和静态初始化器的类,该初始化器为特定字段设置AtomicReferenceFieldUpdater。这同样有效,但需要一些asm库的经验,并且要小心使其能够在aot编译中良好工作(我认为我已经正确处理了这个部分,但不敢肯定)。

比较和设置非常棒,如果能提供一种方式在不需要额外对象包装的情况下对deftype字段进行比较和设置,那就更好了。在java/jvm中存在实现这种机制的机制,但在Clojure中很难利用。
by
我认为Alex的要求仍然没有得到满足。即使使用原子引用(atom)和比较和设置(CAS),也解决了您试图解决的问题。使用可变状态和CAS解决什么问题呢?

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