<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 12 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Aptos;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.m7247407421996311182m-2682028665710061497gmailsignatureprefix
        {mso-style-name:m7247407421996311182m-2682028665710061497gmailsignatureprefix;}
span.E-MailFormatvorlage18
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.E-MailFormatvorlage19
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=DE link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>So this discussion is as useless as Dan's request that I shall come back with all the requested answers.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>As apparently that is declared to be a dead end upfront, I hereby reject the idea and I look forward to see the solution provided for frozen objects instead. :-)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>-Markus<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><a name="_MailEndCompose"><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></a></p><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>Von:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Brian Goetz [mailto:brian.goetz@oracle.com] <br><b>Gesendet:</b> Donnerstag, 21. Dezember 2023 17:27<br><b>An:</b> Dan Heidinga; Markus Karg; 'Red IO'<br><b>Cc:</b> 'Holo The Sage Wolf'; 'Archie Cobbs'; 'amber-dev'<br><b>Betreff:</b> Re: [External] : AW: Frozen objects?<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='font-size:13.5pt;font-family:"Courier New"'>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.<br><br><br><o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>So you think frozen objects will be any simpler?</span><span style='font-size:13.5pt;font-family:"Courier New"'><o:p></o:p></span></p><p class=MsoNormal style='margin-bottom:12.0pt'><span style='font-size:13.5pt;font-family:"Courier New"'><br>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.  <br><br>(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.)<br><br>In any case, we are way outside the charter of amber-dev here.  I think best to stop here.  <br><br></span><o:p></o:p></p><div><p class=MsoNormal>On 12/21/2023 11:08 AM, Dan Heidinga wrote:<o:p></o:p></p></div><blockquote style='margin-top:5.0pt;margin-bottom:5.0pt'><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>Not unsolvable but the payoff isn’t there.</span><o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>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.</span><o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>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.</span><o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><div id=mail-editor-reference-message-container><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:36.0pt'><b><span style='font-family:Aptos;color:black'>From: </span></b><span style='font-family:Aptos;color:black'>Markus Karg <a href="mailto:markus@headcrashing.eu"><markus@headcrashing.eu></a><br><b>Date: </b>Thursday, December 21, 2023 at 10:52 AM<br><b>To: </b>'Red IO' <a href="mailto:redio.development@gmail.com"><redio.development@gmail.com></a>, Dan Heidinga <a href="mailto:dan.heidinga@oracle.com"><dan.heidinga@oracle.com></a><br><b>Cc: </b>'Holo The Sage Wolf' <a href="mailto:holo3146@gmail.com"><holo3146@gmail.com></a>, 'Archie Cobbs' <a href="mailto:archie.cobbs@gmail.com"><archie.cobbs@gmail.com></a>, 'amber-dev' <a href="mailto:amber-dev@openjdk.org"><amber-dev@openjdk.org></a><br><b>Subject: </b>AW: [External] : AW: Frozen objects?</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>-Markus</span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='margin-left:36.0pt'><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>Von:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Red IO [<a href="mailto:redio.development@gmail.com">mailto:redio.development@gmail.com</a>] <br><b>Gesendet:</b> Donnerstag, 21. Dezember 2023 16:06<br><b>An:</b> Dan Heidinga<br><b>Cc:</b> Markus Karg; Holo The Sage Wolf; Archie Cobbs; amber-dev<br><b>Betreff:</b> Re: [External] : AW: Frozen objects?</span><o:p></o:p></p></div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p><div><p class=MsoNormal style='margin-left:36.0pt'>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.<o:p></o:p></p><div><p class=MsoNormal style='margin-left:36.0pt'>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. <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>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. <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>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.<o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>In java we currently are stuck with exception throwing views, documentation and defensive copies. <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>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.<o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>Best regards<o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>RedIODev<o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p></div></div><p class=MsoNormal style='margin-left:36.0pt'> <o:p></o:p></p><div><div><p class=MsoNormal style='margin-left:36.0pt'>On Wed, Dec 20, 2023, 17:58 Dan Heidinga <<a href="mailto:dan.heidinga@oracle.com">dan.heidinga@oracle.com</a>> wrote:<o:p></o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt'><div><div><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>Syntactic sugar to indicate “I won’t write to this” doesn’t really pay its way.  The costs are quite high.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> </span><o:p></o:p></p><div id="m_7247407421996311182mail-editor-reference-message-container"><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:72.0pt'><b><span style='font-family:"Arial","sans-serif";color:black'>From: </span></b><span style='font-family:"Arial","sans-serif";color:black'>Markus Karg <<a href="mailto:markus@headcrashing.eu" target="_blank">markus@headcrashing.eu</a>><br><b>Date: </b>Wednesday, December 20, 2023 at 5:32 AM<br><b>To: </b>'Holo The Sage Wolf' <<a href="mailto:holo3146@gmail.com" target="_blank">holo3146@gmail.com</a>><br><b>Cc: </b>Dan Heidinga <<a href="mailto:dan.heidinga@oracle.com" target="_blank">dan.heidinga@oracle.com</a>>, 'Archie Cobbs' <<a href="mailto:archie.cobbs@gmail.com" target="_blank">archie.cobbs@gmail.com</a>>, 'amber-dev' <<a href="mailto:amber-dev@openjdk.org" target="_blank">amber-dev@openjdk.org</a>><br><b>Subject: </b>[External] : AW: Frozen objects?</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>-Markus</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='margin-left:72.0pt'><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>Von:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Holo The Sage Wolf [mailto:<a href="mailto:holo3146@gmail.com" target="_blank">holo3146@gmail.com</a>] <br><b>Gesendet:</b> Dienstag, 19. Dezember 2023 14:18<br><b>An:</b> Markus Karg<br><b>Cc:</b> Dan Heidinga; Archie Cobbs; amber-dev<br><b>Betreff:</b> Re: Frozen objects?</span><o:p></o:p></p></div><p class=MsoNormal style='margin-left:72.0pt'> <o:p></o:p></p><div><div><p class=MsoNormal style='margin-left:72.0pt'>How do you freeze a memory region without talking about freezing objects?<o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:72.0pt'> <o:p></o:p></p></div><div><p class=MsoNormal style='mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:72.0pt'>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.<o:p></o:p></p><div><div><p class=MsoNormal style='margin-left:72.0pt'>On Tue, 19 Dec 2023, 10:04 Markus Karg, <<a href="mailto:markus@headcrashing.eu" target="_blank">markus@headcrashing.eu</a>> wrote:<o:p></o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt'><div><div><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;color:#1F497D'>I wonder why we discuss about freezing *objects* (which needs time) but not simply freezing *references* (like `const` does in C++)?</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;color:#1F497D'>-Markus</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;color:#1F497D'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt;color:#1F497D'> </span><a name="m_7247407421996311182_m_-268202866571006"></a><o:p></o:p></p><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='margin-left:72.0pt'><b><span style='font-family:"Tahoma","sans-serif"'>Von:</span></b><span style='font-family:"Tahoma","sans-serif"'> amber-dev [mailto:</span><a href="mailto:amber-dev-retn@openjdk.org" target="_blank"><span style='font-family:"Tahoma","sans-serif"'>amber-dev-retn@openjdk.org</span></a><span style='font-family:"Tahoma","sans-serif"'>] <b>Im Auftrag von </b>Dan Heidinga<br><b>Gesendet:</b> Montag, 18. Dezember 2023 16:04<br><b>An:</b> Archie Cobbs; amber-dev<br><b>Betreff:</b> Re: Frozen objects?</span><o:p></o:p></p></div></div><p class=MsoNormal style='margin-left:72.0pt'> <o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'>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.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'>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). </span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'>--Dan</span><o:p></o:p></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p><div id="m_7247407421996311182m_-2682028665710061497mail-editor-reference-message-container"><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:108.0pt'><b><span style='color:black'>From: </span></b><span style='color:black'>amber-dev <</span><a href="mailto:amber-dev-retn@openjdk.org" target="_blank">amber-dev-retn@openjdk.org</a><span style='color:black'>> on behalf of Archie Cobbs <</span><a href="mailto:archie.cobbs@gmail.com" target="_blank">archie.cobbs@gmail.com</a><span style='color:black'>><br><b>Date: </b>Saturday, December 16, 2023 at 12:33 PM<br><b>To: </b>amber-dev <</span><a href="mailto:amber-dev@openjdk.org" target="_blank">amber-dev@openjdk.org</a><span style='color:black'>><br><b>Subject: </b>Frozen objects?</span><o:p></o:p></p></div><div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>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.</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>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.</span><o:p></o:p></p></div><div><div><div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>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).</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>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.</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>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.</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>Summary of differences between C 'const' and Java 'final':</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>Granularity:</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>C: Any contiguous memory region that has a language name/identification</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Java: At most 64 bits at a time (*) and arrays are not included</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Advantage: C</span><o:p></o:p></p><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>Enforcement:</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>C: Enforced only by the compiler (mostly)</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Java: Enforced by the compiler and at runtime</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Advantage: Java</span><o:p></o:p></p><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>Dynamic Application:</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>C: Yes</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Java: No</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Advantage: C</span><o:p></o:p></p></div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>(*) 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.</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>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?</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>In other words, add the ability to "freeze" an object or array. If 'x' is frozen, whatever 'x' directly references becomes no longer mutable.</span><o:p></o:p></p></div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>A rough sketch...</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>Add new </span><span style='font-size:11.0pt;font-family:"Courier New"'>Freezable</span><span style='font-size:11.0pt'> interface:</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>    public interface Freezable {</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>        boolean isFrozen();</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>        static boolean freeze(Freezable obj);   // returns false if already frozen</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>    }</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>Arrays automatically implement </span><span style='font-size:11.0pt;font-family:"Courier New"'>Freezable</span><span style='font-size:11.0pt'> (just like they do </span><span style='font-size:11.0pt;font-family:"Courier New"'>Cloneable</span><span style='font-size:11.0pt'>)</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>What about the memory model? Ideally it would work as if written like this:</span><o:p></o:p></p></div></div><div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>    public class Foo implements Freezable {</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>        private volatile frozen;    // set to true by Freezable.freeze()</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>        void mutateFooContent(Runnable mutation) {</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>            if (this.frozen)</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>                throw new FrozenObjectException();</span><o:p></o:p></p></div><div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>            else</span><o:p></o:p></p></div></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>                mutation.run();</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>        }</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt;font-family:"Courier New"'>    }</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>But there could be a better trade-off of performance vs. semantics.</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>Other trade-offs...</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>(-) All mutations to a </span><span style='font-size:11.0pt;font-family:"Courier New"'>Freezable</span><span style='font-size:11.0pt'> would require a new 'frozen' check (* see below)</span><o:p></o:p></p><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>(-) There would have to be a new bit allocated in the object header</span><o:p></o:p></p><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>(+) Eliminate zillions of JDK defensive array copies (things like </span><span style='font-size:11.0pt;font-family:"Courier New"'>String.toCharArray()</span><span style='font-size:11.0pt'>)</span><o:p></o:p></p><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>(+) JIT optimizations for constant-folding, etc.</span><o:p></o:p></p><p class=MsoNormal style='margin-left:144.0pt'><span style='font-family:Symbol'>·</span><span style='font-size:7.0pt'>         </span><span style='font-size:11.0pt'>(+) GC optimizations</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>(*) Put frozen objects into a read-only region of memory to eliminate mutation checks</span><o:p></o:p></p><p class=MsoNormal style='margin-left:180.0pt'><span style='font-family:"Courier New"'>o</span><span style='font-size:7.0pt'>    </span><span style='font-size:11.0pt'>Optimize scanning of frozen references (since they never change)</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>I'm curious how other people think this idea would or wouldn't make sense for Java & what's been decided in the past.</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>Thanks,</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>-Archie</span><o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'> </span><o:p></o:p></p></div><div><div><p class=MsoNormal style='margin-left:108.0pt'><span class=m7247407421996311182m-2682028665710061497gmailsignatureprefix><span style='font-size:11.0pt'>-- </span></span><o:p></o:p></p><div><p class=MsoNormal style='margin-left:108.0pt'><span style='font-size:11.0pt'>Archie L. Cobbs</span><o:p></o:p></p></div></div></div></div></div></div></div></div></blockquote></div></div></div></div></div></div></div></div></blockquote></div></div></div></div></blockquote><p class=MsoNormal><o:p> </o:p></p></div></body></html>