I'm aware that immutability is not always the holy grail. However, since I'm learning Scala for quite a while now, I always try to find an immutable solution at first, especially when it comes to pure "data objects". I'm currently in the progress of finding a method for creating an immutable object graph for a given scenario, but I'm not sure if this is possible at all.
I just want to create the graph once, changes after the creation are not necessary.
Imagine the following scenario:
Person
.Person
objects can have two types of references:
Person
). The first problem is that the relationship between two spouses is cyclic. Because setting references results in new objects (due to immutability), eventually spouse A is pointing to spouse B_old and spouse B is pointing to spouse A_old. Someone in another posting said that cyclic references and immutability are an oxymoron. I don't think this is always true since spouse A could create spouse B in its own constructor and pass this
- but even when using this uncomfortable approach, adding the children references afterwards would change A and B again. The other way round - beginning with children and then linking spouses - results in a similar situation.
At the moment, I think there is no way to do this. but maybe I'm wrong and there are some patterns or workarounds I'm not aware of. If not, is mutability the only solution?
I can imagine several tricks how you can create immutable cycle, including, but not limited to:
But the one I like most (and it is truly scala-way) is carefully mixed lazy evaluation and by-name parameters:
object DeferredCycle extends App {
class C(val name:String, _child: => C) {
lazy val child = _child
override def toString: String = name + "->" + child.name
}
val a:C = new C("A", b)
val b:C = new C("B", a)
println(a)
println(b)
}
Prints:
A->B
B->A