[swift-evolution] access control

Matthew Johnson matthew at anandabits.com
Tue Jan 26 08:14:45 CST 2016


> On Jan 25, 2016, at 9:22 PM, Andrew Bennett <cacoyi at gmail.com> wrote:
> 
> It seems to be the opposite, these example work in a playground:
> 
> let public: Int = 123
> 
> error: keyword 'public' cannot be used as an identifier
> 
> However:
> 
> struct Test {
>     private(set) var set: Int
> }
> 
> no errors

You are right.  The access modifiers are not available as identifiers while most other decl modifiers are allowed: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-ID410 <https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-ID410>.  I should have checked before mentioning what I did about decl modifiers.

> 
> I think that `module` and `file` without further context may be confusing. I also think that `class` that I had is probably confusing.

You’re probably right about `module` and `file` having potential for confusion without context.  With that in mind, `internal` is probably better than `module` and is what we already have..

> 
> I don't see the additional verbosity as a problem, I think the more frequently used ones are probably fine.
> 
> I'm happy for them all to be keywords, the original proposal had some good suggestions there, I just think what I've suggested is a bit nicer.
> 
> I think that what I'm suggesting would increase safety and granularity, with only one new case you didn't have, and it would actually reduce the number of keywords.

I did cover all of your cases.  Making a distinction based on the type of scope (class vs extension) doesn’t seem to be worthwhile.  If you really wanted to stick with the private syntax `private(scope)` would make the most sense and would work for any kind of scope.

However I think that is verbose.  I think we have a couple of reasonable options.

Ilya’s proposal and closest to current state:
* public, internal, private, local (or scoped)

Change `private` to be scope-based and come up with something new for file-level visibility:
* public, internal, ??? file level, private

My preference depends on what we could come up with for file-level visibility.  If it’s better than `local` or `scoped` I would prefer that.  If not, I would prefer Ilya’s proposal.  In other words, we should choose the option with the best overall clarity.

-Matthew

> 
> 
> On Tue, Jan 26, 2016 at 1:51 PM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
> 
>> On Jan 25, 2016, at 8:37 PM, Andrew Bennett <cacoyi at gmail.com <mailto:cacoyi at gmail.com>> wrote:
>> 
>> I like file scoped private, it's way better than C++'s `friend`. I also often feel that it's unsafe when I've mentally scoped implementation details to a class or extension, but the implementations are in the same file.
>> 
>> I would support something like this:
>>     * `private(module)` alternatively `internal`, the default.
>>     * `private` alternatively `private(file)`
>>     * `private(class)`
>>     * `private(extension)`
>>     * `public`
> 
> I like the basic breakdown of functionality here, but why overload private with so many variations?  This is more verbose than necessary.  I think we can get away with being more clear and concise (access modifiers are decl modifiers, not keywords so they don’t steal identifiers, IIUC).
> 
> Why not this:
> 
>     * `public`
>     * `module`, the default (currently `internal`).
>     * `file` (currently `private`)
>     * `private` (no current equivalent: containing scope whether class, struct, enum, extension, etc)
> 
>> 
>> Perhaps this could let us deprecate/remove the keyword `internal`, I'm not sure of many circumstances when you'd actually need to write it.
>> 
>> I also think that `private(module)` is also more intuitively understood than `internal`.
>> 
>> My reasoning:
>> 
>> This seems to come down to:
>> It lowers the cognitive load if you can put related concepts in the same file.
>> It lowers the cognitive load if you can reduce the number of things a class needs to understand.
>> People like the current system, its simple and it works for them.
>> "Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" - The Elements of Programming Style
>> 
>> On Tue, Jan 26, 2016 at 12:46 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> > On Jan 25, 2016, at 5:47 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> >
>> >
>> > on Mon Jan 25 2016, Ilya Belenkiy <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> >
>> >>> Why should the compiler enforce this? That’s my design decision.
>> >>
>> >> It would enforce whatever design decision you make.
>> >>
>> >>> For the same reason the compiler does not enforce where I have to
>> >>> put „private“ (it can make suggestions like many IDEs do and offer
>> >>> fix-its, like „this method can be made private as it is not used
>> >>> outside the class“ or „this class can be put into its own file as
>> >>> its private methods are not used by other components in this file“.
>> >>
>> >> But once you do put it, it enforces it, and that’s the whole point of having access control.
>> >>
>> >>> No, there is a clear difference: making the type name part of the
>> >>> variable name enforces no compiler checks whereas putting something
>> >>> into different files does.
>> >>
>> >> Similarly, putting all of the source code in the same file is
>> >> equivalent to no checks.
>> >
>> > The place where I'm most concerned about this is in playgrounds.  If
>> > we're going to use them to teach programming, it should be possible to
>> > demonstrate encapsulation there.
>> >
>> 
>> Using playgrounds for teaching is a great example of a use case for this.  Thanks for mentioning it!
>> 
>> I also think the fact that “surrounding scope” is actually the most frequent use of `private` members (in code I have surveyed) indicates that it is a very reasonable feature request.  Allowing us to declare the actual intent aids readability and clarity.
>> 
>> -Matthew
>> 
>> > --
>> > -Dave
>> >
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160126/d9457207/attachment.html>


More information about the swift-evolution mailing list