> On Oct 16, 2016, at 8:19 PM, David Waite <da...@alkaline-solutions.com> wrote:
> fileprivate (and internal, in a sense) are really in the “friend” camp. 
> Rather than declaring particular types are friends, these require code 
> locality - in the same file in the case of fileprivate, in the same module in 
> the case of internal.
> This does mean that the more stringent you wish to control internals, the 
> more code gets stuffed into a file or module - but could actually be 
> considered a benefit, as depending on internals naturally makes code highly 
> coupled.
> That reason is why I’m not exactly fan of expanding ‘friend’-style 
> permissions further - this could completely disguise the level of effort 
> needed to change ‘hidden’ code in one class.

I think that is a valid point.  There is a tradeoff.  Being able to spread an 
API over more files means that there are more files to change when you need to 
make a change (and there is always a chance that you forget a file).  My 
argument would be that this allows the author to choose the tradeoff for 
themselves in each situation, whereas right now the choice is being made for 

> I’m against allowing hidden cross-module. If external code is explicitly 
> allowed to depend on ‘hidden’ API, then its still API which would be expected 
> to be stably maintained. Why not just make it public with appropriate caveats?

Yes, I think it would be expected to be stably maintained… but any sort of 
protected-style access is going to be the same, as you need a stable API to 
build subclasses/extensions on.  There are several reasons for encapsulation 
beyond making it easier to update API.  My main reason for wanting this is to 
be able to hide the levers which could get things into an inconsistent state 
internally, while still allowing for the few cases where that access is needed 
for efficient implementation.  Safe by default, with override.

I do suppose, at the expense of a little more complexity, we could make 
‘hidden' a separate axis of control.  That is, you could have ‘public hidden’, 
‘internal hidden’, and ‘private hidden’, with private hidden being exactly the 
same as today’s fileprivate (C# has protected internal, etc… so it isn’t 
unprecedented). That way, an author could choose the tradeoff between 
maintenance burden and extensibility.


> -DW
>> On Oct 16, 2016, at 2:34 PM, Jonathan Hull via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> I keep wanting a “protected” access level, but I must also admit that there 
>> was something really elegant about Swift 2’s access scheme (and I think most 
>> of us feel like the word ‘fileprivate’ feels out of place).  I was thinking 
>> about how to mesh those two ideas, and I think I may have come up with a 
>> solution.
>> I propose we replace ‘fileprivate’ with a new ‘hidden’ access level.  Hidden 
>> would work exactly the same way as fileprivate does now, but adds the 
>> connotation that what is hidden can also be unhidden.  By adding ‘import 
>> hidden TypeName’ to another file, that file also gains access to all of the 
>> hidden items of that type (kind of like if it was in the same file).
>> #FileA       
>>      import Foundation
>>      Struct A {
>>              private var x:Int
>>              hidden var y:Int  //This is just like fileprivate, but can also 
>> be shared with other files
>>      }
>>      extension A {
>>              //y can be accessed here because they are in the same file
>>      }
>> #FileB
>>      import Foundation
>>      import hidden A  //This allows the entire file to see A’s hidden 
>> variables
>>      extension A {
>>              //y can be accessed here because of the ‘import hidden’ 
>> declaration
>>      }
>> #FileC
>>      import Foundation
>>      extension A {
>>              //y can NOT be seen or accessed here because it is hidden
>>      }
>> I think this is a fairly elegant solution to our protected dilemma, which 
>> also feels in sync with Swift 2’s file-based scheme.  The key features:
>>      • Extensions no longer need to be piled in the same file if it is 
>> getting too long
>>      • Subclasses can be in their own file, but still have access to the 
>> necessary parts of their superclass
>>      • It communicates the author’s intent that the items are not meant to 
>> be visible to its users, but that it is expected to be used for 
>> extension/subclassing
>>      • It requires an explicit statement ‘import hidden’ to access the 
>> hidden variables. Safe by default, with override.
>>      • It is not bound by module boundaries  (i.e. you could use it for 
>> subclassing classes from an imported module)
>>      • Roughly the same length as ‘private’ and ‘public’ so various 
>> declarations packed together are much easier to read (fileprivate breaks 
>> reading rhythm)  
>> Worth a formal proposal?
>> Thanks,
>> Jon
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution

swift-evolution mailing list

Reply via email to