[swift-evolution] Simplifying Access Using 'Hidden'

Jonathan Hull jhull at gbis.com
Mon Feb 13 18:37:37 CST 2017


I think you hit the nail on the head in that the main issue is that our access control is mixing together several concepts (file-based, type-based, module-based, “open”).

I don’t think anyone is actually reading the proposal though.  Hidden is file based (not type based). It provides the functionality of protected, but using swift’s file based approach.  The reason ‘fileprivate’ goes away is not because it isn’t possible, but because it is essentially redundant (with the shorter keyword of ‘hidden’).

The big difference is that you can put extensions in separate files within the module (while still expressing intent).  Which based on your assertion that "it's not particularly useful for the compiler to hide something from you that you can plainly see and touch” is a good thing.

Also note that my proposal is completely compatible with either the Swift 2 or Swift 3 version of private. It does need one of them to stay, but either would work fine. As you say, having several shades of private is not helpful. 

Without something like this, we are going to continue to see a proliferation of new levels/proposals (e.g. friend & protected), each with associated bookkeeping/boilerplate.  The idea is to head that off and provide a single concept with enough flexibility to avoid that while still using Swift’s file based approach.

Thanks,
Jon


> On Feb 13, 2017, at 3:38 PM, Xiaodi Wu via swift-evolution <swift-evolution at swift.org> wrote:
> 
> The beauty of Swift 2's access modifiers was that they were based around files and modules, explicitly rejecting types and scopes as units for determining visibility. It seems at base there's a group of people who reject that decision altogether. Hence, new `private`, proposals around `protected`, `friend`, `hidden`, `extensible`, etc.
> 
> The point of the other thread was that a sizable proportion of people are finding the old system to be elegant and a suitable basis for future enhancements such as submodules. Here, there's another proportion of people who want to dismantle the old design completely. This was pitched already during the Swift 3 evolution process, repeatedly.
> 
> At some point, we've got to stop relitigating this design. It's untenable to have something as foundational as access control change with every version of Swift.
> 
> My two cents are that supporting all the shades of private is completely a non-goal. I've yet to be convinced that more access modifiers will improve anyone's code sufficiently to justify any more turmoil in the language. The Swift 2 way took a very pragmatic approach. When can I access this member? If private: when I have the source code already open; if internal: when I have the source code available to open; if public: whenever. It takes the opinionated (but IMO correct) view that it's not particularly useful for the compiler to hide something from you that you can plainly see and touch.
> 
> 
> On Mon, Feb 13, 2017 at 5:04 PM, Joanna Carter via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> What still strikes me as odd is that we now seem to have a plethora of visibilities, some of which do not provide for a given context, some of which seem to be looking for a context to justify their existence.
> 
> Whatever it is called, I find the idea of a file scope visibility somewhat bizarre and at odds with the principle of standard OO class encapsulation.
> 
> The two main reasons I can see for the perceived need for fileprivate are :
> 
> 1. being able to separate out "sections" of a class into various extensions
> 
> 2. giving global junkies the ability to write all their code in one unit
> 
> Surely, there are members of a type that the writer wants to remain private, even if an extension were declared in the same file. Fine, we have private for that and, even if the writer declares members to be fileprivate, there is no way that any extension declared outside of the file can see those members.
> 
> Now, I have a problem with that. If I want to access non-public members when I extend a type, either I declare those extensions in the same unit and declare those members as fileprivate, or if I want to declare those extensions in another file, I have to move up to the next suitable scope, which is internal.
> 
> But internal is too "open" because it allows, not only my chosen extensions to see those members but, also, any other code in the entire module.
> 
> Having made use of the "friend" concept in C++, this "all or next to nothing" approach to visibility seems to leave me in much the same place as Objective-C, where I could only have private or public, unless I did some tricky stuff with class extensions, something which really didn't look that pretty.
> 
> There are some parts of a type that I would want to remain really, really private to the type, not even visible to an extension.
> 
> There are other parts of a type that I would want to be private to that type but also visible in, but only in, extensions explicitly written against that type.
> 
> Which is why I am suggesting the "extensible" scope : private to the declaring type but also and only visible within any extension to that type.
> 
> Here follows a highly contrived example :
> 
> // Person.swift
> public struct Person
> {
>   public var name: String
> 
>   public extensible(set) var dateOfBirth: Date
> 
>   public var age: Int
>   {
>     // return calculated age as of today
>   }
> 
>   init(name: String, dateOfBirth: Date)
>   {
>     self.name <http://self.name/> = name
> 
>     self.dateOfBirth = dateOfBirth // accessible as if it were private
> }
> 
> // Registrar.swift
> extension Person
> {
>   func correct(dateOfBirth: Date)
>   {
>     self.dateOfBirth = …
>   }
> }
> 
> // Test.swift
> {
>   let person = Person()
> 
>   person.dateOfBirth = … // compilation error, not visible
> }
> 
> IMHO, this then removes one use case for fileprivate in that it allows privileged visibility to private members of a type in extensions, both in the same file and in any other file. But, it also ensures that not other code is allowed access, whether that be in non-extension code in the same file or other non-extension code anywhere else.
> 
> As for case 2. for fileprivate, if a developer wants to put all sorts of globals and other code in one file, then I doubt if they are even going to bother to use fileprivate, especially when they get internal visibility with less typing ;)
> 
> Now, if someone could help me prepare this as a proposal…
> 
> --
> Joanna Carter
> Carter Consulting
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170213/68ae49f0/attachment.html>


More information about the swift-evolution mailing list