[records] updates for Preview 6. Default access modes

Brian Goetz brian.goetz at oracle.com
Fri Jan 10 16:38:46 UTC 2020

As with the previous mail, this is one of those where we have to trade 
off between what is ideal for the purpose and not introducing gratuitous 
new variations between similar looking entities, which add to the 
developer's complexity load and create migration challenges.

We've already discussed making the default accessibility for mandated 
members match that of the class, rather than "public." What you're 
asking for is: when someone explicitly specifies a mandated member, they 
not have to say the access modifier.

I sympathize, but I think this would be a mistake.  First, the idea is 
that most of the time, you don't have to explicitly specify the mandated 
members.  But more importantly, this is a string that you can pull on 
arbitrarily long.  Suppose the default accessibility for explicit 
mandated members were the "right thing" (either public, or matching the 
class -- the difference is purely aesthetic.)  Now there's a gap between 
these members and others, that sucks.  So suppose all members had that 
access mode by default (as you propose in B).  This at least has the 
benefit that it is like interfaces, rather than a new thing, but ... 
interfaces cannot use certain accessibilities (no protected, no private 
fields or member classes), so its not exactly the same.  But more 
importantly, this creates (a) friction between records and classes (I 
disagree that records are more like interfaces -- and more importantly, 
I think most users will think of them as compact classes), and (b) 
migration friction.  All to save a few "publics" -- but only a 
vanishingly small percentage of the publics in a typical code base.

I think we're back in the "aha, a chance to fix mistakes of the past" trap.

On 1/10/2020 1:40 AM, John Rose wrote:
> 6. Default access modes in records.  (See above. )
> I specifically want to make sure we are doing the best thing on
> access defaults (what happens when you don’t mention *any*
> access mode).  I suppose that’s a separate item, related to this
> one.  Even though we have a decision of record on this, I’m
> calling it out here and now because we are stuck with the final
> decision we make this time around.  (Maybe like a mandatory
> appeal for a capital case.)
> Choices:  A. Package scope like classes, B. public like interfaces,
> C,D,… something new for records.
> A. Records are concise classes which represent a state vector
> of components, plus optional additional behavior.  If a record
> member is declared with no access mode, it is given the package
> access mode.  Just like classes.  The word “public” must be
> reaffirmed for every API in the record; just like classes, the
> presumption is that API points should be private by default,
> and only made public via explicit mark-up.
> B. Records are state vectors of components, plus optional
> additional behavior.  They are not general classes, but rather
> constrained types, much like interfaces are behavior vectors
> of abstract API points, plus optional behavior.  If a record
> member is declared with no access mode, it is given the
> public access mode.  Just like an interface, a record is a
> restricted type, whose contracts with the outside world
> are mainly public, and which has a limited capacity for
> non-public contracts.
> C. Records are state vectors of components, plus optional
> additional behavior.  The parts of their API which are
> intended to be mostly public are public by default, at least
> if the record type as a whole is public.  The precedent for
> this variability is the implicit empty nullary constructor
> supplied to every class, whose access mode is copied
> from the class itself.  The parts of a record API that are
> expected to be public are the factory (canonical constructor)
> and the accessors (component projection methods).
> So those guys are public by default (if the record is public).
> (If the record isn’t public those other guys are the same.)
> At present I prefer “B”, because I now think that, regarding
> the access expectiations of API points, records are *far more
> similar to interfaces* than they are to random run of the mill
> classes.  We started with random classes, but after applying
> enough constraints we now have API elements which are
> closely analogous to interfaces:  Bundles of state, bundles
> of operations.  And, for wide use; i.e. few or no secrets.
> In both cases, “public” is the sane default.
> An advantage of “B” is there’s nothing new to teach. “You
> know how interfaces have their own default access?  Well,
> records use the same rules.”
> — John

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200110/4e258192/attachment-0001.htm>

More information about the amber-spec-experts mailing list