[External] : AW: Frozen objects?
Brian Goetz
brian.goetz at oracle.com
Thu Dec 21 16:27:15 UTC 2023
Dan is 100% correct here; there's a reason we haven't pursued this, and
it's not because we've never used C++. It's not even a close call; it's
an obvious loser.
> So you think frozen objects will be any simpler?
Dan never suggested frozen objects were a good idea either; someone
asked a question about them, that's all. And it's disingenuous to
suggest that these are the only two options, or that if you don't like
A, then you must like B.
(As a rule of thumb: arguments that start with "So you think / so you're
saying" are almost never what that person things or is saying.)
In any case, we are way outside the charter of amber-dev here. I think
best to stop here.
On 12/21/2023 11:08 AM, Dan Heidinga wrote:
>
> Not unsolvable but the payoff isn’t there.
>
> None of this is the hard work of figuring out what “const” would mean
> in the language, how it would fit with return types, method
> parameters, receivers, conversions, annotations, reflection,
> methodhandles, debuggers and any other number of existing features in
> Java.
>
> If “const” is something you really want to see added to Java, then
> spend the time to work through the semantics and bring a proposal with
> enough details worked out that it can be discussed and debated on its
> merit.
>
> *From: *Markus Karg <markus at headcrashing.eu>
> *Date: *Thursday, December 21, 2023 at 10:52 AM
> *To: *'Red IO' <redio.development at gmail.com>, Dan Heidinga
> <dan.heidinga at oracle.com>
> *Cc: *'Holo The Sage Wolf' <holo3146 at gmail.com>, 'Archie Cobbs'
> <archie.cobbs at gmail.com>, 'amber-dev' <amber-dev at openjdk.org>
> *Subject: *AW: [External] : AW: Frozen objects?
>
> You are right, backwards compatibility without introducing const_cast
> as in C++ is a problem. But that does not neither man that we MUST
> introduce const_cast nor that the problem is not solvable.
>
> -Markus
>
> *Von:*Red IO [mailto:redio.development at gmail.com]
> *Gesendet:* Donnerstag, 21. Dezember 2023 16:06
> *An:* Dan Heidinga
> *Cc:* Markus Karg; Holo The Sage Wolf; Archie Cobbs; amber-dev
> *Betreff:* Re: [External] : AW: Frozen objects?
>
> I think const is a pretty fine concept, the confusion in c++ primarily
> comes from it's confusing syntax and having multiple meanings like
> const member functions.
>
> A conversion from const to non const just makes no sense. You can use
> every non const object like a const one but never the other way around.
>
> I prefer the inverted rust equivalent "mut" more as it makes the point
> more clear. If you share a mutable reference you expect the recipient
> to mutate your data, if you pass an immutable reference you can be
> ensured the recipient won't change your data.
>
> It's just a contract rather or not some value can be mutated and
> rather or not a method requires to mutate it's parameters.
>
> In java we currently are stuck with exception throwing views,
> documentation and defensive copies.
>
> I'm not sure rather adding an internal mutability system afterwards is
> possible or a good idea. Especially old libraries would require some
> sort of const cast to be usable. Which would undermine the certainty
> such a system provides.
>
> Best regards
>
> RedIODev
>
> On Wed, Dec 20, 2023, 17:58 Dan Heidinga <dan.heidinga at oracle.com> 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. Instead of dealing with a single
> type (“X”), we now have two (“X”, “const X”) with a 1-way
> conversion from “X -> const X” but no conversion back (Let’s not
> talk about const_cast’s undefined behaviour….). Now methods need
> to be defined to take either an X or a const X parameter and need
> to flow the const through to all their callers.
>
> But that’s not all – now we need to be able to mark virtual
> methods to declare if the receiver is const or not. And to mark
> return types as const or not.
>
> There’s a pretty massive cost to the user’s mental model and to
> the language as well as producing on-going compatibility problems
> (is adding or removing “const” modifiers binary compatible? Source
> compatible?) for library evolution.
>
> Syntactic sugar to indicate “I won’t write to this” doesn’t really
> pay its way. The costs are quite high.
>
> *From: *Markus Karg <markus at headcrashing.eu>
> *Date: *Wednesday, December 20, 2023 at 5:32 AM
> *To: *'Holo The Sage Wolf' <holo3146 at gmail.com>
> *Cc: *Dan Heidinga <dan.heidinga at oracle.com>, 'Archie Cobbs'
> <archie.cobbs at gmail.com>, 'amber-dev' <amber-dev at openjdk.org>
> *Subject: *[External] : AW: Frozen objects?
>
> C++ ("const") does not freeze the memory region at all, and it
> does not need to (and hence is quite fast at runtime as it does
> not even need to check the access). The compiler simply rejects to
> compile the attempt to write via read-only references. That would
> be sufficient for most cases. Freezing objects is a different
> idea, and only needed in side cases. So I would plea for
> introducing compile-time read-only references first, as it is the
> lower hanging fruit.
>
> -Markus
>
> *Von:*Holo The Sage Wolf [mailto:holo3146 at gmail.com]
> *Gesendet:* Dienstag, 19. Dezember 2023 14:18
> *An:* Markus Karg
> *Cc:* Dan Heidinga; Archie Cobbs; amber-dev
> *Betreff:* Re: Frozen objects?
>
> How do you freeze a memory region without talking about freezing
> objects?
>
> Unless your data is flat (so only value classes, primitives and
> arrays, 2 of which won't benefit from freezing) the only way to
> have freezing something that is enforced at compile time you must
> talk about objects.
>
> On Tue, 19 Dec 2023, 10:04 Markus Karg, <markus at headcrashing.eu
> <mailto:markus at headcrashing.eu>> wrote:
>
> I wonder why we discuss about freezing *objects* (which needs
> time) but not simply freezing *references* (like `const` does
> in C++)?
>
> -Markus
>
> *Von:*amber-dev [mailto:amber-dev-retn at openjdk.org
> <mailto:amber-dev-retn at openjdk.org>] *Im Auftrag von *Dan Heidinga
> *Gesendet:* Montag, 18. Dezember 2023 16:04
> *An:* Archie Cobbs; amber-dev
> *Betreff:* Re: Frozen objects?
>
> Let me throw out one other concern: races. The invariant
> frozen objects want is that the application and runtime can
> trust they will never be mutated again. Unfortunately, if the
> object is published across threads before it is frozen, then
> that invariant is very difficult and expensive to maintain.
>
> If two threads, A & B, both have references to the object and
> thread A freezes it, B may still be publishing writes to it
> that A only observes later. To ensure the right JMM
> happens-before relationship for fields of Freezable objects,
> both reads and writes would need to be more expensive
> (volatile semantics?) until a thread could validate the object
> it was operating on was frozen.
>
> Freezing is not just a free set of unexplored optimizations.
> There’re also new costs associated with it across the runtime
> (field read/write, profiling, etc).
>
> --Dan
>
> *From: *amber-dev <amber-dev-retn at openjdk.org> on behalf of
> Archie Cobbs <archie.cobbs at gmail.com>
> *Date: *Saturday, December 16, 2023 at 12:33 PM
> *To: *amber-dev <amber-dev at openjdk.org>
> *Subject: *Frozen objects?
>
> Caveat: I'm just trying to educate myself on what's been
> discussed in the past, not actually suggest a new language
> feature. I'm sure this kind of idea has been discussed before
> so feel free to point me at some previous thread, etc.
>
> In C we have 'const' which essentially means "the memory
> allocated to this thing is immutable". The nice thing about
> 'const' is that it can apply to an individual variable or
> field in a structure, or it can apply to an entire C structure
> or C array. In effect it applies to any contiguous memory
> region that can be named/identified at the language level.
>
> On the other hand, it's just a language fiction, i.e., it can
> always be defeated at runtime by casting (except for static
> constants).
>
> In Java we have 'final' which (in part) is like 'const' for
> fields and variables, but unlike C 'final' can't be applied to
> larger memory regions like entire objects or entire arrays.
>
> In C, 'const' can be applied "dynamically" in the sense I can
> cast foo to const foo. Of course, this is only enforced at the
> language level.
>
> Summary of differences between C 'const' and Java 'final':
>
> ·Granularity:
>
> oC: Any contiguous memory region that has a language
> name/identification
>
> oJava: At most 64 bits at a time (*) and arrays are not included
>
> oAdvantage: C
>
> ·Enforcement:
>
> oC: Enforced only by the compiler (mostly)
>
> oJava: Enforced by the compiler and at runtime
>
> oAdvantage: Java
>
> ·Dynamic Application:
>
> oC: Yes
>
> oJava: No
>
> oAdvantage: C
>
> (*) With records and value objects we are gradually moving
> towards the ability for larger things than an individual field
> to be 'const'. More generally, Java has slowly been glomming
> on some of the goodness from functional programming, including
> making it easier to declare and work with immutable data.
>
> This all begs the question: why not take this idea to its
> logical conclusion? And while we're at it, make the capability
> fully dynamic, instead of limiting when you can 'freeze'
> something construction time?
>
> In other words, add the ability to "freeze" an object or
> array. If 'x' is frozen, whatever 'x' directly references
> becomes no longer mutable.
>
> A rough sketch...
>
> Add new Freezableinterface:
>
> public interface Freezable {
>
> boolean isFrozen();
>
> static boolean freeze(Freezable obj); // returns false if
> already frozen
>
> }
>
> Arrays automatically implement Freezable(just like they do
> Cloneable)
>
> What about the memory model? Ideally it would work as if
> written like this:
>
> public class Foo implements Freezable {
>
> private volatile frozen; // set to true by Freezable.freeze()
>
> void mutateFooContent(Runnable mutation) {
>
> if (this.frozen)
>
> throw new FrozenObjectException();
>
> else
>
> mutation.run();
>
> }
>
> }
>
> But there could be a better trade-off of performance vs.
> semantics.
>
> Other trade-offs...
>
> ·(-) All mutations to a Freezablewould require a new 'frozen'
> check (* see below)
>
> ·(-) There would have to be a new bit allocated in the object
> header
>
> ·(+) Eliminate zillions of JDK defensive array copies (things
> like String.toCharArray())
>
> ·(+) JIT optimizations for constant-folding, etc.
>
> ·(+) GC optimizations
>
> o(*) Put frozen objects into a read-only region of memory to
> eliminate mutation checks
>
> oOptimize scanning of frozen references (since they never change)
>
> I'm curious how other people think this idea would or wouldn't
> make sense for Java & what's been decided in the past.
>
> Thanks,
>
> -Archie
>
> --
>
> Archie L. Cobbs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20231221/2672d6c1/attachment-0001.htm>
More information about the amber-dev
mailing list