<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"Per-Ake Minborg" <per-ake.minborg@oracle.com><br><b>To: </b>"-" <liangchenblue@gmail.com><br><b>Cc: </b>"Maurizio Cimadamore" <maurizio.cimadamore@oracle.com>, "Per Minborg" <pminborg@openjdk.org>, "leyden-dev" <leyden-dev@openjdk.org><br><b>Sent: </b>Wednesday, August 30, 2023 3:22:17 PM<br><b>Subject: </b>Re: Computed Constants API question<br></blockquote></div><div><style style="display:none;"> P {margin-top:0;margin-bottom:0;} </style></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">


<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Hi Chen,</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
We are looking into splitting up the auxiliary field into two separate fields. One final field for the supplier and another field for the holding of CC's state (e.g. if it was evaluated to null, a non-null value etc.).</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
This will make the CC objects a bit larger but will provide several other benefits including simplifying the code and improving performance.</div></blockquote><div><br></div><div>Yes, it seems a better implementation, the CC object is only larger in case of an exception (if you keep that exception).<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Best, Per</div></blockquote><div><br></div><div>regards,<br data-mce-bogus="1"></div><div>Rémi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">

<hr style="display:inline-block;width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> liangchenblue@gmail.com <liangchenblue@gmail.com><br><b>Sent:</b> Monday, August 28, 2023 3:37 PM<br><b>To:</b> Per-Ake Minborg <per-ake.minborg@oracle.com><br><b>Cc:</b> Maurizio Cimadamore <maurizio.cimadamore@oracle.com>; Per Minborg <pminborg@openjdk.org>; leyden-dev@openjdk.org <leyden-dev@openjdk.org><br><b>Subject:</b> Re: Computed Constants API question</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div dir="ltr"><br>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Mon, Aug 28, 2023 at 6:30 PM Per-Ake Minborg <<a href="mailto:per-ake.minborg@oracle.com" target="_blank">per-ake.minborg@oracle.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div class="x_msg2272718210378170326">
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hi Chen,</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Thanks for trying ComputedConstants!</div>
</div>
</div>
</blockquote>
<div>I'm more than glad to. We finally are able to enjoy constant-folding for array-like structures before frozen arrays arrive :) </div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div class="x_msg2272718210378170326">
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
On top of Maurizio's answers, it should be noted that we have experimented with an array similar to your suggestion early in the prototype phase </div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
and, unfortunately, the solution became slow and had a larger footprint. Such solutions must create and hold an individual lambda</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
for each element and both the elements and the lambdas must be calculated eagerly. <br>
</div>
</div>
</div>
</blockquote>
<div>What if "<span style="font-family:arial,sans-serif">of(() -> provider.apply(t))</span>" was changed to "ListElementComputedConstant.create(i, provider)"? Does creating the CC without creating a lambda instance incur a huge performance overhead as well?
 Guess I will take time and try locally with the existing benchmarks.</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div class="x_msg2272718210378170326">
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
With the on-demand approach, startup times and footprint requirements were significantly better.<br>
<br>
We also have a similar approach for maps that we are experimenting with. This would provide an on-demand map that is eligible for constant folding optimizations. </div>
</div>
</div>
</blockquote>
<div>The on-demand map is definitely better than a non-on-demand one; it has 2 major advantages that merit its inclusion in the API now:</div>
<div>1. The implementation is less likely to be accidentally non-constant-foldable;</div>
<div>2. It will be otherwise difficult for users to implement a on-demand CC map (where each CC is on-demand) </div>
<div><br>
</div>
<div>The implementation itself won't be hard; we can create another subclass that uses a Function as a provider.</div>
<div><br>
</div>
<div>In addition, I doubt the volatile write to the provider (auxiliary) [1] suffices: according to Aleksey Shipilyov [2], since AbstractComputedConstant has no final fields, the auxiliary field might be null in a volatile read even if the constructor has returned.
 Can you explain how this is safe, and if read/write volatile in VarHandle differs from that in regular volatile fields?</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div class="x_msg2272718210378170326">
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I think this concept would be great for general lazy calculation but when and if it can make its way into the JEP is unsure.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Best, Per</div>
</div>
</div>
</blockquote>
<div>No worries. We can always try out, and preview allows us sufficient usage to test out our new APIs.</div>
<div> </div>
<div>Cheers,</div>
<div>Chen</div>
<div><br>
</div>
<div>[1] <a href="https://github.com/openjdk/leyden/blob/591689ed312977bbd6f99484d3c92e6a12aed9b3/src/java.base/share/classes/jdk/internal/constant/AbstractComputedConstant.java#L74" target="_blank">https://github.com/openjdk/leyden/blob/591689ed312977bbd6f99484d3c92e6a12aed9b3/src/java.base/share/classes/jdk/internal/constant/AbstractComputedConstant.java#L74</a><br data-mce-bogus="1"></div>
<div>[2] <a href="https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-volatiles-are-finals" target="_blank">https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-volatiles-are-finals</a><br data-mce-bogus="1"></div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div class="x_msg2272718210378170326">
<div dir="ltr">

