Apologies if the title is confusing; I’m not sure how best to explain this in the title.
Basically, I have two classes, Foo and Bar. Foo has a property of type Bar. Bar has a Set<Int> on it.
data class Foo(bar: Bar)
data class Bar(ints: Set<Int>)
When I have an instance of Foo, and I want to add an Int to the set of Ints on bar, how do I do that in an idiomatic, immutable way that isn’t also ugly and confusing?
Pretty awful, right? Unfortunately, I can only really think of two solutions.
Add a function to Foo to add a new Int to the set of Ints on Bar, then basically move all of that horribly ugly copy code into that function. This basically hides the ugliness from where I’m using it, and makes the code easier to read, but that ugliness still exists in my code base. This is my preferred solution.
Just make things mutable. This is not my preferred solution.
However, both of those thoughts have made me start thinking; how do we update objects while using immutability? Are those two things just fundamentally incompatible? Or do I just not know enough about how to do things in an immutable way? I’m interested in whatever thoughts/knowledge everyone has on this!
(For those curious, this is what my actual code looks like):
I’m not sure how this helps. Forget about the DAO, the real question is more “how do I update a property on a sub-object without copying the parent and the child?”
That’s pretty cool… I was hoping for something within the standard library, not a third-party library with (possibly) extra compilation, but the way it works for “setting” nested values, but presumably still in an immutable way (IE using copy), does kind of look like what I want.
That doesn’t help; my goal is to add a value to the Set on the sub object.
val currentFoo = Foo(Bar(setOf(5)))
val newFoo = currentFoo.copy(bar = currentFoo.bar.copy(ints = currentFoo.bar.ints + setOf(7)))
// newFoo = Foo(bar=Bar(ints=[5, 7]))
EDIT: Wait I get what you mean. Instead of doing setOf(newNumber) I just add it to the existing Set. My apologies. Yeah it does help a little bit.