Possible records tweak

Guy Steele guy.steele at oracle.com
Fri Apr 24 18:59:57 UTC 2020



> On Apr 24, 2020, at 2:24 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> I have been reviewing various Stack Overflow and other queries regarding the use of records, and in particular the compact constructor.  
> 
> The compact constructor was intended to support a model where the constructor body minimally mutates the _constructor arguments_ (if they need to be normalized, defaulted, or clamped), which are then automatically committed to the fields on successful exit:
> 
>     record Rational(int num, int denom) { 
>         Rational {
>             int gcd = gcd(num, denom);
>             num /= gcd;
>             denom /= gcd;
>         }
>     }
> 
> However, developers do not seem to be getting this, and they are instead appealing to the old idiom:
> 
>     record Rational(int num, int denom) { 
>         Rational {
>             int gcd = gcd(num, denom);
>             this.num = num / gcd;
>             this.denom = denom / gcd;
>         }
>     }
> 
> . . .
> 
> So, the question I want to ask is: should we simply _ban_ reads and writes to `this.x` in the body of a compact constructor, and let the auto mechanism take care of it, so there is no confusion about mixing initialization modes, the correct idiom, or reading possibly uninitialized fields?  (If we did, we would probabably extend this to `this`-bound fields in the future, should that feature come to pass.)

Not a bad idea, but here are two and a half alternatives we could consider:

(1) Simply ban use of “this” within a compact constructor.  This might seem like overkill, but it is very easy to explain: the keyword “this” is not available in a compact constructor, period.  Because the argument names shadow the field names, you don’t have access to the fields at all in a compact constructor.  If you don’t like it, write a non-compact constructor.

(2) Change the model so that the constructor arguments are committed to the fields _before_ executing the body of a compact constructor, then for each argument and corresponding field use this assignment analysis to possibly take additional action on exit:

	if the argument is definitely not assigned in the body of the compact constructor
		take no action on exit
	else if the corresponding field is definitely not assigned in the body of the compact constructor
		assign the argument to its corresponding field on exit
	else compile-time error

This rule is intended to allow the programmer to use either style safely.

(2a) Same as (2), but apply it on a bulk basis rather than a per-argument basis:

	if all the arguments are definitely not assigned in the body of the compact constructor
		take no action on exit
	else if all the corresponding fields are definitely not assigned in the body of the compact constructor
		assign all the arguments to their corresponding fields on exit
	else compile-time error

This rule would further require the programmer to adopt the same style uniformly for all arguments.


All of these suggestions depend on compile-time analysis to eliminate redundant assignments.

—Guy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200424/9cb6d8db/attachment.htm>


More information about the amber-spec-experts mailing list