> On Apr 24, 2025, at 6:34 AM, Remi Forax <fo...@univ-mlv.fr> wrote:
> 
>> Perhaps we should be asking: who will emit the ACC_STRICT_INIT flag, and 
>> when?
> 
> yes, making the early field initialization part of FCB muddy our chances to 
> later uses early initialization as a signal for the compiler to declare the 
> field as ACC_STRICT_INIT.

> So i would prefer to have a real plan on how Java will use ACC_STRICT_INIT. 
> For now, we have not ruled out to use early initialization as a signal, so i 
> would like to keep that option open, even if that means going back to the 
> original proposal of FCB, and only releasing that.

Let me clarify how we've been thinking in recent Valhalla work about the path 
toward an eventual strict-by-default world in the language:

1) With value classes, we introduce the concept of strictly-initialized fields 
in the JVM, enforce rules that value class sources require early initialization 
of their fields, and provide an "early-by-default" interpretation of these 
classes (early instance field initializers, implicit 'super()' at the end of 
constructors). Potentially, we can also subject record classes to these 
behaviors, with some small compatibility risk. [See 
https://openjdk.org/jeps/401#Value-object-initialization]

2) At the same time, we introduce some *warnings* to encourage a style of 
programming in identity classes that could support early-by-default compilation 
in the future. [See 
https://openjdk.org/jeps/401#Encouraging-early-initialization-of-identity-classes]

3) At some later point, we provide a language feature (mechanism TBD) to allow 
identity classes to opt in to the value class early-by-default rules. In a 
class that opts in, a field that is early-initialized is treated as 
ACC_STRICT_INIT, and a field that is late-initialized is not. (It might be an 
error or warning to try to mix initialization timings of a single field.)

Where does support for early assignment in constructor bodies fit in? It's a 
hard prerequisite to (1), because that is the only way to initialize a value 
class field. It's also important for (2), because one way to address warnings 
about 'this' dependencies is to add a 'super()' call to the constructor, and 
then put the 'this'-dependent code after that call (but keep the rest of the 
code early).

Note that (2) has no semantic impact, so it's something we can readily impose 
on every class. And then the idea is that (3) allows programmers to opt in to 
subtly different semantics (like the memory model effects you've illustrated); 
a program that has addressed the warnings by then won't need to make any 
additional source changes.

Of course this is not the only possible way to approach the problem, but there 
are some good reasons to arrange things like this:

- (1) comes with early initialization requirements, but we don't want to tie 
the semantic changes of (3) to getting value classes out the door. Frankly, (3) 
is a can of worms and I'm not sure where it will lead. So there needs to be 
some space between (1) and (3).

- (1) encourages class authors to think about construction timing and 'this' 
dependencies, and so it's a good opportunity to get them to consider those 
things throughout their code—hence tying (1) and (2) together.

(One piece of this that isn't clear to me, and that we need to discuss further, 
is where '!'-typed fields fit in—they also require early initialization and 
ACC_STRICT_INIT. Maybe using '!' on a field is one form of the opt-in described 
in (3). Or maybe that's too indirect. TBD...)

Reply via email to