<div dir="ltr">Honestly, I don't understand why you propose this, for synchronized is ALREADY the default behavior of Value Classes per JEP 401. By default, all fields in a value class are synchronized (non-atomic), so you won't see a Range where min > max. The current proposed syntax asks users to opt-in into non-atomic (or non-synchronized in your words) for being non-atomic is bug-prone.<div><br></div><div>Chen Liang</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 25, 2023 at 5:01 PM João Mendonça <<a href="mailto:jf.mend@gmail.com">jf.mend@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-family:verdana,sans-serif;color:rgb(7,55,99)" class="gmail_default"><font size="4"><span style="font-family:monospace"></span></font></div><div dir="ltr"><div class="gmail_default" style="color:rgb(7,55,99)"><font style="font-family:monospace" size="4">Hello Chen,</font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4"><br></font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4"><br></font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4">Thank you very much for your response.</font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4">To address the fragility issue you raised, I would modify the new syntax proposal to:</font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4"><br></font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4">*** synchronized blocks in value class field declarations. ***</font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4"><br></font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4">To your very good point on granularity, I think that synchronized blocks could still be considered more readable than having to segregate fields in separate value classes and using some other class modifier/keyword to indicate non-atomicity.</font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4">All the other advantages/disadvantages would remain the same.<br></font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4">Your example would become:</font></div><div class="gmail_default"><font style="color:rgb(7,55,99);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="color:rgb(7,55,99)"><font style="font-family:monospace" size="4"><span class="gmail_default"></span>value class Container {</font><div><font style="font-family:monospace" size="4">    synchronized {int a, b;}</font></div><div><font style="font-family:monospace" size="4">    int c;</font></div><div><font style="font-family:monospace" size="4">    Container(int a, int b, int c) {</font></div><div><font style="font-family:monospace" size="4">         this.a = a;</font></div><div><font style="font-family:monospace" size="4">         this.b = b;<br></font></div><div><font style="font-family:monospace" size="4">         this.c = c;</font></div><div><font style="font-family:monospace" size="4">    }</font></div><div><font style="font-family:monospace" size="4">}</font></div></div></div><div dir="ltr"><div style="color:rgb(7,55,99)"><font style="font-family:monospace" size="4"><br></font></div><div style="color:rgb(7,55,99)"><font style="font-family:monospace" size="4"><br></font></div><div style="color:rgb(7,55,99)" class="gmail_default"><font style="font-family:monospace" size="4">João Mendonça</font><span style="font-family:monospace"><br></span></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 25, 2023 at 2:08 AM - <<a href="mailto:liangchenblue@gmail.com" target="_blank"><span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span>liangchenblue@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello Joao,<div>I believe the synchronized block proposal is fragile and isn't a good hint to the VM. Each constructor can declare its own synchronization groups, which makes behaviorally-correct optimization harder.</div><div>For your purpose where you only need to declare some of the properties of the value class atomically together, you can group those properties in an atomic (regular) value class. Then, you can include these regular value classes in a non-atomic value class.</div><div><br></div><div>Say you have this:</div><div><span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span>value class Container {</div><div>    int a, b, c;</div><div>    Container(int a, int b, int c) {</div><div>         synchronized { this.a = a; this.b = b; }</div><div>         this.c = c;</div><div>    }</div><div>}</div><div><br></div><div>Why not this instead:</div><div>nonatomic value class Container {</div><div>    value class Constraint {</div><div>        int a, b;</div><div>        Constraint(int a, int b) { this.a = a; this.b = b; }</div><div>    }</div><div>    Constraint ab; int c;</div><div><div>    Container(int a, int b, int c) {</div><div>         this.ab = new Constraint(a, b);</div><div>         this.c = c;</div><div>    }</div></div><div>}</div><div><br></div><div>Chen Liang</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 25, 2023 at 8:58 AM João Mendonça <<a href="mailto:jf.mend@gmail.com" target="_blank">jf.mend@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default"></span>I would like to propose a new syntax to specify that, in a value class, some fields must be assigned atomically together:</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">*** synchronized blocks in value class constructors. ***<br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">Advantages:</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">granularity - only the specific fields involved in an invariant need to be assigned in the same synchronized block. Multiple blocks can be used for independent invariants. Tearing is allowed between blocks and between fields assigned outside blocks. VMs could take advantage of this to perform optimizations.</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">economy - no new keyword/annotation/interface needed.</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">compatibility -</font><font style="color:rgb(11,83,148);font-family:monospace" size="4"> synchronized blocks are currently illegal in constructors.</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">safety - just like with identity classes, the absence of a synchronized block in a constructor means that the whole constructor is synchronized, i.e. all fields are written atomically.</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">safety - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">an empty synchronized block is required to indicate that tearing is allowed between any fields.</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">clarity - "A synchronized block of field assignments" is a very intuitive description of the semantics involved, given the meaning of the word "synchronized" in english.</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">Disadvantages:</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">aesthetics - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">an empty synchronized block is required to indicate that tearing is allowed between any fields.</font><div><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - safety - a user of a value class has no automatic way to be informed of if/where tearing may occur (can be fixed with</font><font style="color:rgb(11,83,148);font-family:monospace" size="4"> an update to the generation of java docs).</font></div></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">clarity - synchronized blocks </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">(§14.18.) have two meanings:</font><font style="color:rgb(11,83,148);font-family:monospace" size="4"></font><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">     </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">   - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">The old meaning in regular methods: only one thread may be running inside of a block for the object given in the expression clause</font></div></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">        - The new meaning i</font><font style="color:rgb(11,83,148);font-family:monospace" size="4">n constructors: all assignments in a block are written atomically </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">(no expression clause)</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">Example:</font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div style="text-align:left"><pre><font style="color:rgb(11,83,148)" size="4"><code>    </code><code>value class Range {
    </code><code>    long</code><code> start, end;
