[swift-evolution] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

Matthew Johnson matthew at anandabits.com
Fri Apr 7 06:44:39 CDT 2017

> What is your evaluation of the proposal?
-1.  I have been a vocal proponent of scoped access all along.  Despite that I really tried to keep an open mind about this proposal.  In the end, I just don’t think it is the right decision.

I can see why some people would like to consider a main type declaration and extensions to be considered the same scope when they are in the same file.  Extensions of a type within a file are usually used primarily for organizational purposes.  The intent often isn’t really to create a scope boundary.  Needing to use the slightly verbose `fileprivate` is unfortunate.  But the keyword isn’t a scoping problem, it is a naming problem.

I think the most compelling argument in the proposal is the one that says it is important to highlight same-file, cross-type communication using the `fileprivate` keyword.  The argument is that by making this the only case where `fileprivate` is used will make these special cross-type members stand out more.  I considered this carefully and ultimately concluded that I just don’t think it’s that important.  

The reason I put scopes for more than one type in the same file to begin with is that privileged access of one kind or another is necessary.  For this reason, I think if we’re going to have a “soft default” that works in the vast majority of cases it should be file scope.  It would be nice if file scope could regain the name `private` without losing the scoped access feature but if we just can’t make that happen maybe we’ll just have to live without the “soft default”.

It isn’t cross-type members that I want to stand out.  It is same-scope-only members that need to stand out.  These members are scoped for important reasons and it is valuable to tightly bound code that can access them and avoid needing to look elsewhere in the same file for accesses.  Brent made an eloquent case for this despite having supported the rollback to Swift 2 access levels.

In the end, I still think the name `fileprivate` was a mistake and that the best design is Swift 2 `private` with `scoped` as the name for the Swift 3 `private`.  If we’re not going to fix that we should just leave access control alone in Swift 4.  

When we’re ready to discuss submodules as part of a release theme I hope we will also be willing to revise access control as a part of that them if that makes sense in the context of whatever submodules end up looking like.  At this time we would not only have more context regarding submodules, we would also have the benefit of more time and experience with the current access levels which may be helpful in informing our decision.

In recent threads on this topic there has been some discussion of introducing some kind of organizational mechanism that can be used within the scope of a type declaration.  I think this is an interesting approach and is the right approach to explore if we want to have a way to organize a type’s declaration without creating scope boundaries.  It would allow people to organize their members while still using `private` more often and better highlighting members that are visible file-wide.  

In Objective-C MARK comments were very commonly used for this purpose.  In Swift this is still possible but has been mostly replaced with extensions.  People want to use an organizational mechanism that is supported by the language.  Maybe we need some kind of organizational mechanism that does not create a scope boundary.  This is a topic for another discussion, but is worth keeping in mind while considering the merit of the current proposal.

> Is the problem being addressed significant enough to warrant a change to Swift?
No.  I believe it makes the language worse, not better.  It doesn’t address the real problems with access control.  The largest problem is the inability to form scopes between files and the entire module.  The problem with `fileprivate` and `private` is a naming problem, not a semantics problem.

I also believe the proposal does not adequately acknowledge the impact on existing code.  While most code will still compile the semantics will be significantly different for people who are using scoped access as it was intended - to closely bound access to members when there are good reasons for doing that.  In order to maintain semantic compatibility this code will need to be re-written to introduce a new type if there remains a desire to highlight access to these members.  Even then, it will be possible to extend that type elsewhere in the file to open a new scope which can access the members.  

We no longer have a tight bound, only a way to make it more verbose and obvious when the scope is opened elsewhere in the file.  This is a significant, not a small impact on this code.  The core team rejected SE-0159 because it determined people are using scoped access control for good reasons.  I don’t understand how we could go from that decision to making a change that effictively removes the primary benefit derived from using scoped access.

> Does this proposal fit well with the feel and direction of Swift?
No.  It violates the principle of nested scopes that has always been the foundation of Swift’s access control.  This principle is a very good one.  Any devastation from it should be extremely strongly motivated.  This proposal is not.  I believe it makes access control more complex, not simpler. 

 I am sympathetic to those who want to say `private` instead of `fileprivate` to share members between type declarations and same-type extensions in the same file but violating the principle that underlies Swift’s access control is not the right way to solve that problem.

> If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

> How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
In-depth study.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170407/f25ffaee/attachment.html>

More information about the swift-evolution mailing list