<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Thanks Drew,</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">This and your previous email have provided a good use case and shifted my view towards the positive. +0.5 now as I'm still not sure it a definite win worthy of the addition to the language but I think it might be. I'll continue thinking about it. </div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Joseph</div><div><br>On 27 Feb 2016, at 05:46, Drew Crawford via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">I’m unsure what you are imagining here - compiler protection of class details from within a closure completion handler that is also part of your class definition?</div></div></blockquote><div class=""><br class=""></div>What i mean here is simply<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">class Foo {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>///it is undefined behavior to access this variable except from specialQueue</div><div class=""> private var _specialQueueOnly = 0</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>public var specialQueueOnly: Int {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>var i: I! = nil</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>dispatch_sync(specialQueue) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>i = _specialQueueOnly</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>return i</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class="">The lynchpin of this defensive programming technique is that only these 12 lines of code have any risk of a threading bug, and we can trivially inspect the 12 lines. So our safety hangs on two tentpegs:</div><div class=""><br class=""></div><div class="">1. That "private" in "private var _specialQueue" is compiler enforcement against other files trying to access this ivar</div><div class="">2. That the file itself is 12 (or other minimal number of) lines and trivially inspectable.</div><div class=""><br class=""></div><div class="">Should we violate any of these constraints, we lose our safety.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">It may be that I’m unfamiliar with UITableViewCellContentView (as it is not documented).</blockquote></div><div class=""><br class=""></div><div class="">Well, that is kind of the point: Objective-C's access control worked, and prevented you from knowing about this class. </div><div class=""><br class=""></div><div class="">But to provide a more accessible illustration, consider the case where we have some motivation to hide Foo from the rest of our framework[/module/target/application/executable/library]. This is more likely to happen in a UIKit-sized project, where there are hundreds of public classes, and probably thousands of "internal" ones, and a typical class has motivation to touch 5 or 6 other classes, of the thousands that may be available.</div><div class=""><br class=""></div><div class="">In Swift, each internal class is visible to every other class. But that is not especially workable at UIKit scale; if every class can potentially reach every other class we are in for an adventure when one of the hundred developers on your team decides that some UITableView implementation detail you've never heard of should be accessing some UILocalNotification detail you've also never heard of. So we need some kind of "fencing" within a large framework to make good neighbors.</div><div class=""><br class=""></div><div class="">This is solved very easily: we can group several related classes into one file, and some of the classes are private. Many ordinary people today group related classes into a file as a fencing mechanism even not at UIKit-scale. So a file can access all of its own classes, but not all the classes of other files. That creates the "fence", and now your coworker cannot draw a line between some UITableView secret class and some UILocalNotification secret class, and your desk will not be dented from the impact of your forehead.</div><div class=""><br class=""></div><div class="">The problem now is that while fixing this situation we have broken one of our safety tentpegs. We earlier required that Foo.swift be only 12 lines for thread safety, but now Foo is contained in a larger file so as to create a fence. So we can solve one of these problems or the other one, but never both at the same time.</div><div class=""><br class=""></div><div class="">"local" effectively resolves this dilemma, because if our _specialQueueOnly variable is local, then it is not the /file/ which must be kept to 12 lines, but the /scope/. So we could group an unlimited number of classes in Foo.swift, with no loss of confidence for our thread safety.</div><div class=""><br class=""></div><div class="">A better approach might be to realize that if global scope, target scope, and file scope do not solve the visibility problem, perhaps yet another scope will not totally solve the problem either. I fully expect Apple will need a "vendor" scope for example (so that UIKit and CoreAnimation, two public frameworks, can still have private APIs between them), and I bet there are many more kinds of scopes that have not yet occurred to me.</div><div class=""><br class=""></div><div class="">Behind that realization lies the Rust system, which divorces visibility from these arbitrary scopes that we seem to be struggling to fit into. But that proposal isn't before us, and this one is. I prefer going somewhere to staying here.</div><div class=""><br class=""></div><div class="">Drew</div><div class=""> </div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 26, 2016, at 10:34 PM, David Waite <<a href="mailto:david@alkaline-solutions.com" class="">david@alkaline-solutions.com</a>> 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=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 26, 2016, at 8:44 PM, Drew Crawford via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Threading is one especially pernicious case. If I have an ivar that is only safe for access from one thread, I *need* compiler enforcement. I *need* a guarantee that this ivar is only accessed through public interface methods that can be audited to be threadsafe. Simply a doccomment that says "bad programmer, don't do it" is not enough.</div></div></div></blockquote><div class=""><br class=""></div>I’m unsure what you are imagining here - compiler protection of class details from within a closure completion handler that is also part of your class definition? I believe you would only get this with this local scope proposal if you structured your code such that callback blocks were functions outside your type definition.</div><div class=""><br class=""></div><div class="">If you are talking about access or modification of the inner state of a class and a manual audit of safety, that audit is of the file and not of the type or extension. I’m unsure if your concern is of having to split code into multiple files for safety, or that there is not a way to split code into multiple files to achieve safety in some particular scenario.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">This is not even a matter of "artistic choice" of whether or not I want to follow "one file per class". I can achieve thread safety with "private" ivars and "one file per class", but if my class is UITableViewCellContentView (which is an implementation detail that should be hidden even to most of UIKit) I am now forced to expose that implementation detail to my entire team.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">This places me in the unconscionable situation of choosing between whether I have thread safety or encapsulation, between whether my coworker will accidentally create a threading bug or accidentally use a class they ought not to use and I am unable to appropriately hide.</div></div></blockquote><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""></div></div></div></div>I’m not quite sure what you mean here - exposing that your class is a subclass of UITableViewCellContentView? Or that the rest of your team needs to code in different files from your class in order to maintain encapsulation?</div><div class=""><br class=""></div><div class="">It may be that I’m unfamiliar with UITableViewCellContentView (as it is not documented).</div><div class=""><br class=""></div><div class=""><snip></div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><ul class="" style="box-sizing: border-box; padding: 0px 0px 0px 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><li class="" style="box-sizing: border-box;">How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</li></ul></div></blockquote><div class="">I've followed this from the earliest discussions. I've rethought my position somewhat in response to the growing uncertainty about dropping the NS prefix, which I think exposes some very real problems with visibility in Swift.</div></div><div class=""><br class=""></div><div class="">As that situation has developed, I no longer believe this proposal goes far enough. But it does go somewhere, and we should not stay where we are.</div></div></div></blockquote><div class=""><br class=""></div>I don’t understand how an access control proposal pertains to changes in the Foundation public API. What is the ideal end state in your mind, and in what way is this a step toward that?</div><div class=""><br class=""></div><div class="">-DW</div><div class=""><br class=""></div><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>