[swift-evolution] SE-0025: Scoped Access Level, next steps

Jose Cheyo Jimenez cheyo at masters3d.com
Mon Mar 28 13:54:33 CDT 2016


That is a deal breaker for me and it is a departure of of the current swift model of localprivate aka private.

I don’t like it. The introduction of a first class scopeprivate is not worth it if that is one of the tradeoffs. 

There are other ways to hide implementation now using nested functions. 

func outside() -> Int{
    func insidelocalfunc() -> Int {return 2}
    return insidelocalfunc()
}



> On Mar 28, 2016, at 11:16 AM, Ilya Belenkiy <ilya.belenkiy at gmail.com> wrote:
> 
> > Would it really make sense to allow extensions in other files to access fileprivate members/funcs? 
> 
> no, fileprivate is limited to the specific file in which it is used.
> 
> On Mon, Mar 28, 2016 at 1:13 PM Cheyo Ximenez <cheyo at masters3d.com <mailto:cheyo at masters3d.com>> wrote:
> Let's say that we go with 
> public, moduleprivate, fileprivate, scopeprivate
> 
> Would it really make sense to allow extensions in other files to access fileprivate members/funcs?  The inclusion of the word 'file' in the name would make it confusing that extensions have the special power to reach into a fileprivate from another file. This almost begs for another access like typeprivate (I am not proposing this).
> 
> My understating is that scopeprivate came about as a way to deal with extensions, perhaps the author needs to look into a way to tag methods/members as not extendable or hidden from extensions only. The solution would probably be swift specific and it should probably brake out from the norm of other languages. 
> 
> 
> 
> 
> 
> 
> 
> On Mar 28, 2016, at 5:46 AM, Ross O'Brien via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>> Ilya said:
>> > "public", "protected", and "private" have a very well defined meaning in OOP. We shouldn't redefine them without a good reason.
>> 
>> I agree. Swift has a scope-based visibility system, not a type-based visibility system, but because Swift redefines the terms 'public' and 'private', programmers keep getting confused about how they're used in Swift.
>> 
>> Over the last few posts, since Chris Lattner proposed switching to: 'public, internal, X, private', we've had several new scales proposed. (In every scale in this post, there are four terms in order of decreasing visibility, with the second term being the default.)
>> 
>> public, external, internal, private.
>> public, internal, private, secret.
>> external, internal, public, private.
>> public, internal, private, secret.
>> public, internal, private, local.
>> 
>> At this point, respectfully, I think we can dismiss the idea that labelling any given level as 'public' or 'private' is right or obvious. Swift is built around clarity at the point of use. 'private' is not as clear as you maintain it is.
>> 
>> > Swift allows extensions, so "private" in its standard form doesn't work well -- you could just define an extension and get access to anything. The scope based private seems to be the most natural extension (pun intended :–)).
>> 
>> We're redefining terms from a type-based visibility scale to a scope-based visibility scale. I'm not disagreeing that an extension would allow access to type-visible symbols and that this might not be the programmer's intention, but that 'private' has a clear meaning in OOP and repurposing 'private' is not resolving any confusion.
>> 
>> > I'd like to keep "private" to be completely private and not allow class injection to gain access, but this is an edge case that could be argued either way. I can definitely live with a pure scoped access  for consistency and don't want to argue the edge case in a never ending discussion.
>> 
>> As far as I know, it's not an edge case in Swift, it's a non-case. Swift doesn't have type-based visibility. Using Swift's system, I do understand that you want 'private' to refer to the least-visible level in the hierarchy.
>> 
>> However, as has already been pointed out, the scope-visible level is not the least-visible conceivable. There's already discussion over whether the properties of inner types should be visible to their outer types. If that ever made its way to a proposal, would that level become 'private'? I think we can agree that another bikeshedding conversation like this would rather be avoided.
>> 
>> There's also the possibility of a 'submodule' level. Chris Lattner suggested that the 'private(foo.bar)' syntax might be best for this, but I don't know what that means - whether 'submodule' would be within the Swift hierarchy or not - but it's a possibility for the future.
>> 
>> I'm repeating myself, but: inclusion of the terms 'module', 'file', and 'scope' in our symbols is winning out in clarity. None of those terms has changed meaning in the entire discussion. The only question is exactly how they should be welded to the term 'private'. There've been three suggestions for doing this so far and they're all awkward, either because they have parentheses or they're conjoined, but they're unambiguous in meaning and no-one's suggested any single-word ideas with the same clarity.
>> 
>> public, private(module), private(file) and private(scope).
>> public, moduleprivate, fileprivate, scopeprivate.
>> public, privatetomodule, privatetofile, privatetoscope.
>> 
>> I'm tempted to go one further, but if you want to ignore that one further, skip the next two paragraphs:
>> 
>> Abandon the words 'public' and 'private'. Let's just accept that, together with 'protected', these are well-defined terms of type-based visibility in OOP which are orthogonal to Swift's hierarchy, and that redefining them leads to confusion. Embrace 'external' and 'internal' in their places:
>> 
>> external, internal(module), internal(file), internal(scope).
>> external, moduleinternal, fileinternal, scopeinternal.
>> external, internaltomodule, internaltofile, internaltoscope.
>> 
>> If you ignored that, welcome back.
>> 
>> I hope I've not been too antagonistic about this. I really want Swift to use terms with clear meaning, and if that breaks code, I want a clean break that can be easily healed / migrated.
>> 
>> Every suggestion for relabelling this hierarchy, bar 'public, internal, private, local/scope', breaks code.
>> 
>> Adding the scope-visible level allows for greater control, but I don't believe module-visible and file-visible levels would be uncommon with its inclusion, so the terms for all three - all four, really - should be balanced in their 'ugliness'.
>> 
>> What the proposal as it stands does need to make clear is what would change and what would be left behind.
>> 
>> If 'internal' is renamed to 'moduleprivate', explicit uses of 'internal' need to be replaced.
>> 
>> If there are constants, 'global' functions, operators, or anything that can be defined outside of a scope, their least visible level is fileprivate. They can never be 'scope-private'.
>> 
>> If 'private' is redefined, it is no nearer to its meaning in other languages than it is now.
>> 
>> 
>> On Mon, Mar 28, 2016 at 12:30 PM, Matthew Judge via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> 
>> On Mon, Mar 28, 2016 at 6:41 AM, Ilya Belenkiy <ilya.belenkiy at gmail.com <mailto:ilya.belenkiy at gmail.com>> wrote:
>> lexical scope is the other way around: "inner" can see "outer". For example:
>> 
>> func f() {
>>   let outer = 0
>>  // f cannot use inner
>>    func g() {
>>        let inner = 1
>>        // g can use outer
>>    }
>> }
>> 
>> 
>> Maybe I'm off in my terminology, but I think my code example matches what you are saying here (outer is visible to g() but inner is not visible to f()
>>  
>> It would work the same way for the access level. That said, I'd rather not include this in the proposal.
>> 
>> So as the proposal stands now, what is the scope that innerVar is visible to in the following code: Inner or Outer?
>> 
>> class Outer {
>>     class Inner {
>>         private var innerVar: Int
>>     }
>> }
>>  
>> The only change that the core team requested was the name changes. I personally would prefer a completely private version where you cannot inject a class into a scope to get access to the scope internals, but it's an edge case that could be argued either way, and I don't want to start another lengthy discussion. We already had quite a few.
>> 
>> On Sun, Mar 27, 2016 at 11:17 PM Matthew Judge <matthew.judge at gmail.com <mailto:matthew.judge at gmail.com>> wrote:
>> I know it was suggested that it be the subject of a different thread, but it might be good to clarify how the new private is going to work (or at least what is currently envisioned).
>> 
>> My understanding is that the new private would be: 
>> - visible only to the immediately enclosing scope
>> - including the scope of a inner nested scope
>> - not including the scope of an outer nested scope
>> - not visible to an extension 
>> 
>> Said in code (all in the same file):
>> ----------
>> class Outer { // Outer visible to module
>>     private var a: Int // visible to Outer, Inner1, & Inner2
>> 
>>     class Inner1 { // Inner1 visible to module
>>         private var b: Int // visible to Inner1 only
>>     }
>>     private class Inner2 { // visible to Outer & Inner(s)
>>         var c: Int // visible to Outer & Inner(s)
>>     }
>> }
>> 
>> extension Outer { // visible to module
>>     // 'a', 'b', and 'Inner2' NOT visible
>> }
>> ----------
>> If this is the intended meaning of private, then fileprivate seems to be the same as private (private to the enclosing scope... which happens to be the file).
>> 
>> Something declared "private" at the top level of a file is fileprivate. There would still need to be a way to reference scopes other than the immediate one (especially since there is no way to say "private" and mean moduleprivate), though I think it would strengthen the argument for something along the lines of "private(file)", since it would even further reduce the cases where you are spelling something more than just "private"
>> 
>> 
>> On Mar 27, 2016, at 17:31, Haravikk via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> 
>>>> On 27 Mar 2016, at 19:34, Jose Cheyo Jimenez via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> 
>>>> Public 
>>>> External (default)
>>>> Internal
>>>> Private
>>> 
>>> I still feel like these are still too vague; I’m not sure I like the use of external, as public to me is external since it exports outside of the module, whereas what you’re proposing is in fact just limited to the module itself. I dislike the current internal keyword too, but at least it reads as “internal to this module", this is why the more specific terms are better like:
>>> 
>>> 	public				as-is, item is public/exported outside of module
>>> 	private(module) or private	current internal, item is private to this module, would be the default
>>> 	private(file)			current private, item is private to this file
>>> 	private(scope)			new visibility type, item is private to the current scope
>>> 
>>> Assuming I’m understanding the restriction properly this time =)
>>> 
>>> It’s also the easiest method if we do add another visibility later for sub-classes such as private(type), as it doesn’t even require a new keyword.
>> 
>>> _______________________________________________
>> 
>>> 
>>> 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>
>> 
>> 
>> _______________________________________________
>> 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/20160328/30072599/attachment.html>


More information about the swift-evolution mailing list