<div dir="ltr">I'm broadly in favor of this.<br><br><div class="gmail_quote"><div dir="ltr">On Mon, Apr 3, 2017 at 2:35 PM Douglas Gregor via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">Hello Swift Community,<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In rejecting <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md" class="gmail_msg" target="_blank">SE-0159</a>, the core team described a potential direction we would like to investigate for “private” access control that admits a limited form of type-based access control within files. The core team is seeking some discussion here and a motivated volunteer to put together a proposal along these lines for review in the Swift 4 time-frame (i.e., very soon). To be clear, the core team it’s sure this is the right direction to go… but it appears promising and we would *love* to be able to settle the access-control issue.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">The design, specifically, is that a “private” member declared within a type “X” or an extension thereof would be accessible from:</div><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>* An extension of “X” in the same file</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>* The definition of “X”, if it occurs in the same file</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>* A nested type (or extension thereof) of one of the above that occurs in the same file</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">This design has a number of apparent benefits:</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>+ “private” becomes the right default for “less than whole module” visibility, and aligns well with Swift coding style that divides a type’s definition into a number of extensions.</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>+ “fileprivate” remains for existing use cases, but now it’s use it more rare, which has several advantages:</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>+ It fits well with the "progressive disclosure” philosophy behind Swift: you can use public/internal/private for a while before encountering and having to learn about “fileprivate” (note: we thought this was going to be true of <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md" class="gmail_msg" target="_blank">SE-0025</a>, but we were clearly wrong)</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>+ When “fileprivate” occurs, it means there’s some interesting coupling between different types in the same file. That makes fileprivate a useful alert to the reader rather than, potentially, something that we routinely use and overlook so that we can separate implementations into extensions.</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>+ “private” is more closely aligned with other programming languages that use type-based access control, which can help programmers just coming to Swift. When they reach for “private”, they’re likely to get something similar to what they expect—with a little Swift twist due to Swift’s heavy use of extensions.</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>+ Loosening the access restrictions on “private” is unlikely to break existing code.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">There are likely some drawbacks:</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>- Developers using patterns that depend on the existing lexically-scoped access control of “private” may find this new interpretation of “private” to be insufficiently strict</div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>- Swift’s access control would go from “entirely lexical” to “partly lexical and partly type-based”, which can be viewed as being more complicated</div></div></div></blockquote><div><br></div><div>I think it might not as complicated as it may first appear. I haven't fully convinced myself of this, but I believe that it would be lexically scoped <i>modulo inlining extensions</i>.</div><div><br></div><div>To put it somewhat more formally (and awkwardly), if one imagines a textual transformation which blindly inlines any extension in a single file into their type definitions (should those definitions occur within that file) then accessing a "private" member in the original file would compile if and only if the access would be lexically scoped if the above postulated transformation were to be applied to it.</div><div><br></div><div>This is a pleasing property (to me anyway) as it means that it is unlikely (impossible?) for moving code from one extension (or definition) to another to cause a compilation failure.</div><div><br></div><div>Take this with a grain of salt of course, as there's probably an edge case I'm not thinking of :P (This is why we write proofs!)</div><div><br></div><div>Cheers,</div><div>-Colin</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"></div></div><div class="gmail_msg">Thoughts? Volunteer?</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><span class="m_-3904724525666079602Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>- Doug</div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div></div>