</code><code>    </code><code>    </code><code>
    </code><code>    </code><code>public Range(</code><code>long</code><code> start, </code><code>long</code><code> end) {
        </code><code>    </code><code>if (start > end) throw new IllegalArgumentException();<br></code><code>        </code><code>    </code><code>synchronized {</code><code>
            </code><code>    </code><code>this.start = start;
            </code><code>    </code><code>this.end = end;<br></code><code>        </code><code>    </code><code>}</code><code>
    </code><code>    </code><code>}
</code><code>    </code><code>}<br><br></code></font></pre><pre><font style="color:rgb(11,83,148)" size="4"><code>Having all fields assigned in the same synchronized block, as above, is equivalent to declaring no synchronized blocks:<br><br></code><code>    </code><code>value class Range {
    </code><code>    </code><code>long</code><code> start, end;
    </code><code>    </code><code>
    </code><code>    </code><code>public Range(</code><code>long</code><code> start, </code><code>long</code><code> end) {
        </code><code>    </code><code>if (start > end) throw new IllegalArgumentException();</code><code>
        </code><code>    </code><code>this.start = start;
        </code><code>    </code><code>this.end = end;</code><code>
    </code><code>    </code><code>}
</code><code>    </code><code>}</code></font></pre><pre><font style="color:rgb(11,83,148)" size="4"><code><br>Another example:<br><br></code><code></code><code>    </code><code>value class Point {
    </code><code>    </code><code>double x,</code><code> y;
    </code><code>    </code><code>
</code><code>    </code><code>    public Point(double x, double y) {<br>    </code><code>    </code><code>    synchronized {}
        </code><code>    </code><code>this.x = x;
</code><code>    </code><code>        this.y = y;
    </code><code>    </code><code>}
</code><code>    </code><code>}</code></font></pre></div><br><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default"><br></span></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default">João Mendonça<br></span></font></div><div style="text-align:left"><div><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default"></span></font></div></div>
</blockquote></div>
</blockquote></div>
</div><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 25, 2023 at 2:08 AM - <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello Joao,<div>I believe the synchronized block proposal is fragile and isn't a good hint to the VM. Each constructor can declare its own synchronization groups, which makes behaviorally-correct optimization harder.</div><div>For your purpose where you only need to declare some of the properties of the value class atomically together, you can group those properties in an atomic (regular) value class. Then, you can include these regular value classes in a non-atomic value class.</div><div><br></div><div>Say you have this:</div><div>value class Container {</div><div>    int a, b, c;</div><div>    Container(int a, int b, int c) {</div><div>         synchronized { this.a = a; this.b = b; }</div><div>         this.c = c;</div><div>    }</div><div>}</div><div><br></div><div>Why not this instead:</div><div>nonatomic value class Container {</div><div>    value class Constraint {</div><div>        int a, b;</div><div>        Constraint(int a, int b) { this.a = a; this.b = b; }</div><div>    }</div><div>    Constraint ab; int c;</div><div><div>    Container(int a, int b, int c) {</div><div>         this.ab = new Constraint(a, b);</div><div>         this.c = c;</div><div>    }</div></div><div>}</div><div><br></div><div>Chen Liang</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 25, 2023 at 8:58 AM João Mendonça <<a href="mailto:jf.mend@gmail.com" target="_blank">jf.mend@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default"></span>I would like to propose a new syntax to specify that, in a value class, some fields must be assigned atomically together:</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">*** synchronized blocks in value class constructors. ***<br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">Advantages:</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">granularity - only the specific fields involved in an invariant need to be assigned in the same synchronized block. Multiple blocks can be used for independent invariants. Tearing is allowed between blocks and between fields assigned outside blocks. VMs could take advantage of this to perform optimizations.</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">economy - no new keyword/annotation/interface needed.</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">compatibility -</font><font style="color:rgb(11,83,148);font-family:monospace" size="4"> synchronized blocks are currently illegal in constructors.</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">safety - just like with identity classes, the absence of a synchronized block in a constructor means that the whole constructor is synchronized, i.e. all fields are written atomically.</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">safety - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">an empty synchronized block is required to indicate that tearing is allowed between any fields.</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">clarity - "A synchronized block of field assignments" is a very intuitive description of the semantics involved, given the meaning of the word "synchronized" in english.</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">Disadvantages:</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">aesthetics - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">an empty synchronized block is required to indicate that tearing is allowed between any fields.</font><div class="gmail_default"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - safety - a user of a value class has no automatic way to be informed of if/where tearing may occur (can be fixed with</font><font style="color:rgb(11,83,148);font-family:monospace" size="4"> an update to the generation of java docs).</font></div></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">    - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">clarity - synchronized blocks </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">(§14.18.) have two meanings:</font><font style="color:rgb(11,83,148);font-family:monospace" size="4"></font><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">     </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">   - </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">The old meaning in regular methods: only one thread may be running inside of a block for the object given in the expression clause</font></div></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">        - The new meaning i</font><font style="color:rgb(11,83,148);font-family:monospace" size="4">n constructors: all assignments in a block are written atomically </font><font style="color:rgb(11,83,148);font-family:monospace" size="4">(no expression clause)</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4">Example:</font></div><div class="gmail_default" style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div><div class="gmail_default" style="text-align:left"><pre><font style="color:rgb(11,83,148)" size="4"><code>    </code><code>value class Range {
    </code><code>    long</code><code> start, end;
