[swift-evolution] Replace Fileprivate with Hidden + Import Hidden

Rien Rien at Balancingrock.nl
Mon Oct 17 13:28:30 CDT 2016


> On 17 Oct 2016, at 19:47, Jonathan Hull <jhull at gbis.com> wrote:
> 
> First, let me say, thank you for your feedback.  Just because I am arguing against others' points does not mean that I don’t appreciate those points.
> 
>> On Oct 17, 2016, at 12:37 AM, Rien <Rien at Balancingrock.nl> wrote:
>> 
>> -1.
>> 
>> If an API designer wants to allow access to a “hidden’ member, he should be in control of that access.
> This seems to be one of the biggest internal arguments within the swift community.  Who is in control of the use of frameworks?  The author or the user?
> 
> I am trying to plot a middle path here which gives both a fair amount of control.  I think that is part of why this proposal has been so unpopular, it is a compromise between both extremes, and everyone hates a compromise.  Someone else just had the opinion that we should make everything public and note in the documentation what should and should not be used.
> 
> And as I said before, API like UIGestureRecognizer's is currently impossible to create solely in Swift.  There is a hole in Swift’s access system which we will have to fix sometime during this phase.  I think a lot of people think that submodules will magically solve all of our problems, (I want them too) but the core issue here will remain (just with a little less frequency), and we will be forced to go back to the drawing board in 6mo to a year. I am hoping to prevent that.
> 
> 
>> The proposed chance simply opens up access completely and leads to API vulnerability.
> No, it only opens up access to API explicitly marked with ‘hidden’.  That is, the framework author is explicitly saying: This API should only be used for subclassing/extension (but they also realize it can be accessed).  The user of that API has to explicitly acknowledge that intention by writing ‘import hidden’.  API marked private or internal will not be opened beyond it’s scope in any case.
> 
> As I said in another email, a potential further compromise would be to make ‘hidden’ a separate axis, and allow things like ‘internal hidden’, where access can only be opened up within the module.  Would that solve your issues with the proposal?
> 
> I started out closer to your position, wanting more targeted permissions, but I ultimately realized that this would be good enough for real world use.
> 
> 
>> (I am in favour of a “friend” solution, in which the API designer explicitly allows access to identified members of the API users.)
> But what happens when you need to be a friend and you don’t own the API?  I get the thinking behind friend classes, but it is problematic in practice.

In that case, you don’t get to be a “friend”. Tough cookies. Life isn’t “fair”.
In an exact science like SW development, control must be hierarchical or singular. Any deviation, however small, will come back to bite.
Too many API developers have spend too much time to look for “errors” that inexperienced or unknowing API users caused because the API was too “open”. The API developer may think that “it is clearly documented”… but then again, look at stackoverflow…. people don’t read them, and the API developer will be held responsible for the error of others… if only in reputation...


>  As another poster mentioned, we basically have friend classes already, just based on location of code.  The core issue I am trying to solve here cannot be solved with more variation of the same, we need a counterpoint to it, and then the two approaches can be mixed to get the desired balance/tradeoffs.

Balances and tradeoffs only get you deeper into the quicksand. Better not to tread there. Sometimes you have to say NO.

Rien.

PS: I do understand the lure, buts it’s (IMO) always better to resist.



> 
> Thanks,
> Jon
> 
> 
>> Rien.
>> 
>> 
>>> On 16 Oct 2016, at 22:34, Jonathan Hull via swift-evolution <swift-evolution at 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 at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> 
> 



More information about the swift-evolution mailing list