Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly express references in immutable model in Scala?

Let's say I want an immutable model, a world. How one should model references?

case class World(people: Set[Person])

case class Person(name: String, loves: Option[Person])

val alice = Person("Alice", None)
val peter = Person("Peter", Some(alice))
val myWorld = World(Set(alice, peter))

println(myWorld)

Outputs:

World(Set(Person(Alice,None), Person(Peter,Some(Person(Alice,None)))))

But now we have two separate persons named Alice (in the people set and in the peter person).

What is the best practice(s) on approaching this referencing in an immutable model in Scala?

I thought about referencing strictly through ids, but it doesn't feel right. Is there a better way? (Also current implementation doesn't support recursion/circle like A loves B and B loves A.)

like image 625
monnef Avatar asked Nov 24 '25 08:11

monnef


1 Answers

I think you have to distinguish between pure values, and things that have a notion of identity that survives state changes.

A person might be something in the latter category, depending on the requirements of your model. E.g. if the age of a person changes, it is still the same person.

For identifying entities over state changes, I don't think there is anything wrong with using some kind of unique identifier. Depending on your model, it might be a good idea to have a map from person id to person state at top level in your model, and then express relationships between persons either in the person state, or in a separate data structure.

Something like this:

case class Person(name: String, age: Int, loves: Set[PersonRef])

case class PersonRef(id: Long) // typesafe identifier for a person

case class World(persons: Map[PersonRef, Person])

Note that a person state does not contain the ID, since two persons with different IDs could have the same state.

A problem with this approach is that the world could be in an inconsistent state. E.g. somebody could love a person that does not exist in the world. But I don't really see a way around this.

I think it might be worth looking at scala libraries that are confronted with a similar problem. E.g.

diode has the concept of a reference to a value elsewhere in the model

scala graph allows to define custom node and edge types.

like image 107
Rüdiger Klaehn Avatar answered Nov 28 '25 17:11

Rüdiger Klaehn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!