</code><code>    </code><code>    </code><code>
    </code><code>    </code><code>public Range(</code><code>long</code><code> start, </code><code>long</code><code> end) {
        </code><code>    </code><code>if (start > end) throw new IllegalArgumentException();<br></code><code>        </code><code>    </code><code>synchronized {</code><code>
            </code><code>    </code><code>this.start = start;
            </code><code>    </code><code>this.end = end;<br></code><code>        </code><code>    </code><code>}</code><code>
    </code><code>    </code><code>}
</code><code>    </code><code>}<br><br></code></font></pre><pre><font style="color:rgb(11,83,148)" size="4"><code>Having all fields assigned in the same synchronized block, as above, is equivalent to declaring no synchronized blocks:<br><br></code><code>    </code><code>value class Range {
    </code><code>    </code><code>long</code><code> start, end;
    </code><code>    </code><code>
    </code><code>    </code><code>public Range(</code><code>long</code><code> start, </code><code>long</code><code> end) {
        </code><code>    </code><code>if (start > end) throw new IllegalArgumentException();</code><code>
        </code><code>    </code><code>this.start = start;
        </code><code>    </code><code>this.end = end;</code><code>
    </code><code>    </code><code>}
</code><code>    </code><code>}</code></font></pre><pre><font style="color:rgb(11,83,148)" size="4"><code><br>Another example:<br><br></code><code></code><code>    </code><code>value class Point {
    </code><code>    </code><code>double x,</code><code> y;
    </code><code>    </code><code>
</code><code>    </code><code>    public Point(double x, double y) {<br>    </code><code>    </code><code>    synchronized {}
        </code><code>    </code><code>this.x = x;
</code><code>    </code><code>        this.y = y;
    </code><code>    </code><code>}
</code><code>    </code><code>}</code></font></pre></div><br><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default"><br></span></font></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default">João Mendonça<br></span></font></div><div style="text-align:left"><div><font style="color:rgb(11,83,148);font-family:monospace" size="4"><br></font></div></div><div style="text-align:left"><font style="color:rgb(11,83,148);font-family:monospace" size="4"><span class="gmail_default"></span></font></div></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>