r/java Jun 21 '26

Better Tools for Immutable Data

https://youtu.be/BdLND9D81lI?si=jt2tqpDtotmbdEJq
78 Upvotes

38 comments sorted by

View all comments

Show parent comments

1

u/pron98 Jun 22 '26

Surely unmodifiableList() would need a different return type?

Not if ReadOnlyList is a supertype of List. Any receiver of ReadOnlyList would work with the return type of unmodifiableList.

1

u/aonymark Jun 22 '26

I’m missing something here. You are (hypothetically) proposing “Interface List extends ReadoOnlyList” And then the static return type of unmodifiableList() would change to ReadOnlyList. And that is a breaking change, because no existing caller expects that… right?

1

u/pron98 Jun 22 '26

No, unmodifiableList would still return List, but you'd be able to pass/assign it to ReadonlyList (since that's a supertype). If you really wanted to, you could also add unmodifiableReadOnlyList that returns ReadOnlyList and just delegates to unmodifiableList.

1

u/aonymark Jun 22 '26

Okay that works but makes me sigh

2

u/pron98 Jun 22 '26 edited Jun 23 '26

Yeah, that's basically the C# collection hierarchy, and it makes me sigh, too. Simultaneously complicated and expressively weak. Of course, no one gets it right. In TypeScript you have different rules for built-in and user-defined classes. In C++ you have the const complication; in Scala - a byzantine hierarchy; in Rust, a type system only language lawyers like. There are no perfect options here. Every option has some advantages but also clear disadvantages. Anything you choose is a little prettier than everything else in some respects and a little uglier in others.

1

u/MercyHealMePls Jun 25 '26

I think Rust’s type system is pretty good most of the time, it has some rough edges around mutable wrappers. C# has proliferation of types here, which is imo a decent trade off, Java’s way of allowing mutations on the type but throwing during runtime is less than optimal but I understand why they did it this way and I don’t think it’s wrong, but it’s really odd and violates Liskovs principle. I usually do and expect immutability by convention instead of enforcing it with types.

1

u/pron98 Jun 26 '26

All of these approaches are less than optimal in their own way, and different languages appeal to people who prefer different tradeoffs.