[records] updates for Preview 6. Default access modes

John Rose john.r.rose at oracle.com
Sun Jan 12 21:16:53 UTC 2020

On Jan 10, 2020, at 2:04 AM, Tagir Valeev <amaembo at gmail.com> wrote:
> I don't like B. The problem with B is that having a public default you
> may mistakenly expose an implementation detail, and it could be hard
> to fix this when clients start to use it. With interface methods this
> is less important, because if you have an implementation inside
> interface, you should explicitly mark it with either 'default'
> (meaning that it's still part of an interface) or 'private' (meaning
> that it's an implementation detail). But specifying an interface
> method with a body without a modifier at all is an error, so you will
> have to think.

That’s true about methods but not about classes.  Like it or not
(and as Brian says we need to avoid the temptation to fix past
sins), if you define a nested class without modifiers, it is public.
And the same is true of fields.  So your point is partly valid
(default *on a method* makes it clear something is not just
package-scope) but I think you are working too hard to avoid
my main point:  Interfaces have the bad feature you say we
want to avoid, which is that (many) declarations that look like
package-scoped are silently promoted to public.

Besides that, “default” doesn’t convey “public”.  In all cases
with members of interfaces, we have schooled ourselves to
watch for the absence of the modifiers to denote “public”
not “package” as in other classes.  The presence of “default”
helps with this, but does not dispense us from the need to
be basically watchful in interface bodies.

(I do want to fix this, as I’ve mentioned.  But it’s a separate
change request.)

Given that reality, and given the fact that we are not going to
“fix” that “sin” of interfaces, I think it is reasonable to propose
that we *benefit* from the design of interfaces in this case,
by transferring the rules to records as well.

> Records are not of this kind.

My point here (which I see is not gaining a lot of ground with
you and Brian, but it’s a point) is that records and interfaces
are of a common kind, a restricted type whose semantics is
required to be (largely) public.  An interface is a public product
of (mainly abstract) behaviors (plus optional defaults), while a
record is a public product of stateless data components.  I claim
it is perfectly reasonable to view them as “of the same kind” and
in particular to reuse whatever rules we have for interfaces for
records, rather than (option C or D) make up new rules.

In fact, although Brian mentioned that proposal B seems to be
fixing sins of the past (a siren song) it’s exactly the opposite case
here:  Proposal B embraces the sins of the past (interface access
defaults to public), while the favored proposals C and D try to
tinker with defaults in new ways, avoiding badly set defaults
from the past.  Which is fixing sins?

If we avoid the siren song of making a new set of (probably wrong)
defaults for records, and embrace the existing rules (imperfect as
they are) then it’s a choice of A or B.  And of those two choices,
I think B is more natural, given the similarities of interface and
records (semantically restricted mostly-public types).

Another advantage of embracing the interface rules is that, if we
want to tweak the rules later on (say, adding a package-private or
non-public modifier, or something like that) the cost of changing the
rules will lead to a larger benefit, for both interfaces and records
(and any other similar constructs that may come along).  If we do
something bespoke for records, different from classes and interfaces,
the risk is that we’ll be unable to justify later fixes to the access
rules, since they will have lower benefit, applying to smaller
proportions of the language.  Keeping things uniform between
records and interfaces (or for that matter records and classes)
means that we can hope to make things more uniformly better
later with features like “non-public”/ “package”/“package-private”.

So, FTR, my order of preference is B, C/D, A.

— John

More information about the amber-spec-experts mailing list