[records] Non-compact canonical constructors
Tagir Valeev
amaembo at gmail.com
Mon Nov 11 04:07:51 UTC 2019
Hello!
> > Several points are unclear to me
> > 1. It's not explicitly specified whether an explicitly declared
> > canonical constructor must be 'public' like it's specified for compact
> > constructors. Does this mean that I can declare non-public canonical
> > constructor?
>
> The compact constructor _is_ a canonical constructor; its just an alternate notation for it, and its an error to declare it both ways (because its an error to declare the same member twice). The canonical constructor should be public (yes, Remi, we see you there), whether declared implicitly, explicitly with a full argument list, or explicitly with a compact ctor.
Sure, this sounds consistent. I'm just saying that this part of the
current spec draft is incomplete. It says that implicit canonical ctor
is public; it says that compact ctor must be public but it says
nothing about explicit canonical ctor. And it's not evident that it
must be the same as in the implicit declaration (e.g. implicit default
ctor has the same access level as the class, but explicit one is
allowed to have the different one). Also, compact constructor rules
should not be taken into account for the explicit canonical
constructor: the compact constructor is a partial case, so it could be
more restrictive. My suggestion is to write this explicitly in 8.10.4:
If the canonical constructor is explicitly declared, then it must
satisfy the following; otherwise a compile-time error occurs:
- The canonical constructor must be declared public.
...
> > 2. I see the restriction for not having a return statement quite
> > arbitrary. I understand it for compact constructors but see no reason
> > for this restriction in non-compact canonical constructors. Could
> > anybody provide a rationale behind this restriction? Sorry if it was
> > discussed; in this case, links to the discussion would also be
> > appreciated.
>
> Yes, it exists primarily for compact constructors and could be refined to mention only those.
Great.
> > 3. As it's already mentioned in 8.10.3, each record component implies
> > an implicitly declared private final field. And as 8.3.1.2 [2] says,
> > "A blank final instance variable must be definitely assigned and
> > moreover not definitely unassigned at the end of every constructor of
> > the class in which it is declared". Thus "Every field corresponding to
> > a record component of R must be definitely assigned and moreover not
> > definitely unassigned..." part seems redundant as it's covered by
> > normal constructor rules. Probably it's not harmful to specify this
> > explicitly though.
>
> Agreed. Ordinary DA should cover this, though its reasonable to remind the reader that DA applies to implicitly declared final fields too.
>
So to summarize, my suggestion is to reformulate this part of 8.10.4,
as follows:
If the canonical constructor is explicitly declared, then it must
satisfy the following; otherwise a compile-time error occurs:
- The canonical constructor must be declared public.
- The body of a canonical constructor must not contain an explicit
constructor invocation statement (8.8.7.1).
- Every field corresponding to a record component of R must be
definitely assigned and
moreover not definitely unassigned (16.9) at the end of the canonical
constructor. // or probably remove this item
- All the other rules for a constructor in a normal class declaration
must be satisfied (8.8).
And for compact constructor (8.10.5):
A compact constructor declaration must satisfy all of the following
conditions; otherwise a compile-time error occurs.
- The compact constructor must be declared public.
- The body of a compact constructor must not contain an explicit
constructor invocation statement (8.8.7.1).
- The body of a compact constructor must not contain a return statement (14.17).
- All the other rules for a constructor in a normal class declaration
must be satisfied (8.8).
With best regards,
Tagir Valeev.
More information about the amber-spec-experts
mailing list