[swift-evolution] Simplifying Access Using 'Hidden'
dplanitzer at q.com
Mon Feb 13 11:50:45 CST 2017
The problem with fileprivate is this: a new keyword was introduced for the original definition of private and a new definition of private was introduced that does not carry its weight in the context of Swift. Because of these two actions, the original definition of private was elevated to a level above the private keyword which by the end of the day is just a very weak version of a sub-module / package access level.
The original definition of private made sense in the context of Swift 2 because:
1) it fit into the definition of public and internal: private is everything inside a file, internal is everything inside a module and public is the subset of internal stuff that we want to be accessible outside the module boundary. This was a straight-forward conceptual model.
2) it played well together with the Swift definition of an extension and it provided some relieve to the limitation that an extension can’t define a private stored property: e.g. I was able to define a type inside of a file by splitting it up into a base type definition which would carry all the private stored properties and a series of extensions which would define the semantics of the type, organized into logical blocks.
Now in Swift 3 I have to use fileprivate to pull off (2) and fileprivate adds extra complexity to (1) without given me the flexibility to:
a) add support for sub-modules. Sub-modules would require the addition of yet another access level.
b) put the implementation of separate but strongly related types into separate files. Eg in order to implement a module which has a set of SPI
What worries me is that I see more and more proposals that want to add yet another bunch of access levels and I also see the sub-module discussion come up from time to time. It also worries me that Swift already has more access levels than e.g. Java, yet it is Java that allows me to more precisely express my intent because:
I) I can express the intent that this function / type X is only relevant inside this package Y and nobody outside the package should be able to access X
II) I can express the intent that this function X should only be accessed by a subclass A of B, but not outside the subclassing context
I feel that the Swift access level story, as it stands today, is not only needless complicated compared to other languages while actually providing less relevant expressivity, it also feels like that the complexity of this story will sharply increase over time while still not providing much more relevant expressivity.
So IMO Swift should:
1) go back to public, internal and private with the respective definitions of Swift 2 (yes, open is another useless addition to the access level story but I frankly see less chance of getting rid of that compared to fileprivate)
2) then figure out whether and how to add sub-module capabilities. Add a module access level in this case and consider removing internal (with an alias internal == module as a back combat step)
3) then, and only then, consider adding additional levels if there is a clearly measurable advantage in doing so
> On Feb 13, 2017, at 08:21, Adrian Zubarev via swift-evolution <swift-evolution at swift.org> wrote:
> People talk always like “I never liked fileprivate” and I feel like some of you forgot that fileprivate is not new to Swift. It’s the repainted private from days before Swift 3. I cannot recall anyone complaining about it that much. There were some people that forced the addition of a stricter private access modifier for Swift 3. Now that we have both, there are a lot of complains about fileprivate.
> Adrian Zubarev
> Sent with Airmail
> Am 13. Februar 2017 um 17:10:45, Joanna Carter via swift-evolution (swift-evolution at swift.org) schrieb:
>> Le 13/02/2017 à 15:15, Adrian Zubarev via swift-evolution a écrit :
>> > –1
>> > I won’t even try to be constructive on this one. It simply makes me
>> > tired of all this access modifier mess. |open|, |closed|, |public|,
>> > |internal|, now |hidden|, |fileprivate|, |directoryprivate|,
>> > |moduleprivate|, |private|, I might even forget some of the proposed
>> > access modifiers.
>> > Instead of adding new stuff that explodes the complexity we should put
>> > our energy and fix existing issues, like the inconsistent |open| for
>> > example.
>> I would also say that access modifiers do seem to be be somewhat messy.
>> I have never liked the idea of fileprivate ; this is the equivalent of Delphi's private scope, to which they then added strict private for class only scope. That was a similar mess.
>> I am still not sure why we can't have the good old-fashioned visibilities of private, protected and public for classes. They have worked well for years and I feel we are changing things for change's sake.
>> For all types other than classes, where inheritance is a feature, we have private, internal and public.
>> For classes, we should definitely add protected ; I find internal just too exposing for stuff to be used exclusively by derived classes.
>> But, I believe one of the motives behind fileprivate was to satisfy the need for extensions to a type to access private members.
>> Just to put in my 2¢ worth, the only extra scope I would suggest could be named "extensible" and would allow anything so marked to be visible only as far as extensions ; the difference being that such extensions could then be placed in separate files.
>> So, private, protected (class only), internal, public and extensible.
>> Or is that too revolutionary ?
>> swift-evolution mailing list
>> swift-evolution at swift.org
> swift-evolution mailing list
> swift-evolution at swift.org
More information about the swift-evolution