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

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 29 17:44:42 CDT 2016


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

>
> On Jun 29, 2016, at 5:30 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Wed, Jun 29, 2016 at 5:25 PM, Matthew Johnson <matthew at anandabits.com>
> wrote:
>
>>
>> On Jun 29, 2016, at 4:30 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> On Wed, Jun 29, 2016 at 4:15 PM, Jordan Rose <jordan_rose at apple.com>
>> wrote:
>>
>>>
>>> On Jun 29, 2016, at 14:12, Xiaodi Wu <xiaodi.wu at gmail.com> 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.
>>>
>>>
>>> I’m sorry, I don’t understand.
>>>
>>> Stepping back, though, this part of the proposal *was* discussed back
>>> when it was first going through, and it was settled (after some
>>> disagreement and discussion) that pure lexical scoping was the best choice.
>>>
>>
>> I entirely misunderstood that part of the debate. I had thought the gist
>> of the discussion was that SE-0025 itself was an explicit break from purely
>> lexical scoping, that the proponents of pure lexical scoping were arguing
>> against its adoption, and that its acceptance by the core team was a move
>> away from purely lexical scoping.
>>
>> Let me see if I can rephrase the difficulty as I perceive it. I had
>> thought that this was an equivalent formulation of the problem that you are
>> addressing with the amendment. The interpretation of `private` as a purely
>> lexical scope results in the scenario as follows:
>>
>> 1. I declare `private var foo`
>> 2. There are places in code where `foo` is visible but where its access
>> level cannot be uttered (e.g., within a nested type, `foo` is not private
>> to that nested type, but it is more narrow in scope than fileprivate,
>> internal, or public)
>>
>> Your proposal is to allow `fileprivate` to be used in place of the
>> unutterable access level. This seems like a hack. The necessity for it
>> would go away if we stipulated `private` to exclude all places in code
>> where `foo` is visible but where its access level cannot be uttered.
>>
>>
>> You have this wrong.  It is not that you declare `private var foo` and
>> then in specific places it is visible but you can’t utter its access
>> control.
>>
>> The problem is when you use `private` on any construct which introduces a
>> scope that contains further declarations.  You cannot utter the default
>> access control for the members of that scope.  Here are examples:
>>
>> private struct S {
>>     var foo: Int
>> }
>> private class C {
>>     var foo: Int
>> }
>> private enum E {
>>     var foo: Int { return 42 }
>> }
>> private extension S {
>>     func bar() {}
>> }
>>
>> In all of these examples `foo` and `bar` are visible within the top level
>> scope, but not outside the file.
>>
>
> Sorry, yes, that is one problem. The related problem I was trying to
> describe was this:
>
> ```
> public struct A {
>   private var foo: Int
>   internal struct B {
>     // I cannot utter the access control for `foo` here
>     // and there is nothing I can declare here to be visible
>     // exactly where `foo` is visible
>   }
> }
> ```
>
>
> Access control is never uttered at *usage* sites.  It is uttered at
> *declaration* sites.  By definition of scope-base access control you are
> not going to be able to utter the precise visibility level of some visible
> declarations at the *usage* sites.  I don’t see why this is a problem.  It
> is utterability at *declaration* sites that is important.
>

Sorry, I'm being sloppy here. Inside struct B, I intend to declare things.
Substitute `typealias Foo` for `var foo` and declarations inside struct B
will have trouble with `A.Foo` because of restrictions concerning minimum
visibility.


>
>
>
>> In this case that happens to correspond to `fileprivate` which is
>> probably why Jordan selected that keyword.  In cases where these are not
>> top level declarations, but nested within a scope these will be visible
>> within that scope, but not at the top level of the file.  In *no* case does
>> the unutterable access level correspond to *internal* which is probably why
>> Jordan did not suggest using that.
>>
>> -Matthew
>>
>>
>>
>>
>>>
>>> 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/caef74fc/attachment.html>


More information about the swift-evolution mailing list