AW: [External] : AW: Frozen objects?

Markus Karg markus at headcrashing.eu
Fri Dec 22 14:36:14 UTC 2023


John,

thanks a lot for sharing, this is the definitive answer I originally hoped for when asking about freezed references vs freezed objects! :-)

You guys all are doing a great job and I do not want to get misunderstood: I didn't want to upset or criticize anybody, I just had a bad idea that apparently was discussed and ruled out long time ago by your team. In the end, I already rejected by proposal recently, and really, I am looking forward for the solution your team will some day come up with for read-only arrays.

Merry Christmas to all of you!
-Markus


-----Ursprüngliche Nachricht-----
Von: John Rose [mailto:john.r.rose at oracle.com] 
Gesendet: Freitag, 22. Dezember 2023 00:11
An: Dan Heidinga
Cc: Markus Karg; Holo The Sage Wolf; Archie Cobbs; amber-dev
Betreff: Re: [External] : AW: Frozen objects?

On 20 Dec 2023, at 8:58, Dan Heidinga wrote:

> C++ “const” is a bit of a mess.  It’s not only a local property that prevents writes to the reference; it’s also a viral property that infects the type system.

Well put Dan.  Thanks for writing that point so I don’t have to.
But I do have some more comments in this vein.

Adding distinctions to a type system is never a cost-free move.

They put a new burden on all programmers to maintain them,
as well a burden on all related tools and infrastructure.

A new distinction must be remarkably useful to pay for its costs.
Java generics is one good example, and maybe the only example,
of new distinctions successfully added to Java’s type system.

Even today the VM is designed to ignore the distinctions
introduced by generics.  It operates on “erased types”.

C# has made interesting forays into the game of adding new type
distinctions that apply uniformly across the pre-existing type system.
One is adding to every T an “expression-of-T” type for AST reification.
It had interesting results.  The Babylon project is developing something
similar, but less intrusive, with method and lambda reflection.

Another is adding an async mode at selected points (functional
types) which instructs the system to compile affected code into a
reactive form.  This was, I think, not a complete win, because
async code and regular code do not interoperate completely, so
programmers must assign incompatible “colors” to different regions
of code and API points using within them.  The “coloring problem”
of assigning reactive and normal “coloration” to code has always
struck me as a move similar to the C++ decision to “color” methods
as const or non-const (and often both ways repeatedly).

With Java, we tend to look skeptically on any attempt to “color”
code.  In particular, we invested in Project Loom precisely to
avoid having to “color” code as reactive vs. non-reactive.

Immutable data are interesting and highly useful, but modeling
immutability in the type system would probably be a mistake.
Note that the Java Collections API refuses to duplicate itself
into “mutable” and “immutable” colors.  Mutability in Java is
a mostly dynamic property.

Because of all of the above, I do think frozen arrays may be
in our future, but not a first-class type that looks like
“const T[]” or “final T[]”.  At most we might have a
declaration format like “__Frozen int[] FA = {1,2,3}”,
but it would be equivalent to something like “int[]
FA = Arrays.freeze(new int[]{1,2,3})”, maybe with a
subtle compilation format that avoids the temporary.

(I will not launch a syntax bikeshed discussion by
trying for a “real looking” syntax.  Just “__Frozen”
is sufficient to get my point across.  I will ignore
comments on the cosmetics of my example keyword,
since it is manifestly non-cosmetic.)

IN THEORY, frozen instances are possible in the VM,
with some header hacking and some extra barriers on
affected putfield instructions.  IN PRACTICE, we
would probably need to distinguish in user code
which methods are intended for all instances, and
which are for mutable ones.  There are not good
examples, IMO, for making this distinction in some
other programming language.  C++ const is not a
good example for Java to follow because it is too
viral, invasive.

So, given the above, the reserved keyword “const”
is almost certainly not going to be adopted into
Java along the lines of C++ const.  Nor is it likely
to be adopted as a new type distinction between
immutable and mutable data structures (which C++
const fails to fully express).

I will close with a speculation about what “const”
MIGHT be used for in the future, in Java.  (This
is just me wondering.  I agree with the consensus
to leave the dust on it undisturbed indefinitely
in the Java language specification.)

Java has a special place in the world of languages
because it has a reasonably strong static type
system, and yet execution does not depend greatly
on the type system.  In the VM, a Java program
acts in many ways like a Smalltalk or Lisp program.
At the user level this surfaces with the usefulness
of the Object type and interface types.

Part of the interplay between static and dynamic
typing is managed in Java by making permanent
decisions dynamically.  You can load a class
dynamically based on runtime computations,
but once loaded it is loaded forever.

For that reason, there is a special place in
Java for dynamic computations at the time of
symbolic resolution.  The invokedynamic and
CONSTANT_dynamic features in the VM live in
this special place:  You spin up something like
a lambda class on demand, and then use it
moving forward.  Spinning up program resources
(code and data) is inherent in the VM but not
in the language user model, except in a few
places, such as what happens the first time
a static field or method is accessed, in a
given class.  (Static initializers are run
then, at most once.)

PERHAPS the “const” keyword might someday
play a role in maintaining the distinction
between computations which take place at
most once, to spin up program resources
that will be permanently available thereafter.
It’s more likely that if we need a keyword
it will be some other more “transparent” word.

It’s not nearly time to design any of this,
however, within the language.  First we have to
build (in the existing language) Java APIs and data
structures which make such code patterns clear
and easy to work with.  Today, the work on
ComputedConstant is where this action is.

Also, program resources which are derived
by code transformations are an area we are
experimenting with in Project Babylon.
There are also experiments for offline
derivation in Leyden.  These experiments
all need to make much more progress before
we jump into language design.

This hesitation to modify Java is precisely
because Java is already an exquisitely effective
notation for formalizing and modeling and
thinking about all kinds of complicated designs,
including immutability and the spin-up of program
resources.  So we can prototype new ideas almost
forever in Java without touching the language.

When we do make changes, we can be reasonably sure,
through long experience, that the changes will be
profitable.

— John



More information about the amber-dev mailing list