Hasn't "hidden" already been discussed? I could swear that it was already pitched and feedback given.
In any case there's an ongoing discussion in another thread about removing new private; it seems distinctly poor form to abandon that and propose doing the exact opposite (removing old private) in a new thread. On Mon, Feb 13, 2017 at 08:06 Jonathan Hull via swift-evolution < [email protected]> wrote: > I wanted to propose a second simplification to the access system which > would have several benefits: > > • It would remove ‘fileprivate’ > • It would allow extensions to be in their own files > • It would serve the needs of ‘protected’ without the > complications involved in that > • It would serve some of the needs of submodules (but also work > together with them really nicely when we have both) > • It would allow protocols to have something similar to private > methods, which are not exposed to callers of the protocol, but still > required for conformance > > > My proposal is to add a ‘hidden’ access modifier which would act as a > separate AXIS as opposed to a new level. Thus, it could be combined with > any of the other modifiers (e.g. 'public hidden var’). The ‘fileprivate’ > level would be removed. > > Anything which is marked hidden is not visible outside of the file it is > defined in. That visibility can be explicitly restored on a per file basis > (but only within the defined access level). Take a look at the following: > > //File: MyStruct.swift > > struct MyStruct { > var a:Int > hidden var b:Int > } > > extension MyStruct { > var biggest:Int {return max(a,b)} //We can still see ‘b’ > because it is only hidden outside the file > } > > Here we see that ‘b’ behaves very similarly to the way fileprivate works > now. ‘b’ is technically still internal, but it is hidden and thus can’t be > seen outside the file. The difference is that instead of being forced to > add all of our extensions in the same file, we can organize them however we > prefer. > > //In another file > import hidden MyStruct //This exposes all ‘hidden’ items from the > file MyStruct to this file > > extension MyStruct { > var c:Int {return a + b} //We can see ‘b’ because of the > ‘import hidden’ statement > } > > > Notice how the intent has been shown here. ‘b’ is marked ‘internal’, > which means we know that no one can see ‘b’ outside of the module. In > addition ‘b’ is marked ‘hidden’, which means that the author is saying that > this should only really be accessed from extensions, subclasses, or types > which would be called friends in other languages. The actual guarantee is > still ‘internal’, but a caller does have to explicitly request the access > by typing ‘import hidden’, which will stop accidental/casual misuse. > (If/when we get submodules, then we can make tighter guarantees) > > This also allows a class to “hide the ejection seat levers” from its > callers, while still allowing access for subclasses and extensions (i.e. it > does most of what ‘protected’ would do, but with swift’s simpler file-based > access model) > > The same is true of protocols. There are often methods I have to include > on protocols which are needed by the default implementations, but NEVER > meant to be called directly by callers of the protocol. If vars/methods of > a protocol are marked hidden, then they would be hidden from callers of the > protocol outside the file. They are still required for conformance, > however*. > > protocol MyProtocol { > var a:Int > hidden var b:Int //Conformers still need to provide this, > but callers can’t see it > } > > extension MyProtocol { > func doSomethingBasedOnB() { > //The extension can see b in the same file, but > callers in other files won’t have access to ‘b’ directly > } > } > > I think all of this works really well with Swift’s goal of progressive > disclosure. Users of protocols/classes/etc… are not exposed to the > internals necessary for extension (e.g. it won’t come up in autocomplete) > until they actually need to conform/subclass/extend. Users won’t even need > to learn about ‘hidden' until they are trying to extend a type which uses > it (in a way which requires access to those internals), or they are writing > their own framework. It has a simple and consistent meaning based on > Swift’s original file-based access, but allows power/flexibility (without > too much bookkeeping/boilerplate) where needed. > > Thanks, > Jon > > > * One detail needed to make things useful for protocols, is that both > hidden and non-hidden vars/methods on the conforming type should count > towards conformance of hidden vars/methods on the protocol. Basically, > marking something as ‘hidden’ on a protocol means it isn’t seen by the > caller (only conformers/extensions). It makes sense to allow the conformer > not to expose that either, unless desired. It would technically work fine > without this allowance, but it ‘feels right’ and people would ask for it > quickly... > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
