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