[swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

Matthew Johnson matthew at anandabits.com
Tue Mar 21 09:58:33 CDT 2017

> On Mar 20, 2017, at 9:33 PM, Greg Parker via swift-evolution <swift-evolution at swift.org> wrote:
>> On Mar 20, 2017, at 4:54 PM, Douglas Gregor <dgregor at apple.com <mailto:dgregor at apple.com>> wrote:
>> Hello Swift community,
>> The review of SE-0159 "Fix Private Access Levels" begins now and runs through March 27, 2017. The proposal is available here:
>> https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md <https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md>
> -1. I yield the remainder of my time to Drew Crawford who satisfactorily explained my concerns.

I am also -1.  

I think there are two issues to be considered.  One is scoped access itself and the other is the names of the access levels.  

I think a reasonable case can be made that changing the meaning of private and introducing fileprivate was a mistake.  We probably should have left private alone and chosen a new name for scoped access.  There was abundant bikeshedding over this at the time, but now we have the benefit of experience.  I believe we should have simply called scoped access control `scoped`.  It’s clear that some people would still oppose scoped access but I also don’t think we’d be revisiting this topic if we hadn’t changed the meaning of `private`.  The passionate dislike of the feature seems to me mostly related to stealing the `private` keyword.  

I support correcting the naming mistake eventually.  I’m neutral as to whether Swift 4 is the right time to do that.  We just introduced a lot of churn in Swift 3.  There is still inconsistency in Swift’s access control system as well as unmet needs (especially around submodules).  It may be better to leave things alone for a release and make the change as part of a larger set of changes when access control and submodules are part of a release “theme”.

I am extremely unconvinced that having a scoped access level is actively harmful.  It introduces another choice in the language but no individual programmers or teams are forced to use the additional flexibility if they don’t want to.  It would be very easy for linters to prohibit scoped access if there are teams that don’t want to use it.  It is one extra degree of control for new programmers to learn but properly taught it helps programmers learn to think about encapsulation.  This is a good thing.

On the other hand, I believe removing scoped access is active harmful.  It reduces our ability to properly encapsulate mutable state.  For example, I like to use scoped access to create small state machine types which are used as part of the implementation of another type.  These are usually structs with a private enum.  The struct exposes methods which encapsulate state transitions.  Without scoped access there is no way to encapsulate the state of the state machine and force all changes to go through one of the methods on the struct.  This is just one example of how this feature can be very useful, there are many others.  Small helper types like this are very idiomatic in Swift.  It would be a big step backward to lose the ability to have proper encapsulation of small helper types.

One common argument agains scoped access is that “you’re only protecting yourself from yourself”.  I find this to be a bit of a straw man.  It isn’t about “protection”.  It is about compiler verified encapsulation.  This prevents inadvertent changes that violate the intent of the design.  For example, it is not out of the question that without scoped access a new member of a large team writes directly to the internal storage of the state machine in the above example.  It is also possible that they do so in a way that represents an invalid state transition.  The compiler would not catch this mistake.  Hopefully it would be caught in a code review but I can imagine it getting missed for many different reasons.  On the other hand, with scoped access the new team member would be unlikely to prefer changing access control to using the intended methods.  If they did change access control this would be very likely to be caught in code review.

Access control also provides compiler verified documentation of our code.  This facilitates reasoning about our code.  It also communicates design intent from the original author to future maintainers.  Removing a tool that many people find useful in facilitating reasoning about code is actively harmful.  Teams that don’t find this tool useful should use a linter and ban its use on their team.  This approach would let those of us who do find this tool useful continue to use it.

My observation thus far has been that people seem to be preferring private over fileprivate in many cases.  I don’t think this preference is solely about typing four less characters.  I think many people really do value the tighter encapsulation it provides.

I do think changes to access control are necessary but I also think this proposal is not the right answer.  The right answer should consider access control more holistically.  Access control is not a theme for Swift 4.  We shouldn't cause more churn around it until we’re ready to look at all of the issues with the current design.  And we certainly should not make an actively harmful change to the language.

> -- 
> Greg Parker     gparker at apple.com <mailto:gparker at apple.com>     Runtime Wrangler
> _______________________________________________
> 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/20170321/eb362356/attachment.html>

More information about the swift-evolution mailing list