<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=""><div class="">This is incorrect; the current Swift model for "private" does not privilege anything in other files (or other modules), even extensions. This proposal does not change that, either for the existing file-private level being renamed, or for the new scope-private level being proposed.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 28, 2016, at 11:54, Jose Cheyo Jimenez via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">That is a deal breaker for me and it is a departure of of the current swift model of localprivate aka private.<div class=""><br class=""></div><div class="">I don’t like it. The introduction of a first class scopeprivate is not worth it if that is one of the tradeoffs.&nbsp;</div><div class=""><br class=""></div><div class="">There are other ways to hide implementation now using nested functions.&nbsp;</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> outside() -&gt; </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> insidelocalfunc() -&gt; </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">2</span><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">insidelocalfunc</span><span style="font-variant-ligatures: no-common-ligatures;" class="">()</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div class=""><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 28, 2016, at 11:16 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=""><div dir="ltr" class=""><span style="" class="">&gt; Would it really make sense to allow extensions in other files to access fileprivate members/funcs?&nbsp;</span><div class=""><br class=""></div><div class="">no, fileprivate is limited to the specific file in which it is used.</div><div class=""><br class=""></div><div class=""><div class="gmail_quote"><div dir="ltr" class="">On Mon, Mar 28, 2016 at 1:13 PM Cheyo Ximenez &lt;<a href="mailto:cheyo@masters3d.com" class="">cheyo@masters3d.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=""></div><div class="">Let's say that we go with&nbsp;</div><div class="">public, moduleprivate, fileprivate, scopeprivate</div><div class=""><br class=""></div><div class="">Would it really make sense to allow extensions in other files to access fileprivate members/funcs?&nbsp; 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).</div><div class=""><br class=""></div><div class="">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.&nbsp;</div></div><div dir="auto" class=""><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class="">On Mar 28, 2016, at 5:46 AM, Ross O'Brien 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 dir="ltr" class=""><div class="">Ilya said:</div><div class="">&gt;&nbsp;<span style="font-size:13px" class="">"public", "protected", and "private" have a very well defined meaning in OOP. We shouldn't redefine them without a good reason.</span></div><div class=""><span style="font-size:13px" class=""><br class=""></span></div><div class=""><span style="font-size:13px" class="">I agree.&nbsp;</span>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.</div><div class=""><br class=""></div><div class="">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.)</div><div class=""><div class=""><br class=""></div><div class="">public, external, internal, private.</div><div class="">public, internal, private, secret.</div><div class="">external, internal, public, private.</div><div class="">public, internal, private, secret.</div><div class="">public, internal, private, local.</div><div class=""><br class=""></div><div class="">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.</div></div><div class=""><br class=""></div><div class=""><span style="font-size:13px" class="">&gt;&nbsp;</span><span style="font-size:13px" class="">Swift allows extensions, so "private" in its standard form doesn't work well -- you could just define an extension and get access to anything.</span><span style="font-size:13px" class="">&nbsp;The scope based private seems to be the most natural extension (pun intended :–)).</span></div><div class=""><span style="font-size:13px" class=""><br class=""></span></div><div class="">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.</div><div class=""><span style="font-size:13px" class=""><br class=""></span></div><div class=""><span style="color:rgb(80,0,80);font-size:13px" class="">&gt; 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&nbsp; for consistency and don't want to argue the edge case in a never ending discussion.</span><br class=""></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.<br class=""></div><div class=""><br class=""></div><div class=""><div class=""><div class="">public, private(module), private(file) and private(scope).</div><div class="">public, moduleprivate, fileprivate, scopeprivate.</div><div class="">public, privatetomodule, privatetofile, privatetoscope.</div></div></div><div class=""><br class=""></div><div class="">I'm tempted to go one further, but if you want to ignore that one further, skip the next two paragraphs:</div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">external, internal(module), internal(file), internal(scope).<br class=""></div><div class=""><div class="">external, moduleinternal, fileinternal, scopeinternal.</div><div class="">external, internaltomodule, internaltofile, internaltoscope.</div></div><div class=""><br class=""></div><div class="">If you ignored that, welcome back.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Every suggestion for relabelling this hierarchy, bar 'public, internal, private, local/scope', breaks code.</div><div class=""><br class=""></div><div class="">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'.</div><div class=""><br class=""></div><div class="">What the proposal as it stands does need to make clear is what would change and what would be left behind.<br class=""></div><div class=""><br class=""></div><div class="">If 'internal' is renamed to 'moduleprivate', explicit uses of 'internal' need to be replaced.</div><div class=""><br class=""></div><div class="">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'.</div><div class=""><br class=""></div><div class="">If 'private' is redefined, it is no nearer to its meaning in other languages than it is now.</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Mon, Mar 28, 2016 at 12:30 PM, Matthew Judge via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote"><span class="">On Mon, Mar 28, 2016 at 6:41 AM, Ilya Belenkiy <span dir="ltr" class="">&lt;<a href="mailto:ilya.belenkiy@gmail.com" target="_blank" class="">ilya.belenkiy@gmail.com</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir="ltr" class="">lexical scope is the other way around: "inner" can see "outer". For example:<div class=""><br class=""></div><div class="">func f() {</div><div class="">&nbsp; let outer = 0</div><div class="">&nbsp;// f cannot use inner</div><div class="">&nbsp; &nbsp;func g() {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;let inner = 1</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;// g can use outer</div><div class="">&nbsp; &nbsp;}</div><div class="">}</div><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div></span><div class="">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()</div><span class=""><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir="ltr" class=""><div class=""></div><div class="">It would work the same way for the access level. That said, I'd rather not include this in the proposal. </div></div></blockquote><div class=""><br class=""></div></span><div class="">So as the proposal stands now, what is the scope that innerVar is visible to in the following code: Inner or Outer?</div><div class=""><br class=""></div><div class="">class Outer {</div><div class="">&nbsp;&nbsp;&nbsp; class Inner {</div><div class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private var innerVar: Int</div><div class=""><div class=""><div class="">&nbsp;&nbsp;&nbsp; }</div><div class="">}</div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir="ltr" class=""><div class="">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.</div><div class=""><div class=""><div class=""><br class=""></div><div class=""><div class="gmail_quote"><div dir="ltr" class="">On Sun, Mar 27, 2016 at 11:17 PM Matthew Judge &lt;<a href="mailto:matthew.judge@gmail.com" target="_blank" class="">matthew.judge@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir="auto" class=""><div class=""></div><div class="">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).</div><div class=""><br class=""></div><div class="">My understanding is that the new private would be:&nbsp;</div><div class="">- visible only to the immediately enclosing scope</div><div class="">- including the scope of a inner nested scope</div><div class="">- not including the scope of an outer nested scope</div><div class="">- not visible to an extension&nbsp;</div><div class=""><br class=""></div><div class="">Said in code (all in the same file):</div><div class="">----------</div><div class="">class Outer { // Outer visible to module</div><div class="">&nbsp; &nbsp; private var a: Int // visible to Outer, Inner1, &amp; Inner2</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; class Inner1 { // Inner1 visible to module</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; private var b: Int // visible to Inner1 only</div><div class="">&nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; private class Inner2 { // visible to Outer &amp; Inner(s)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; var c: Int // visible to Outer &amp; Inner(s)</div><div class="">&nbsp; &nbsp; }</div><div class="">}</div><div class=""><br class=""></div><div class="">extension Outer { // visible to module</div><div class="">&nbsp; &nbsp; // 'a', 'b', and 'Inner2' NOT visible</div><div class="">}</div><div class="">----------</div><div class="">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).</div><div class=""><br class=""></div><div class="">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"</div></div><div dir="auto" class=""><div class=""><br class=""></div><div class=""><br class="">On Mar 27, 2016, at 17:31, Haravikk 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=""><br class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On 27 Mar 2016, at 19:34, Jose Cheyo Jimenez via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div dir="auto" class=""><div class=""><br class=""></div><div class="">Public&nbsp;</div><div class="">External (default)</div><div class="">Internal</div><div class="">Private</div></div></div></blockquote><br class=""></div><div class="">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:</div></div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span style="white-space:pre-wrap" class="">        </span>public<span style="white-space:pre-wrap" class="">                                </span>as-is, item is public/exported outside of module</font></div><div class=""><font face="Monaco" class=""><span style="white-space:pre-wrap" class="">        </span>private(module) or private<span style="white-space:pre-wrap" class="">        </span>current internal, item is private to this module, would be the default</font></div><div class=""><font face="Monaco" class=""><span style="white-space:pre-wrap" class="">        </span>private(file)<span style="white-space:pre-wrap" class="">                        </span>current private, item is private to this file</font></div><div class=""><font face="Monaco" class=""><span style="white-space:pre-wrap" class="">        </span>private(scope)<span style="white-space:pre-wrap" class="">                        </span>new visibility type, item is private to the current scope</font></div><div class=""><br class=""></div><div class="">Assuming I’m understanding the restriction properly this time =)</div><div class=""><br class=""></div><div class="">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.</div></div></blockquote></div><div dir="auto" class=""><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span></div></blockquote></div><div dir="auto" class=""><blockquote type="cite" class=""><div class=""><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></div></div></div>
</blockquote></div></div></div><br class=""></div></div>
<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="">
<br class=""></blockquote></div><br class=""></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></div>
</div></blockquote></div><br class=""></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>