Welcome! Please see the About page for a little more info on how this works.

+2 votes
in Records and Types by
recategorized by

As a person who is really into atoms and compare and set as a concurrency primitive, it would be nice to be able to do a compare and set on mutable fields in a deftype without incurring the overhead (more objects taking more memory, and more pointers to chase) of either a java AtomicReference or a clojure atom.

The jvm has several mechanisms that allow you to directly cas on a field (AtomicReferenceFieldUpdater , VarHandles. maybe others). It seems like deftype could make such a thing available on request.

It is currently possible to use AtomicReferenceFieldUpdater with deftype, but is somewhat convoluted due to volatile fields being private, and the lack of static initializers.

1 Answer

0 votes

This seems like an interesting request but is more of a solution rather than a problem. Can you restate it more from that perspective?

I am sorry, I just don't understand what you are asking for.

I think this is the second or third time you given similar feedback on this (previously in #clojure-dev), and I have already rewritten this once to (I thought) incorporate that feedback. Thank you for taking the time, but it seems clear that I just don't get it.
As in, "I'm trying to make X, but I can't". What's X? what's the case where you need to do this?
what a comedy of errors, I misunderstood things basically the opposite way before and removed all references to my specific problem.

I wrote a custom kind of reference type, not really a clojure reference type, but a similar kind of thing. A box with controlled mutation for the contents of the box. A ends up being vaguely atom or ref like.

My type being a reference type, has a mutable field that points to whatever the reference itself points to, a long with other fields to facilitate other operations. I would like to mutate the mutable field using compare and set.

Writing this in "vanilla" clojure the only way to do this by using an atom or an AtomicReference wrapper around a value held in a deftype field. This works but adds 1 or 2 levels of pointer chasing. I would like to get rid of those extra pointers.

Java provides at least two different facilities for doing a compare and set directly on a mutable field (they may require that the field be volatile, I forget). Both of those mechanisms work by creating a kind of field accessor object. The typical pattern for a class seems to be create the field accessor object in a static initializer and then use it as needed when doing cas type stuff on fields of instances.

The typical pattern doesn't work with deftype as is, because although you an make a deftype field mutable, that also makes it private, which makes constructing a field accessor object difficult. You can't construct one from "outside" because the field is private, and deftype's don't provide a way to do static initialization.  There are ways to work around this, basically you add a method to your deftype that does nothing but create and return the field accessor object, and then in some top level static context construct a dummy instance of your deftype and invoke the method. So it is possible to make this work, it is just kind of terrible.

I initially did the dummy deftype instance thing, but eventually just wrote what is basically an extremely stripped down version of deftype to generate a class with fields and a static initializer that sets up AtomicReferenceFieldUpdater for specific fields. This also works, but relied on having some experience with the asm library, and some care to make it work well with aot compilation (I think I got this part right, but not sure).

Compare and set is great, it would be nice to provide someway to do it on deftype fields that didn't require additional object wrappers around what we want to compare and set. The mechanisms for it exist in java/jvm but are painful to take advantage of in clojure.
I think Alex's request still remains unfulfilled. Having something mutable, even if it is using an atom like reference and compare and set, is the solution to the problem you're trying to solve. What is the problem that is being solved with mutable state and CAS?

If we can get to that original problem then one of two things may happen... either 1) we'll find there are other good ways to solve the problem with existing constructs in Clojure, or 2) we have a challenging unsolved problem that may lead to an addition to the language, an addition to a library, or a new library.
I arrived here because I am thinking deftype with mutable state may be a good solution to a problem I have. I have a UI based on Clojure code and I need to implement/extend one of the TableModel implementations and give it to my JTable instance. Somehow, I need to update the contents of the TableModel... I suppose I could completely recreate it and give JTable a new TableModel every time, but that doesn't seem performant for Swing. I could also use gen-class - which would be fine if that is the best way. The data I want to display is in my app state, which is in an atom. When the data changes, I want to send the changes to a swap! on the app state atom and propagate those changes back to the TableModel and subsequently display them with the JTable. So the question/problem is how to wire up the TableModel to the app state.
Writing all that out it seems clear what my solution might be... to reference the app state directly from the table model and fire table structure/row/etc. changes when the app state changes. However, there's a layer I didn't mention. I'm actually using FRP (Functional Reactive Programming) for the UI. So the view is a function of the app state. The view function is a pure function, but because of how JTable is coded in Swing, it must contain a reference to the actual data. So either I create a new table model with each view rendering, store state within the table model using some custom or existing class, violate the FRP model for this case, or something I haven't thought of.