Thanks for spelling that out Brian. I withdraw my earlier +1. 

> On Nov 10, 2019, at 7:36 AM, Brian Goetz <brian.go...@oracle.com> wrote:
> 
> Yes, this is about the fourth time you’ve brought this up...
> 
> I understand your concerns here (as I’ve said before).  We’re not going to do 
> anything about it right now — and I don’t want to discuss it further until 
> after 14 closes.  But, I will put a few points into the record for when that 
> discussion resumes.  
> 
> I understand that it is a little weird that the constructor is public when 
> the class is not.  It is a little weird, but in reality, _it makes no 
> difference_.  Public doesn’t really mean public, it means “public, subject to 
> the public-ness of my containing class, and the exported-ness of my 
> containing package.”  So this is really just a personal-preference argument, 
> that you find this weirdness more weird than the weirdness introduce by the 
> alternate (and more complex) scheme.  
> 
> I also understand that you are making a “for consistency” argument with how 
> default constructors work.  But, there are more moving parts here, so I don’t 
> find the “but default constructors work this way” argument to be compelling 
> in this case.  
> 
> What you’re missing is the accessors.  A record gains a set of mandated 
> members, which must be accessible.  All the talk so far has been about the 
> constructor, but it would be ridiculous to use a different accessibility 
> scheme for the constructor as for the other mandated members.  We would have 
> to have the same treatment for all the mandated members (some of which must 
> be public, as they come from Object.)  
> 
> And here’s why this scheme is not without cost.  Because the accessors and 
> the constructor can be explicitly specified, now we have a more complex rule 
> about what accessibilities are allowed on explicit members (i.e., it should 
> be OK to upgrade from package to public, but not the other way around).  And 
> this is a nontrivial amount of additional spec complexity compared to 
> “they’re always public.”  Further, if one has a package-protected record with 
> explicit members, and one changes the accessibility of the record, one has to 
> change the accessibility of all mandated members.  So while your scheme 
> (assuming it encompasses accessors too) may feel cleaner, it is also more 
> expensive for both the spec and for the users, who have to internalize a more 
> complex rule.  (Yes, its the same as the default constructor, but: _no one 
> knows this rule_, so we can’t really lean on the “but its just like something 
> else they understand.”)  Which is why it is by no means the slam-dunk you 
> seem to think it is, and why have been unwilling to reopen this issue.  
> 
> We can reconsider it after the first preview.  
> 
> 
> 
> 
> 
>> On Nov 9, 2019, at 2:31 PM, Remi Forax <fo...@univ-mlv.fr> wrote:
>> 
>> I  know we already discuss that but i still don't understand why  a 
>> canonical constructor has to be public.
>> 
>> I understand that a canonical constructor is not a simple constructor 
>> because it is also used as a kind of default de-constructor, but this 
>> doesn't work well with the current rules for constructors in nested 
>> classes/enums and if the class is not visible, it's constructor is not 
>> visible anyway.
>> 
>> As Brian said in its presentation at Devoxx, records can be used to 
>> represent local nominal tuples, like
>> 
>> public void foo() {
>>   record Pair(String name, int value);
>>   ...
>> }
>> 
>> If one want to add a requireNonNull using a compact constructor, it will be
>> public void foo() {
>>   record Pair(String name, int value) {
>>     public Pair {
>>       Objects.requireNonNull(name);
>>     }
>>   }
>>   ...
>> }
>> 
>> having to declare the constructor to be public in that case seems weird. 
>> 
>> Mandating that the canonical constructor (hence the compact constructor) to 
>> be public:
>> - goes against the idea of encapsulation that a constructor like any members 
>> should be the least visible
>> - goes against the rules of default constructors (default constructor use 
>> the same visibility as their class) [1]
>> - goes against the rules of constructors in enums (use private or package 
>> private depending on the kind of enums) [2]
>> 
>> So we a set of rules in the JLS that follows the idea that a constructor 
>> should not be public by default in nested classes [1] but the rule for a 
>> canonical constructor doesn't follow the same idea [3], this should be fixed.
>> 
>> In my opinion, the rule for a canonical constructor should be the same as 
>> the rule for a default constructor.
>> 
>> regards,
>> Rémi
>> 
>> 
>> [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9
>> [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2
>> [3] 
>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4
> 

Reply via email to