4 ms·
Having worked in a couple different large Java projects, there are certainly tradeoffs to both sides: make too many things immutable and you will not end up in
by pbh101 11y ago
Having worked in a couple different large Java projects, there are certainly tradeoffs to both sides: make too many things immutable and you will not end up in a happy place GC-wise. And add the requisite "it depends on the project" to the remainder of this comment :)
But if I were to start a project, I would start with immutability by default and go from there, chiefly because when you find yourself needing to add additional threads and share data, I consider the transition from mutable to immutable would be more difficult than the inverse.
Another perspective: mutability is a feature that can be used in certain contexts (and QUITE useful there) but nothing intrinsic to the feature (in Java, at least) enforces the contexts' prerequisites (i.e. thread-safe access), and thus it is easy to end up with runtime errors when the environment of your project shifts.
Immutability, OTOH, makes fewer contextual assumptions (or perhaps more tractable ones).
Said perhaps more pithily: when mutable-by-default, your resultant architecture will frequently hinge on mutability. If you instead start with immutability, the immutability will be less of a crutch than the mutability would have been.
- unclebucknasty 11y ago>nothing intrinsic to [mutability] (in Java, at least) enforces the contexts' prerequisites (i.e. thread-safe access) I guess that's where I differ: To my mind the mutability construct is not supposed to provide this. Instead, enforcing thread-safety should involve the use of concurrency constructs. And, that's the thing: OOP represents a stateful paradigm, in the sense that operations may be performed which mutate the state of an object. When we bring out the Hammer of Immutability to prevent potential concurrency issues, we are basically saying that we no longer want to be OO because of an unrelated requirement. Let's turn the objects into structs that can only be passed around and copied so we don't accidentally screw something up. This, rather than using the language's actual concurrency constructs to safely share data. >it is easy to end up with runtime errors when the environment of your project shifts I can't remember when this has happened to me and I'm genuinely having trouble seeing the case. If I have an object which suddenly must be shared across another thread, then I generally cease to access it on the initial thread without some sort of synchronization. So, I just don't see how you'd suddenly share data across threads under any model without very careful consideration of what's being shared and why. What operations will be performed with the data as input, what will be the output, and how/when do we communicate this to other threads? Once you've done that analysis, then you have a blueprint for how to safely share data the right way.