[swift-evolution] SE-0025: Scoped Access Level, next steps
jordan_rose at apple.com
Mon Mar 28 15:30:43 CDT 2016
> On Mar 28, 2016, at 11:40, Ilya Belenkiy <ilya.belenkiy at gmail.com> wrote:
> > I still don't understand your reasoning here. If a private member can be used in a member function, and in closures inside that member function, why can't it be used in a member type?
> The simplest answer is that it's the most private access level, and also one that doesn't create any confusion. We already discussed several times here whether inner should have access to outer or the other way around. With this design, the answer is neither.
> A longer answer is that if you move a function into a type and make it a member function, you change the semantics. It's no longer the same function. If you move the type inside another type, the semantics is the same. The only difference is that we get shorter names. Also, if you move a function to be a member function, that changes the class API. If you move a class to become a nested class, that does not change the outer class API. Both classes can be used the same way but with different spelling of the name of the inner class.
> Also, I think that the terminology of access level really comes from OOP. The problem with the current state of things is that it mixes this terminology with export levels. This proposal makes "private" mean what it means in OOP and extends it so that it makes sense with Swift extensions.
> If we were talking about "scoped" level access, the immediate scope addition would be wrong. But if we are talking about "private", it's a different matter.
I don't buy this argument. Before Swift, there have been plenty of OO languages with extensions and plenty with access control, but no major ones with both except Ruby (discounting Objective-C's @private instance variables). And, ignoring extensions, the behavior of 'private' in all of these languages is to include access from member types:
- C++: yes
- Java: yes
- C#: yes
- Ruby: no, but even the outer class can't invoke private methods on a different instance of itself
- D: yes, but D's "private" is closer to Swift's current "private" than anything else
- Kotlin: yes
- Scala, Python, Go, Rust, Objective-C, Smalltalk: either no access control or no nested types, AFAICT
So "private" in these languages doesn't seem to mean "restricted to this type", and that shouldn't be considered the "obvious" meaning when several of us have considered it decidedly non-obvious.
P.S. "If you move the type inside another type, the semantics is the same." This already isn't true if the new member type is used to satisfy a protocol requirement (which, because of retroactive modeling, counts as "changing the class's API"), but it especially won't be true if/when we start allowing member types inside generic types. In that case, the inner type now has extra generic parameterization that it wouldn't have had before.
P.S. Extensions do make things a little more complicated, but again, there's almost no precedent here, and pretty much everyone agrees that this new scope-private access level shouldn't give access to extensions. That also means there's an option to keep yourself from accidentally accessing scope-private members in a member type: put the member type in an extension.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the swift-evolution