<hr style="display:inline-block; width:98%">
<div id="x_m_2272718210378170326divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b><a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a> <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>><br><b>Sent:</b> Monday, August 28, 2023 12:08 PM<br><b>To:</b> Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank">maurizio.cimadamore@oracle.com</a>><br><b>Cc:</b> Per Minborg <<a href="mailto:pminborg@openjdk.org" target="_blank">pminborg@openjdk.org</a>>;
<a href="mailto:leyden-dev@openjdk.org" target="_blank">leyden-dev@openjdk.org</a> <<a href="mailto:leyden-dev@openjdk.org" target="_blank">leyden-dev@openjdk.org</a>><br><b>Subject:</b> Re: Computed Constants API question</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div dir="ltr"><font face="arial, sans-serif">Thanks Maurizio,</font>
<div><font face="arial, sans-serif">This late condensation does explain the peculiarities in the OnDemandComputedConstantList. And I think not providing a List<V> factory is fine, despite the usage complexities: we still need to track the computation state
 for each element, so having a CC wrapper over each element isn't too bad.</font></div>
<div><font face="arial, sans-serif"><br></font></div>
<div><font face="arial, sans-serif">I think the OnDemandComputedConstantList implementation is unnecessary; we can just create an array of non-null ComputedConstant elements like:</font></div>
<div><font face="arial, sans-serif"><br></font></div>
<div><font face="arial, sans-serif">ComputedConstant<T>[] array = new ComputedConstant<?>[size]; // unchecked</font></div>
<div><font face="arial, sans-serif">for (int i = 0; i < size; i++) {</font></div>
<div><font face="arial, sans-serif">    final int t = i;</font></div>
<div><font face="arial, sans-serif">    array[i] = of(() -> provider.apply(t));</font></div>
<div><font face="arial, sans-serif">}</font></div>
<div><font face="arial, sans-serif">return JUCA.listFromTrustedArray(array);</font></div>
<div><font face="arial, sans-serif"><br></font></div>
<div><font face="arial, sans-serif">Users can use Map.ofEntries to create a Map<K, CC<V>>, but since people might use other types of maps that aren't eligible for Constant-folding, I would recommend providing an official API as well to avoid user errors.</font></div>
<div>
<pre style="color:rgb(0,0,0)"><font face="arial, sans-serif">The interloping from List<CC<V>> to List<V> (and also that for Maps) can be implemented by users if needed. It shouldn't be too much of a problem, I would assume.</font></pre>
</div>
<div><font face="arial, sans-serif">Chen Liang</font></div>
</div>
<font face="arial, sans-serif"><br></font>
<div>
<div dir="ltr"><font face="arial, sans-serif">On Mon, Aug 28, 2023 at 5:29 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank">maurizio.cimadamore@oracle.com</a>> wrote:<br></font></div>
<blockquote style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<font face="arial, sans-serif">Hi,<br>
I believe the issues you see in the JEP reflect the fact that the API <br>
went through a stage of "late condensation" - we used to <br>
ComputedConstant and ComputedList, but the latter has now turned into <br>
just a factory on the former. I think the factory provided is the more <br>
general (as it allows for different resolution policies).<br><br>
If I recall correctly, the decision _not_ to provide a List<V> factory <br>
is motivated by the fact that we would have to respecify that List::get <br>
is associated with the same behavior as ComputedConstant::get. That is, <br>
that list can act in very weird ways, throw novel exceptions, etc. For <br>
these reasons we preferred to make the CC-nature of the list apparent in <br>
its generic type, rather than introducing some magic list wrapper which <br>
adds its own special behavior (see Collections::unmodifiableList).<br><br>
Now, with that said, I can see this going both ways - while List<CC> is <br>
a more explicit and "honest" representation - what you say re. interop <br>
with clients accepting just a List<V> is also a valid point (and you <br>
can't fully get to a List<V> just by using a Steam mapper, as the <br>
terminal operation `asList` would force eager computation of all the <br>
constants).<br><br>
Maurizio<br><br>
On 28/08/2023 09:31, - wrote:<br>
> Hello Per and Leyden subscribers,<br>
> First, I am glad that we are finally adding an API that exposes one of <br>
> core libraries' favorite feature, `@Stable`, to common users!<br>
><br>
> For the API design, however, I have a request: Can we have a <br>
> ComputedConstant factory that creates a List<V> in addition to one <br>
> that creates a List<ComputedConstant<V>>?<br>
><br>
> I think using the List<ComputedConstant<V>> is confusing. The example <br>
> usages in the JEP [1] and in the API specification [2] are already <br>
> wrong: we need an extra ConputedConstant.get() call to unwrap the <br>
> ComputedConstant after List.get(index) call, which currently returns a <br>
> computed constant than the actual value.<br>
><br>
> The current List<ComputedConstant<V>> is to be kept in case users want <br>
> fine-grained control over each constant's resolution failure, etc. and <br>
> covers the new factory's functionality. But I believe the new factory <br>
> will see wider usage:<br>
><br>
> 1. None of the 2 old patterns in the "Motivation" section uses any of <br>
> these exception handling or initialization state detection.<br>
> 2. Returning a List<V> allows users to conveniently pass the list in <br>
> usages instead of using streams or writing custom wrappers.<br>
><br>
> A follow up to a previous request [3], I believe having a map (of type <br>
> Map<K, V> instead of Map<K, ComputedConstant<V>>) would be feasible too.<br>
><br>
> Finally, a side comment about the current <br>
> OnDemandComputedConstantList: it computes ComputedConstant wrappers in <br>
> addition to the actual constants on demand, which... seems a bit <br>
> overkill, when ComputedConstant itself is already a lightweight <br>
> wrapper of a heavy computation?<br>
><br>
> Best,<br>
> Chen Liang<br>
><br>
> [1]: <a href="https://openjdk.org/jeps/8312611" rel="noreferrer" target="_blank">
https://openjdk.org/jeps/8312611</a>  "var kbd = lbl.labels.get(3);"<br>
> [2]: <br>
> <a href="https://cr.openjdk.org/~pminborg/computed-constant/api/java.base/java/lang/ComputedConstant.html#of(int,java.util.function.IntFunction)" rel="noreferrer" target="_blank">
https://cr.openjdk.org/~pminborg/computed-constant/api/java.base/java/lang/ComputedConstant.html#of(int,java.util.function.IntFunction)</a><br>
>  "return PO2_CACHE.get(n);"<br>
> [3]: <a href="https://mail.openjdk.org/pipermail/leyden-dev/2023-August/000277.html" rel="noreferrer" target="_blank">
https://mail.openjdk.org/pipermail/leyden-dev/2023-August/000277.html</a></font><br>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div><br></blockquote></div></div></body></html>