[swift-evolution] Type access level as the default for its members?

Jose Cheyo Jimenez cheyo at masters3d.com
Fri Jul 22 12:14:13 CDT 2016

> On Jul 22, 2016, at 3:34 AM, Eric-Paul Lecluse via swift-evolution <swift-evolution at swift.org> wrote:
> To illustrate my question below, here are three publicly modified entities: a struct, an enum and an extension, whose properties lack explicit access modifiers:
>     public struct Car {
>         var wheel: [Wheel]
>         var licensePlate: String
>         func combust() { ... }
>     }
>     public enum Wheel {
>         case big
>         case small
>         var revolutionDistance: Double { ... }
>     }
>     public extension Car {
>         func park() { ... }
>     }
> The default access level for every member is `internal` for all members of an original type. Therefore both `combust()` and `revolutionDistance` are publicly inaccessible. For extensions, this is different, `park()` _is_ publicly accessible (as would be computed properties if it had any) because the extension is marked `public`. There's no option to modify an enum's cases individually (nor should there be), they're inherently linked to the enum's access level.
> When modifying any of the entities to `private`, their members become inaccessible by association. If a type isn't accessible, neither are its members. Thus for the `private` case, the behavior feels more like what the extension modifier did in the first place. 
> Not immediately apparent from this example is that the struct has an implicit constructor (lacking any explicit ones), whose access level also defaults to `internal`. This means the Car-struct can't be constructed outside of its defining module, until we create an explicit initializer with the `public` access modifier.
> # Problems
> The current approach is very verbose for any kind of access modification. Public structs that are intended to expose their members, require explicitly marked `public` modifiers everywhere. Consider the case where you want to expose a previously hidden (internal or private) type, you need to modify every individual member. Except if you're modifying an extension, in that case you only need to modify in one place. This means that conceptually, putting a `public` or `private` modifier on a type behaves differently from putting one one an extension, with regard to a type's members, which can lead to confusion (and has in my case, and with several fellow developers).
> # Idea
> What if the default access level were chosen differently? Instead of being `internal` by default, or `private` by association, what if the _type-level_ access modifier would determine the default for _all_ members, unless explicitly modified, including `public` and to-be-introduced ones?

I don't think this is going fly:
- internal is the default because the team wants any public API to be explicit. 
- There was a rejected proposal (119?) that tried to make extensions work just like types. 
- This is a breaking change and we are out of time for swift3
- What you want is already offered by public extensions. (Some people find this confusing but it looks like this is stay in swift 3). 

> This would...
> 1. equalize the conceptual behavior between access levels of an original type and the ones of their extensions.
> 2. greatly reduce verbosity on members due to explicit access level modifiers.
> 3. make it easier to modify the access level of an entire type, without requiring modification of individual members.
> 4. reduce the requirement of public constructors where they would match the implicit ones.
> 5. still allow exceptions on an individual level
> What do you think?
> Regards,
> Eric-Paul
> --
> Notes:
> * I'm using the word 'entity' to lump types and extensions together under one term. There must be a better term, please do share!
> * My examples are based off of my experience with Swift 2.2, even though I believe the concepts still apply in 2.3 and the 3.0-beta.
> * Protocols don't allow access modification on individual members, of course, similar to an enum's cases.
> * Didn't find any similar topics in the [commonly rejected list](https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md)
> * There's a [newly accepted proposal](https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md#proposed-solution) that adds `fileprivate` as a fourth access level modifier.
> Other discussions about access levels, yet not what I was looking for:
> * [Default access control / Access control blocks] (https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160328/013683.html)
> * [Access modifier blocks] (https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160613/020968.html)
> _______________________________________________
> 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/20160722/e801a964/attachment.html>

More information about the swift-evolution mailing list