You can usually get away with treating mutable Java objects as immutable 
values providing that you strictly limit where / how they can be mutated. 
This means:

- Knowing where / when the Java library might mutate the value (usually 
this is pretty obvious)
- Not mutating the value yourself

I use this technique myself a lot. For example, Vectorz has mutable Vector3 
instances that can represent points in 3D space, but I generally try to use 
them in an immutable style. Using a wrapper of any sort here would probably 
be a prohibitive overhead.

Bonus technique: you can also safely mutate the object *during 
construction* to get some performance gain before you have passed the 
reference anywhere else (various Clojure data structures do this, so you 
are in good company....)

One final point: if you have a really large number of such items and they 
are changing constantly, consider abandoning immutability and accepting 
mutable  objects in your Clojure code. Otherwise you may simply have too 
much GC pressure. This is clearly a compromise of the "purity" of immutable 
code, but it may be the pragmatic choice (e.g. if you are working on a 3D 
game engine, I don't think it is a good idea to have all your physics 
vectors immutable....).


On Saturday, 5 April 2014 16:10:19 UTC+8, David Koontz wrote:
>
> I am very new to Clojure so please forgive me if there is an obvious 
> answer that I have missed.  I'm trying to understand the effect of interop 
> with Java objects, specifically on the polluting nature of non-values in a 
> system.  If I need to interop with a Java library, and that library will 
> have mutable objects, how do I shield the rest of my program from that?  I 
> can think of a few solutions but they all seem terrible.
>
> 1. Copy all the data from the mutable Java object to a Clojure structure 
> that is a value.  This seems incredibly wasteful and in my case probably 
> totally unmanageable due to the GC pressure it would create (I'm working on 
> a game with lots of rapidly mutating Java objects).
>
> 2. Create a value-like wrapper that provides a read only interface.  This 
> doesn't really cause a memory issue, but now you have a "value'ish" thing 
> floating around that while not modifiable by you can up and change at any 
> moment.
>
> 3. Create a wrapper that memoizes data into true values but only as it's 
> accessed.  In my case I have an update window that demarcates time into 
> discreet slices.  At the end of the frame I could indicate to my "value" 
> that the underlying Java object can no longer be trusted to be the same so 
> all future attempts to access non-memoized values should fail.  This works 
> as long as you access the same fields/methods off the Java object down the 
> road.
>
> Of course all of these solutions have issues with object graphs and 
> needing to walk the whole graph to fully convert it into a value. So is it 
> worth trying to do anything along this path or is this a fool's errand and 
> I should find some other code organization way to run caution tape all over 
> the place shouting "careful here, this is dangerous highly volitile stuff!"?
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to