[swift-evolution] [Draft] Harmonize access modifiers for extensions

Xiaodi Wu xiaodi.wu at gmail.com
Sun Jul 17 10:36:21 CDT 2016


That's a good point. I will incorporate these into a revised draft. Only
two things will change:

```
public struct Foo {
  // implicitly internal
  func frobnicate1() { }
}
public extension Foo {
  // currently implicitly public
  //
  // depending on which alternative is adopted,
  // the proposal will either prohibit `public extension`
  // or this method will be implicitly internal
  func frobnicate2() { }
}
```

```
internal struct Bar {
  // permitted by SE-0025 without a warning
  // this method can only be accessed within module anyway
  // because `internal struct` bounds access of its members
  public func frobnicate1() { }
}
extension Bar {
  // not permitted by SE-0025
  //
  // after proposal, this will also be permitted without a warning
  // and this method will also be accessible only within module
  public func frobnicate2() { }
}
```

On Sun, Jul 17, 2016 at 1:50 AM, Adrian Zubarev via swift-evolution <
swift-evolution at swift.org> wrote:

> I’m struggling to understand your proposal, can you provide some specific
> code samples how it works now and what will change. The example from the
> draft doesn’t help my understanding. :/
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 17. Juli 2016 um 04:40:45, Xiaodi Wu via swift-evolution (
> swift-evolution at swift.org) schrieb:
>
> On Sat, Jul 16, 2016 at 7:56 PM, Jose Cheyo Jimenez <cheyo at masters3d.com>
> wrote:
>
>> I think you can simplify this proposal by just saying something like this
>> and give a couple of examples that are easy to follow:
>>
>> Disallow explicit public access modifier on non-protocol-conforming type
>> extensions.
>>
>
> It took me a while to process what you're trying to say here, but this is
> a good idea and would go along well with the first draft's proposed
> solution. I will spell it out. (If we say that you can use an explicit
> modifier only to lower the access level of members, then `public` as an
> explicit modifier could be entirely disallowed.)
>
>
>>
>> I think if you only focus on that breaking change then the proposal will
>> have a good chance of getting accepted and fixing the immediate issue of
>> public. There is a reason why protocol conforming extensions do not allow
>> explicitly saying public
>> `public extension Type: Protocol {}` // public not allowed
>>
>
> Actually, no modifiers are allowed in that scenario, IIUC.
>
>>
>> In essence we will be asking for the same behavior for types.
>>
>> Allowing methods declared inside extensions to have a higher declared
>> visibility is not a breaking change and can be introduced later.
>>
>
> It is a breaking change in that I am proposing that the rules be
> harmonized so that the implicit default access level will be notionally
> `internal` (there are follow-on benefits to this change). That cannot be
> changed later.
>
>
>> Nobody wants private extensions or implicit internal extensions to go
>> away. :)
>>
>
> I know that there are people who don't want it to go away. That was why
> the first draft proposed keeping them, but it sounds like it would make for
> an illogical system. I know that Jordan and John have both indicated that
> they don't think it's worth keeping around but don't seem to feel too
> strongly about it, and I think I feel the same way (leaning towards not
> keeping them, but don't feel very strongly). I will definitely feature this
> concern (using extensions as access modifier groups) prominently in the
> proposal and hope for a robust discussion to see how it plays out with the
> community and core team.
>
>
>
>> On Jul 16, 2016, at 4:22 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> On Sat, Jul 16, 2016 at 6:10 PM, David Hart <david at hartbit.com> wrote:
>>
>>> This proposal really confuses me. Two comments:
>>>
>>> 1) With the proposal, we loose the ability to use access modifiers on
>>> extensions as a way of grouping members by access. That's a huge loss for
>>> me.
>>>
>>
>> You lose the ability to group public members only. That part is
>> intentional, so that only methods declared with `public func` are public.
>>
>>
>>> 2) If we adopt the proposal, I now have no idea what explicit access
>>> modifiers on extensions do.
>>>
>>
>> I propose keeping explicit access modifiers because previous comments on
>> this list have said that it's useful for grouping members by access. You
>> can continue to use extensions to group fileprivate members of an internal
>> type, or internal members of a public type.
>>
>>
>>
>>> More generally, I don't understand this proposal as it's trying to apply
>>> the same access modifier rules on extensions as for types but extensions
>>> are not types. They are just a declaration for extending types which
>>> already have an access level.
>>>
>>> On 16 Jul 2016, at 20:04, Xiaodi Wu via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>> With the impending withdrawal of SE-0119 and the closing window for
>>> (most) source-breaking changes, I thought I'd draft up a proposal to
>>> address some of the key points raised in that discussion.
>>>
>>> The proposed changes are deliberately limited in scope to rationalizing
>>> access modifier rules without adding any new facilities (such as
>>> conformances of lower visibility than the type), which might be more
>>> appropriate for the Swift 4 timeline.
>>>
>>> I hope this will prove satisfactory to the community :)
>>>
>>>
>>> Harmonize access modifiers for extensions
>>>
>>>    - Proposal: SE-XXXX
>>>    <https://github.com/xwu/swift-evolution/blob/harmonize-access-modifiers/proposals/XXXX-harmonize-access-modifiers.md>
>>>    - Author: Xiaodi Wu <https://github.com/xwu>
>>>    - Status: Awaiting review
>>>    - Review manager: TBD
>>>
>>>
>>> <https://github.com/xwu/swift-evolution/tree/harmonize-access-modifiers#introduction>
>>> Introduction
>>>
>>> During discussion of SE-0119
>>> <https://github.com/xwu/swift-evolution/blob/harmonize-access-modifiers/proposals/0119-extensions-access-modifiers>,
>>> the community articulated the view that access modifiers for extensions
>>> were and should continue to be subject to the same rules as access
>>> modifiers for types. Unfortunately, it is not factually true today; this
>>> proposal aims to make it so.
>>>
>>> Swift-evolution threads:
>>>
>>>    - [Proposal] Revising access modifiers on extensions
>>>    <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160620/022144.html>
>>>    - [More to be added here]
>>>
>>>
>>> <https://github.com/xwu/swift-evolution/tree/harmonize-access-modifiers#motivation>
>>> Motivation
>>>
>>> Consider the following:
>>>
>>> public struct foo {
>>>   func frobnicate() { } // implicitly internal
>>> }
>>> public extension foo { }
>>>
>>> public struct bar { }
>>> public extension bar {
>>>   func frobnicate() { } // implicitly public, according to SE-0025
>>> }
>>>
>>> According to SE-0025, a method moved from the body of a public struct
>>> into a public extension becomes public without modification. This is
>>> surprising behavior contrary to Swift's general rule of not exposing public
>>> API by default.
>>>
>>> Furthermore, SE-0025 now permits the owner of a type to design access
>>> for members as though the type will have a higher access level than it
>>> currently does. For example, users will be able to design public methods
>>> inside an internaltype before "flipping the switch" and making that
>>> type public. The same approach is prohibited by SE-0025 for extensions,
>>> although conceptually it need not be.
>>>
>>> <https://github.com/xwu/swift-evolution/tree/harmonize-access-modifiers#proposed-solution>Proposed
>>> solution
>>>
>>> The proposed solution is to change access modifier rules for extensions
>>> with the following effect: if any method (or computed property) declared
>>> within the body of a type at file scope is moved without modification into
>>> the body of an extension in the same file, the move will not change its
>>> accessibility.
>>>
>>> In code:
>>>
>>> struct foo {
>>>   // Any method declared here...
>>> }
>>> extension foo {
>>>   // ...should have the same visibility when moved here.
>>> }
>>>
>>> This implies that public API commitments will need to be annotated as
>>> public at declaration sites inside an extension just as it must be at
>>> declaration sites inside types.
>>>
>>> <https://github.com/xwu/swift-evolution/tree/harmonize-access-modifiers#detailed-design>Detailed
>>> design
>>>
>>>    1. Declarations inside the extension will, like declarations inside
>>>    types, have a default access level of internal.
>>>    2. The compiler should not warn when a broader level of access
>>>    control is used for a method (or computed property, etc.) declared within
>>>    an extension with more restrictive access. This allows the owner of the
>>>    extension to design the access level they would use for a method if the
>>>    type or extension were to be made more widely accessible.
>>>    3. An extension declared without an explicit access modifier will
>>>    have the same access level as the type being extended.
>>>    4. An extension declared without protocol conformance may optionally
>>>    use an explicit access modifier to provide an upper bound for the
>>>    visibility of its members.
>>>
>>>
>>> <https://github.com/xwu/swift-evolution/tree/harmonize-access-modifiers#alternatives-considered>Alternatives
>>> considered
>>>
>>>    - One alternative, still open for consideration, is to eliminate #4
>>>    and disallow explicit access modifiers on extensions. As an advantage, this
>>>    would clarify the mental model that extensions are not their own entities,
>>>    as they cannot be referred to by name and have no runtime representation.
>>>    As a disadvantage, extensions cease to be an access modifier grouping
>>>    construct, which some users really like.
>>>
>>>
>>> <https://github.com/xwu/swift-evolution/tree/harmonize-access-modifiers#acknowledgments>
>>> Acknowledgments
>>>
>>> Thanks to all discussants on the list, especially Adrian Zubarev and
>>> Jose Cheyo Jimenez.
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> 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/20160717/aad6a2d3/attachment.html>


More information about the swift-evolution mailing list