New informational JEP: 14: The Tip & Tail Model of Library Development

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Oct 23 11:12:25 UTC 2024


On 22/10/2024 17:32, Alan Snyder wrote:
> Some language extensions may involve removing restrictions performed 
> by older compilers. Such extensions probably cannot be implemented 
> using a preprocessor. However, if no JVM support is required, then 
> these extensions are also candidates for a direct implementation by 
> javac. Flexible constructor bodies might fit in this category. Even a 
> restricted version of this feature would be useful.

I find the general idea of having magic switches to allow new features 
to target older JDKs rather unworkable in practice. Most features we do 
(sealed classes, records, pattern matching) do have rather deep 
ramifications, sometimes in terms of the Java SE API (e.g. patterns 
switches are translated with an indy targeting a bootstrap method that 
is not available in older JDKs), sometimes in terms of the JVM itself 
(e.g. the JVM knows about sealed classes).

So, if you start cherry picking language features, you quickly end up 
with a Frankenstein Java, which has some of the latest features, but not 
others. When we design a feature, we do not just design _that_ feature. 
A big part of designing a new feature (the biggest, often) is making 
sure that the feature work in harmony with other features that are part 
of that version of the language. An example of this is the strong 
synergy between record types, sealed interfaces and pattern matching 
which, together, give us algebraic data types (or, how we came to call 
it the "data-oriented programming" model [1]).

To put it bluntly, what you are asking for amounts at throwing all this 
careful design work down the drain, and work with _some_ unspecified 
version of the language where things *might* work (but also might break 
in surprising ways). Logistically, this is also a big nightmare, as the 
JDK will have different implementations for the same feature - which 
makes code harder to maintain and test, and much more difficult to 
evolve. This is certain to translate in *less* new features being added 
to Java, as a lot of our budget will be spent in fixing arcane issues 
when a feature in Java N doesn't work as expected when running on Java N 
- M.

But, since you specifically refer to "Flexible constructor bodies", as 
one of those seemingly low-hanging fruits that javac should "just" 
translate away and make available for older runtimes, please take a look 
at the size and complexity of some of the patches involved to support 
that feature [2, 3, 4]. Can we "just" enable flexible constructor bodies 
for older targets? In theory, yes. In practice, the chances that such 
changes can be enabled for any older target and not disrupt anything 
else are rather slim -- in fact, the work in (4) was to fix an obscure 
regression with serializable lambdas that was only possible to spot due 
to extensive testing.

In my experience, there's no such thing as a "simple" language feature 
-- even a feature might be *conceptually* simple, the devil is always in 
the details, and it is those details that, in the end, make your 
suggestion unworkable in most cases I can think of.

[1] - https://www.infoq.com/articles/data-oriented-programming-java/
[2] - https://github.com/openjdk/jdk/pull/13656
[3] - https://git.openjdk.org/jdk/pull/19836
[4] - https://git.openjdk.org/jdk/pull/20349



More information about the jdk-dev mailing list