<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 24, 2016, at 9:59 AM, Ilya Belenkiy &lt;<a href="mailto:ilya.belenkiy@gmail.com" class="">ilya.belenkiy@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">I am not sure if consistency is a problem here. My primary concern is that as long as the class or extension code itself hasn't changed, it's private API stays hidden from anything else. If we can simply inject a class into a class or extension and get access to all of its internals, that reduces the protection level that private would provide. I'd like private to hide implementation details completely.<br class=""></div></blockquote><div><br class=""></div><div>That wouldn’t be possible because the semantics are scope-based, not type-based. &nbsp;</div><div><br class=""></div><div>Here’s an example (using the new “private” modifier):</div><div><br class=""></div><div>fileA.swift:</div><div><br class=""></div><div>class C {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>private let s: String</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>class Nested {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>func foo() {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>let c = C()</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>// s is visible here because `Nested` and `foo`&nbsp;</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>//&nbsp;are within the lexical scope that declared `s`</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>let s = c.s</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>}</div><div><br class=""></div><div><div>extension C {</div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>// `s` is not visible anywhere here</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// because we are not within the lexical scope</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// where `s` was declared</div><div>}</div></div><div><br class=""></div><div>fileB.swift:</div><div><br class=""></div><div>extension C {</div><div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>// `s` is not visible anywhere here</div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>// because we are not within the lexical scope</div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>// where `s` was declared</div></div><div>}</div><br class=""><blockquote type="cite" class=""><div class=""><br class="">That said, I am not sure if we need to discuss it as part of this proposal.<br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Mar 24, 2016 at 10:28 AM Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class=""><div class=""><br class=""><br class="">Sent from my iPad</div></div><div dir="auto" class=""><div class=""><br class="">On Mar 24, 2016, at 8:40 AM, Ilya Belenkiy &lt;<a href="mailto:ilya.belenkiy@gmail.com" target="_blank" class="">ilya.belenkiy@gmail.com</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="white-space:pre-wrap" class="">The discussion was about the other direction: whether a nested class should have access to private members of the outer class.</div></div></blockquote><div class=""><br class=""></div></div><div dir="auto" class="">In that case the answer seems clear as well.&nbsp; Everywhere in Swift's access model nested scopes have visibility to all members visible in the containing scope.&nbsp; For example, all scopes in a file can see any "fileprivate" members contained in that file. &nbsp;<div class=""><br class=""></div><div class="">Following this semantic, all nested types would be able to see members of their containing type, even those with the new "private" visibility because the nested types are within the same scope where those members are declared.&nbsp;</div><div class=""><br class=""></div><div class="">Semantic consistency is the most important concern IMO.&nbsp; All current access modifiers are strictly based on nested scopes.&nbsp; Hiding members of a containing type from a nested type would break this model and introduce type-driven semantics, which I think (and hope) is beyond the scope of this proposal (pun mildly intended).</div></div><div dir="auto" class=""><div class=""><br class=""></div><div class="">Matthew</div></div><div dir="auto" class=""><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Mar 24, 2016 at 9:35 AM Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" target="_blank" class="">matthew@anandabits.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class=""><div class=""><br class=""><br class="">Sent from my iPad</div></div><div dir="auto" class=""><div class=""><br class="">On Mar 24, 2016, at 5:07 AM, Ilya Belenkiy via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="white-space:pre-wrap" class="">It's very consistent with other keywords. I wish compound keywords were joined with a dash or something that made them easier to read, but I guess it's too late now. If we have associatedtype, it makes sense to use moduleprivate (I saw that the name  associatedtype was discussed extensively but didn't participate in the discussion; I am sure that it was given a lot of thought). If we could change this, I'd suggest keyword names with dashes everywhere, but if not, these names work well and is a great compromise for everything I've seen in this thread.<br class=""><br class="">I am not worried about the length because the 2 most frequently written keywords would be public and private. Moduleprivate is the default, and file private will not be used as often as private.<br class=""><br class="">One question: should the proposal be explicit about access control for nested classes? We discussed it here briefly (I wanted private to be completely private to the class or extension itself while 2 other people wanted a nested class to have access to the outer class.)</div></div></blockquote><div class=""><br class=""></div></div><div dir="auto" class=""><div class="">I don't think it would make sense at all to allow an outer type to see private members of a nested class.&nbsp; That would break the semantics of private meaning "containing scope".</div><div class=""><br class=""></div><div class="">However, with Chris's suggestion of using identifiers as parameters, maybe we could eventually have something like private(OuterTypeName) to specify the precise level of access desired.</div></div><div dir="auto" class=""><br class=""><blockquote type="cite" class=""><div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Mar 24, 2016 at 1:13 AM Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">&lt;responding to several posts in this thread at once&gt;<br class="">
<br class="">
On Mar 14, 2016, at 5:18 PM, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt; Per Doug’s email, the core team agrees we should make a change here, but would like some bikeshedding to happen on the replacement name for private.<br class="">
<br class="">
What we do with private setters is orthogonal from this proposal, so I’m going to ignore it in this thread.&nbsp; After SE-0025 is resolved, it would be great to have another thread/proposal that discusses reskinning private(set) - presumably as just a modifier on the setter.<br class="">
<br class="">
Similarly, this proposal has nothing to do with “protected” or any other type based access control, so I don’t delve into that at all either.<br class="">
<br class="">
I’ve seen several proposals that seem promising:<br class="">
<br class="">
On Mar 14, 2016, at 5:49 PM, James Berry &lt;<a href="mailto:jberry@rogueorbit.com" target="_blank" class="">jberry@rogueorbit.com</a>&gt; wrote:<br class="">
&gt; I like fileprivate, if that’s the only change. On the other hand, if we want to consider a broader change, what about:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp;private&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;symbol visible within the current declaration (class, extension, etc).<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp;private(module) symbol visible within the current module.<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp;private(file)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;symbol visible within the current file.<br class="">
<br class="">
I love how this establishes a family with different levels of access control, and unites them under the idea of "levels of being private”.&nbsp; I also like how people would commonly only ever write public and private (because “private(module)” is the default, and "private(file)" is obscure).&nbsp; However, parenthesized modifiers that take a keyword (as opposed to an identifier) are a bit weird and awkward, so it would be nice to avoid them if possible.<br class="">
<br class="">
On Mar 15, 2016, at 3:39 AM, Thorsten Seitz via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt; public<br class="">
&gt; private-module<br class="">
&gt; private-file<br class="">
&gt; private<br class="">
<br class="">
This follows the same sort of structure as James’ proposal, without the parens.&nbsp; It has the same advantages, but trades them with hyphenated decl modifiers.&nbsp; We don’t do that, but it is a good direction.<br class="">
<br class="">
How about we continue this trend, and follow other existing Swift keywords that merge two lowercase words (associatedtype, typealias, etc), and use:<br class="">
<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; public<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; moduleprivate<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; fileprivate<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; private<br class="">
<br class="">
The advantages, as I see them are:<br class="">
1) We keep public and private meaning the “right” and “obvious” things.<br class="">
2) The declmodifiers “read” correctly.<br class="">
3) The unusual ones (moduleprivate and fileprivate) don’t use the awkward parenthesized keyword approach.<br class="">
4) The unusual ones would be “googable”.<br class="">
5) Support for named submodules could be “dropped in” by putting the submodule name/path in parens: private(foo.bar.baz) or moduleprivate(foo.bar).&nbsp; Putting an identifier in the parens is much more natural than putting keywords in parens.<br class="">
<br class="">
What do you all think?<br class="">
<br class="">
-Chris<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</blockquote></div>
</div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></blockquote></div>
</div></blockquote></div></div></div></blockquote></div>
</div></blockquote></div><br class=""></body></html>