Immutable object graph

V

visionset

I have a graph of Leafs and Nodes.
A Node has 0...n Leafs
A Leaf has 1...2 Nodes.
The referencing is circular.

During execution I wish to modify both Nodes (eg add/remove Leafs) and Leafs
(eg add a Node to a single Noded Leaf).
The Leaf is easy to make Immutable, but does it make sense to make the Node
immutable?
Since my model holds a collection of references to all the nodes[1], the
collection itself, is mutable so I can swap nodes in and out if I were to
have an immutable Node. The overhead of recreating Nodes and linking them
is not going to be a problem. Really my concern is the simplicty of the
code. On one hand immutables themselves are simple and have the usual
advantages but on the downside there will be more code that has to
reestablish the natural composition references that would otherwise (with a
mutable) already exist.
If I end up having a mixture of Mutable Node and Immutable Leaf, then I'll
have Sets of Leafs and Lists of Nodes, since I see it non-sensical (and
error prone) to have a Set of mutables. But I guess that doesn't matter.

[1] I don't rely on traverseing the graph because there are non-contiguous
graph portions.

TIA,
 
P

Patricia Shanahan

visionset wrote:
....
If I end up having a mixture of Mutable Node and Immutable Leaf, then I'll
have Sets of Leafs and Lists of Nodes, since I see it non-sensical (and
error prone) to have a Set of mutables. But I guess that doesn't matter.
....

I don't see the reason for avoiding a Set of mutables, provided those
things that affect the Set contract and implementation are immutable.

In particular, I see no problem with a HashSet<Node> if Node directly
extends Object and overrides neither equals nor hashCode.

Patricia
 
M

Mike Schilling

visionset said:
I have a graph of Leafs and Nodes.
A Node has 0...n Leafs
A Leaf has 1...2 Nodes.
The referencing is circular.

During execution I wish to modify both Nodes (eg add/remove Leafs) and
Leafs (eg add a Node to a single Noded Leaf).
The Leaf is easy to make Immutable, but does it make sense to make the
Node immutable?

It seems to me that
I wish to modify both Nodes and Leafs
and
The Leaf is easy to make Immutable

contradict each other.
 
V

visionset

Mike Schilling said:
It seems to me that
I wish to modify both Nodes and Leafs
and
The Leaf is easy to make Immutable

contradict each other.

When I wrote that I thought, 'shall I be totally precise or will it get the
point accross?' ...Alas.

So by modify an immutable I mean obtain an instance that reflects the new
state I require.
I mean it really goes without saying, you can't Modify an Immutable, doesn't
it?

Leaf newLeaf = oldLeaf.withNewFoo(myFoo);
 
V

visionset

Patricia Shanahan said:
visionset wrote:
...
...

I don't see the reason for avoiding a Set of mutables, provided those
things that affect the Set contract and implementation are immutable.

In particular, I see no problem with a HashSet<Node> if Node directly
extends Object and overrides neither equals nor hashCode.

Patricia

Thanks Patricia, I'll see how I get on.
 
A

andrewmcdonagh

I have a graph of Leafs and Nodes.
A Node has 0...n Leafs
A Leaf has 1...2 Nodes.
The referencing is circular.

During execution I wish to modify both Nodes (eg add/remove Leafs) and Leafs
(eg add a Node to a single Noded Leaf).
The Leaf is easy to make Immutable, but does it make sense to make the Node
immutable?
Since my model holds a collection of references to all the nodes[1], the
collection itself, is mutable so I can swap nodes in and out if I were to
have an immutable Node. The overhead of recreating Nodes and linking them
is not going to be a problem. Really my concern is the simplicty of the
code. On one hand immutables themselves are simple and have the usual
advantages but on the downside there will be more code that has to
reestablish the natural composition references that would otherwise (with a
mutable) already exist.
If I end up having a mixture of Mutable Node and Immutable Leaf, then I'll
have Sets of Leafs and Lists of Nodes, since I see it non-sensical (and
error prone) to have a Set of mutables. But I guess that doesn't matter.

[1] I don't rely on traverseing the graph because there are non-contiguous
graph portions.

TIA,


So it if I have it right, you'd prefer to have everything immutable,
whilst also be able to insert and remove nodes within the tree...

If thats right, then this is possible, and used by the AWTSwing event
system, to provide thread safe yet non-blocking structures of Publish-
subscribers.

Take a look at (old but good) http://www.javaworld.com/javaworld/jw-03-1999/jw-03-toolbox.html
for an example about how you could achieve this.

Andrew
 
D

Daniel Pitts

When I wrote that I thought, 'shall I be totally precise or will it get the
point accross?' ...Alas.

So by modify an immutable I mean obtain an instance that reflects the new
state I require.
I mean it really goes without saying, you can't Modify an Immutable, doesn't
it?

Leaf newLeaf = oldLeaf.withNewFoo(myFoo);

So, your object graph itself is not immutable, but the nodes within it
may be? That doesn't quite make sense either.

In any case, isn't a Leaf just a type of Node? Often they are
implemented using the same class, as their behavior is the same.
Another common approach is a Node class and an Edge class.
 
M

Mike Schilling

visionset said:
When I wrote that I thought, 'shall I be totally precise or will it get
the point accross?' ...Alas.

So by modify an immutable I mean obtain an instance that reflects the new
state I require.
I mean it really goes without saying, you can't Modify an Immutable,
doesn't it?

This time, at least, it helped to say it.

But (and I'm not trying to be difficult, honestly) if you're going to
"modify" a leaf by making a new instance of it, the things that point to
leaves (i.e. Nodes) need to be mutable. Otherwise, when you change any
Leaf, you'll have to recreate the Nodes that point to it, and the leaves
that point to *them*, and the Nodes that point to *them*, ... in other words
the entire graph.
 
V

visionset

But (and I'm not trying to be difficult, honestly) if you're going to
"modify" a leaf by making a new instance of it, the things that point to
leaves (i.e. Nodes) need to be mutable. Otherwise, when you change any
Leaf, you'll have to recreate the Nodes that point to it, and the leaves
that point to *them*, and the Nodes that point to *them*, ... in other
words the entire graph.

Yes but most of the objects will be reused. Changing a Leaf will only cause
instantiation of that Leaf and its Nodes. Anyway expense isn't an issue,
code elegance and simplicity is the aim.
With that in mind, however, I think perhaps the best solution is Mutable
Nodes and Immutable Leafs.
 
V

visionset

So, your object graph itself is not immutable, but the nodes within it
may be? That doesn't quite make sense either.

Item13: Always favour Immutability
In any case, isn't a Leaf just a type of Node? Often they are
implemented using the same class, as their behavior is the same.
Another common approach is a Node class and an Edge class.

Yes I really mean Edge not Leaf (sorry for confusion)
 
V

visionset

Lew said:
"Always favor" != "Always use"

You are supposed to think about the situation. Dogma is unreliable.

You snipped the context, it was a response to the confusion of another
poster.
I don't think I've said 'always use'.
 
L

Lew

visionset said:
You snipped the context, it was a response to the confusion of another
poster.
I don't think I've said 'always use'.

I wasn't trying to take issue with what you said but to point out for other
readers what the limitations are of such principles.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top