Thoughts on opt-in mutability?
Brian Goetz
brian.goetz at oracle.com
Thu Jan 18 15:52:59 UTC 2024
So, you provide several good arguments here for "Java picked a bad
default with respect to mutability." (It is in good company; Java
picked many bad defaults, such as package visibility rather than
private, classes being extensible rather than closed, etc.) Let's just
take it as given that non-final is an imperfect default for fields.
Which brings us to the next question: "now that we realize the default
is bad, should we change it?" This is a much harder question, because
it involves the reality of 10M developers and billions of lines of code.
One bit of prior art here that might be relevant (and the experiment is
still playing out) is C#'s flipping of the nullability default on a
per-module basis (with injecting checking at the boundaries.) This was
a bold experiment and we are interested in seeing the results.
The problem with trying to fix the mistakes of the past is that in most
cases, you are just creating a fork and forcing users to deal with both
branches. If we had a directive:
class X {
#pragma default-final
...
}
then now users have to keep track (possibly on a per-file basis) of
where "int x" means final or mutable. This is adding cognitive load to
all users, since almost no Java developer has the luxury of controlling
100% of the code they deal with.
> A one line distillation of the above is perhaps: "Immutability is
> common enough to consider a fast path at source level; the current
> slow path has negative consequences for cognition and devx."
Valid, but what this misses is: "having to constantly reason about
whether line #656 of Moo.java is on the fast path or the slow path has
even higher cognitive load."
On 1/17/2024 10:20 PM, Subra V wrote:
> Hello Project Amber team,
>
> What are the current thoughts on providing source level mechanisms for
> opting-in to mutability rather than the current opt-out? For example,
> a notion of immutable class (not a record) can obviate specifying
> "private final" for fields. Opt-in mutability would perhaps also jive
> with two recent themes in language evolution: 1. Functional style 2.
> More cognition, less ceremony (switch statement, pattern matching to
> name a few).
>
> If there's prior relevant material, I'd appreciate a pointer; Dr.
> Google hasn't uncovered anything of note.
>
> I realize that this question has red flags of "proposing a solution"
> to "my specific problem". So, let me clarify that (1) I only write
> because I believe there's a reasonable chance that opt-in mutability
> is of fairly broad interest. (2) I am not proposing obviating the need
> for 'private final' as a solution; instead, it is meant to be
> analogous to saying 'I want String interpolation', a 'solution' from
> which language designers carefully teased apart a general problem and
> solved it in the form of String Templates.
> ---
>
> I am certain language designers are aware of this (and plenty more),
> but in the interest of intellectual honesty, let me attempt to
> articulate problems with default-mutability from my default-immutable
> practice.
>
> 1. [Immutable style feels second class] Java has moved in a functional
> direction much to my (and most practitioner's?) pleasure. For
> the subset of folks who buy into this direction, Immutable classes are
> natural. Yet, they feel second class in that (1) notions of "private
> final" aren't relevant yet pollute (2) It requires extra work [making
> all fields final, binding them in constructor] compared to the default
> case of mutability
>
> 2. [Cognitive Cost of Ceremony] For non-record Immutable classes, I
> have to (1) Write 'private final X' and then add a constructor param
> and set `this.X = X` in the constructor. (2) Read and verify `private
> final` on every field to know that the class is immutable. Even though
> IDEs help, it breaks the flow of thought both when reading and writing
>
> 3. [Poor Prototyping Velocity] I often find the ceremony especially
> frustrating in early phases of design, especially when using immutable
> classes. Imagine I have 20 concepts/fields and I am attempting
> to organize them. A common occurrence is to realize 'ohh this
> field/method logically belongs to that other class; let me move it
> there' but it is a pretty big chore to do so (even with Intellij)
> given that immutability takes extra work to achieve. Such moves also
> come with further transitive ripple effects. All the busy work perhaps
> accounts for upwards of 30% of the initial few hours/days of design
> and more importantly, constantly interrupts thoughts. For contrast, if
> I just make every field public during the initial period, it'd
> probably be a better experience, but then I need a magic wand to make
> them all immutable after the design settles down.
>
> A one line distillation of the above is perhaps: "Immutability is
> common enough to consider a fast path at source level; the current
> slow path has negative consequences for cognition and devx."
>
> Appreciate thoughts.
>
> Thank you,
> Subrahmanyam
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240118/d1fc771a/attachment-0001.htm>
More information about the amber-dev
mailing list