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

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 29 17:30:36 CDT 2016


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
  }
}
```


> 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/a34989cf/attachment.html>


More information about the swift-evolution mailing list