[swift-evolution] [Discussion] A Problem With SE-0025?

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 29 17:59:55 CDT 2016


On Wed, Jun 29, 2016 at 5:55 PM, Matthew Johnson <matthew at anandabits.com>
wrote:

>
> On Jun 29, 2016, at 5:41 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Wed, Jun 29, 2016 at 5:36 PM, Matthew Johnson <matthew at anandabits.com>
> wrote:
>
>>
>> On Jun 29, 2016, at 4:57 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>> On Wed, Jun 29, 2016 at 4:46 PM, Matthew Johnson <matthew at anandabits.com>
>>  wrote:
>>
>>>
>>> On Jun 29, 2016, at 4:19 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>
>>> On Wed, Jun 29, 2016 at 4:16 PM, Matthew Johnson <matthew at anandabits.com
>>> > wrote:
>>>
>>>>
>>>> On Jun 29, 2016, at 4:12 PM, Xiaodi Wu via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>>
>>>> On Wed, Jun 29, 2016 at 4:07 PM, Jordan Rose <jordan_rose at apple.com>
>>>> wrote:
>>>>
>>>>>
>>>>> On Jun 29, 2016, at 14:03, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>>>
>>>>> On Wed, Jun 29, 2016 at 3:15 PM, Jordan Rose via swift-evolution <
>>>>> swift-evolution at swift.org>wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> > On Jun 29, 2016, at 13:13, Jose Cheyo Jimenez <cheyo at masters3d.com>
>>>>>> wrote:
>>>>>> >
>>>>>> > I know this might be have been brought up before but
>>>>>> >
>>>>>> > why not just disallow the “private" keyword for top level types,
>>>>>> extensions etc.
>>>>>> >
>>>>>> > A fixit could change top level `private` to `fileprivate`.
>>>>>> >
>>>>>> > I think this is a little less confusing since effectively this is
>>>>>> what is happening in the background.
>>>>>>
>>>>>> That doesn’t fix anything for inner types, so it’s a lot less
>>>>>> important than the rest of the amendment.
>>>>>>
>>>>>> There actually is an answer to this, which is that the core team
>>>>>> expects 'private' to be the common keyword, and therefore it’s better if
>>>>>> you can use it at the top level and ignore ‘fileprivate’ altogether in most
>>>>>> programs.
>>>>>>
>>>>>
>>>>> On second thought, wouldn't all of this be inapplicable if `private`
>>>>> literally meant visibility *only* within the current declaration, and
>>>>> neither outside it nor inside any nested types, etc.?
>>>>>
>>>>>
>>>>> Yes, but that's not very useful:
>>>>>
>>>>> public struct Foo {
>>>>>   private var value: Int = 0
>>>>>   public func test() {
>>>>>     print(value) // error
>>>>>   }
>>>>> }
>>>>>
>>>>>
>>>>> I suppose you could say that nested *types* are different from nested
>>>>> *functions,* but then we start getting complexity in a different
>>>>> direction. And it still doesn't fix the default access within a private
>>>>> type.
>>>>>
>>>>
>>>> Let me offer a principled rule: if I write `private var foo`, then
>>>> `foo` is invisible at such places within the declaration where writing
>>>> `private var bar` at the same place would cause `bar` to be visible where
>>>> `foo` is not or vice versa.
>>>>
>>>>
>>>> This violates the principle behind all of Swift’s access control
>>>> rules.  That principle is that access control is strictly based on a
>>>> hierarchy of lexical scopes.  This is a really great principle and is what
>>>> makes Swift’s access control better than any other I know of (IMO of
>>>> course).
>>>>
>>>
>>> But however you slice it, some principle of Swift's access control rules
>>> is violated by `private`. If `foo` is visible in a place where I cannot
>>> write `private var bar` to mean the same visibility, then the access level
>>> of `foo` is unutterable in that location, which is unprecedented as well.
>>>
>>>
>>> I don’t think utterability was a conscious principle to the degree that
>>> scope based access control was.  If that was the case the issue would
>>> surely have been identified during review.  It wasn’t until Robert started
>>> the implementation that anyone (AFAIK) notices that the proposal introduces
>>> unutterable visibility in some cases.  Utterability just isn’t something
>>> people were thinking about until then.
>>>
>>> But you are right that unutterability is unprecedented and I think
>>> everyone agrees that it poses problems which is why Jordan and Robert have
>>> amended the proposal to make the visibility members of private types
>>> without explicit access control utterable.
>>>
>>> The solution we want is to preserve *both* of these principles, not
>>> change which one were violating. :)
>>>
>>
>> If a private member must be visible within a nested type, then that
>> access level necessarily becomes unutterable within the nested type unless
>> we introduce another keyword, which is out of scope without a new proposal.
>> There is no squaring the circle to be had. The amendment, to my
>> understanding, simply hacks around this issue to make `private` nonetheless
>> useful by allowing `fileprivate` things inside `private` things, but in so
>> doing we're enshrining which of these principles we're violating, not
>> finding a solution that avoids violating them.
>>
>>
>> Do you mean a third principle which says something like “a member shall
>> not have a higher access level than its parent”.  If so, you are correct
>> that Jordan’s amendment does violate that and another proposal would be
>> necessary to give it a name that does not exist today.  I don’ think that's
>> going to happen for Swift 3.
>>
>
> No, not exactly what I mean, but that is a concern. Jordan's proposal
> introduces a dichotomy between the actual access level (i.e. the answer to
> the question, which code can see this member?) and the access modifier
> which is used in conjunction with the member (which would become
> `fileprivate`). So yes, I can utter something, but it doesn't change the
> fact that the question "which code can actually see this member?" still has
> no utterable answer.
>
>
> The dichotomy is already implied by the semantics of SE-0025, it just left
> the visibility unutterable.  Jordan’s amendment makes `fileprivate` have
> context / scope sensitive semantics which makes the answer utterable.
>

Yes, I see your point now. It took me this long to understand what was
being proposed because the name "fileprivate" explicitly disavows
context-sensitive semantics. With this amendment, `fileprivate` will
definitely need a renaming because it will neither be private nor scoped to
file.

The only way I can think of to make a scope-dependent visibility level
> *precisely* utterable everywhere within the relevant scope would be to
> introduce modifiers like `private(Foo)` where `Foo` is a parent scope.  If
> you want it to be *precisely* utterable you could consider proposing
> something along these lines after Swift 3 is out.  Any proposal along these
> lines would need to consider how to handle extensions since those don’t
> have names and would also need to handle degenerate cases such as `Foo`
> within `Foo` within `Foo`.
>
>
>
>>
>>
>>
>>>
>>>
>>>
>>>>
>>>>
>>>>
>>>>> Jordan
>>>>>
>>>>
>>>> _______________________________________________
>>>> 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/20160629/61cd692b/attachment-0001.html>


More information about the swift-evolution mailing list