There are two different questions that we keep bouncing back and forth
between. Given:
class Outer {
private var outerVar: Int
class Inner {
private var innerVar: Int
}
}
Is outerVar visible inside Inner? To me this seems 'obvious'... Yes.
Is innerVar visible to Outer? The answer to this impacts what I think the
access modifiers should be called.
> On Mar 28, 2016, at 18:05, Ilya Belenkiy via swift-evolution
> <[email protected]> wrote:
>
> Ok, I guess I never used nested types much in C++. If this is standard, I
> don't want to change it. I'll revert back to the pure "scoped" meaning. Thank
> you, this was very useful.
>
> On Mon, Mar 28, 2016 at 4:30 PM Jordan Rose <[email protected]> wrote:
>>> On Mar 28, 2016, at 11:40, Ilya Belenkiy <[email protected]> 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.
>>
>> Best,
>> Jordan
>>
>> 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.
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution