<div dir="ltr">Allowing extensions within a module to introduce stored properties would be a great addition to the language, but it&#39;s a completely different matter. A language shouldn&#39;t dictate file structure. It may make sense to keep related classes in the same file for easier access rather than having tiny files for every scope. &quot;scoped&quot; is much clearer about intent then &quot;private&quot;. It says that something must be hidden in the scope regardless of where the code is.</div><br><div class="gmail_quote"><div dir="ltr">On Sat, Feb 27, 2016 at 8:04 PM Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Drew Crawford via swift-evolution<br>
&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt; I’m unsure what you are imagining here - compiler protection of class<br>
&gt;&gt; details from within a closure completion handler that is also part of<br>
&gt;&gt; your class definition?<br>
&gt;<br>
&gt; What i mean here is simply<br>
&gt;<br>
&gt; class Foo {<br>
&gt;       ///it is undefined behavior to access this variable except from specialQueue<br>
&gt;        private var _specialQueueOnly = 0<br>
&gt;<br>
&gt;       public var specialQueueOnly: Int {<br>
&gt;               var i: I! = nil<br>
&gt;               dispatch_sync(specialQueue) {<br>
&gt;                       i = _specialQueueOnly<br>
&gt;               }<br>
&gt;               return i<br>
&gt;       }<br>
&gt; }<br>
&gt;<br>
&gt; The lynchpin of this defensive programming technique is that only these<br>
&gt; 12 lines of code have any risk of a threading bug, and we can trivially<br>
&gt; inspect the 12 lines.  So our safety hangs on two tentpegs:<br>
&gt;<br>
&gt; 1.  That &quot;private&quot; in &quot;private var _specialQueue&quot; is compiler enforcement<br>
&gt; against other files trying to access this ivar<br>
&gt; 2.  That the file itself is 12 (or other minimal number of) lines and<br>
&gt; trivially inspectable.<br>
&gt;<br>
&gt; Should we violate any of these constraints, we lose our safety.<br>
<br>
Allowing extensions within a module to introduce stored properties might be<br>
another possible way of enabling this, since you could then factor the<br>
private storage and its concurrency-safe accessors into a separate file.<br>
Looking further into the future, our concurrency model will hopefully have<br>
some mechanism for isolating state, by actors or some other means.<br>
<br>
-Joe<br>
<br>
&gt;<br>
&gt;&gt; It may be that I’m unfamiliar with UITableViewCellContentView (as it is not documented).<br>
&gt;<br>
&gt;<br>
&gt; Well, that is kind of the point: Objective-C&#39;s access control worked, and<br>
&gt; prevented you from knowing about this class.<br>
&gt;<br>
&gt; But to provide a more accessible illustration, consider the case where we<br>
&gt; have some motivation to hide Foo from the rest of our<br>
&gt; framework[/module/target/application/executable/library].  This is more<br>
&gt; likely to happen in a UIKit-sized project, where there are hundreds of<br>
&gt; public classes, and probably thousands of &quot;internal&quot; ones, and a typical<br>
&gt; class has motivation to touch 5 or 6 other classes, of the thousands that may be available.<br>
&gt;<br>
&gt; In Swift, each internal class is visible to every other class.  But that<br>
&gt; is not especially workable at UIKit scale; if every class can potentially<br>
&gt; reach every other class we are in for an adventure when one of the<br>
&gt; hundred developers on your team decides that some UITableView<br>
&gt; implementation detail you&#39;ve never heard of should be accessing some<br>
&gt; UILocalNotification detail you&#39;ve also never heard of.  So we need some<br>
&gt; kind of &quot;fencing&quot; within a large framework to make good neighbors.<br>
&gt;<br>
&gt; This is solved very easily: we can group several related classes into one<br>
&gt; file, and some of the classes are private.  Many ordinary people today<br>
&gt; group related classes into a file as a fencing mechanism even not at<br>
&gt; UIKit-scale.  So a file can access all of its own classes, but not all<br>
&gt; the classes of other files.  That creates the &quot;fence&quot;, and now your<br>
&gt; coworker cannot draw a line between some UITableView secret class and some<br>
&gt; UILocalNotification secret class, and your desk will not be dented from<br>
&gt; the impact of your forehead.<br>
&gt;<br>
&gt; The problem now is that while fixing this situation we have broken one of<br>
&gt; our safety tentpegs.  We earlier required that Foo.swift be only 12 lines<br>
&gt; for thread safety, but now Foo is contained in a larger file so as to<br>
&gt; create a fence.  So we can solve one of these problems or the other one,<br>
&gt; but never both at the same time.<br>
&gt;<br>
&gt; &quot;local&quot; effectively resolves this dilemma, because if our<br>
&gt; _specialQueueOnly variable is local, then it is not the /file/ which must<br>
&gt; be kept to 12 lines, but the /scope/.  So we could group an unlimited<br>
&gt; number of classes in Foo.swift, with no loss of confidence for our thread safety.<br>
&gt;<br>
&gt; A better approach might be to realize that if global scope, target scope,<br>
&gt; and file scope do not solve the visibility problem, perhaps yet another<br>
&gt; scope will not totally solve the problem either.  I fully expect Apple<br>
&gt; will need a &quot;vendor&quot; scope for example (so that UIKit and CoreAnimation,<br>
&gt; two public frameworks, can still have private APIs between them), and I<br>
&gt; bet there are many more kinds of scopes that have not yet occurred to me.<br>
&gt;<br>
&gt; Behind that realization lies the Rust system, which divorces visibility<br>
&gt; from these arbitrary scopes that we seem to be struggling to fit into.<br>
&gt; But that proposal isn&#39;t before us, and this one is.  I prefer going<br>
&gt; somewhere to staying here.<br>
&gt;<br>
&gt; Drew<br>
&gt;<br>
&gt;<br>
&gt;&gt; On Feb 26, 2016, at 10:34 PM, David Waite<br>
&gt;&gt; &lt;<a href="mailto:david@alkaline-solutions.com" target="_blank">david@alkaline-solutions.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; On Feb 26, 2016, at 8:44 PM, Drew Crawford via swift-evolution<br>
&gt;&gt;&gt; &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt;&gt;&gt; &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;&gt; wrote:<br>
&gt;&gt;&gt; Threading is one especially pernicious case.  If I have an ivar that is<br>
&gt;&gt;&gt; only safe for access from one thread, I *need* compiler enforcement.  I<br>
&gt;&gt;&gt; *need* a guarantee that this ivar is only accessed through public<br>
&gt;&gt;&gt; interface methods that can be audited to be threadsafe.  Simply a<br>
&gt;&gt;&gt; doccomment that says &quot;bad programmer, don&#39;t do it&quot; is not enough.<br>
&gt;&gt;<br>
&gt;&gt; I’m unsure what you are imagining here - compiler protection of class<br>
&gt;&gt; details from within a closure completion handler that is also part of<br>
&gt;&gt; your class definition? I believe you would only get this with this local<br>
&gt;&gt; scope proposal if you structured your code such that callback blocks<br>
&gt;&gt; were functions outside your type definition.<br>
&gt;&gt;<br>
&gt;&gt; If you are talking about access or modification of the inner state of a<br>
&gt;&gt; class and a manual audit of safety, that audit is of the file and not of<br>
&gt;&gt; the type or extension. I’m unsure if your concern is of having to split<br>
&gt;&gt; code into multiple files for safety, or that there is not a way to split<br>
&gt;&gt; code into multiple files to achieve safety in some particular scenario.<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; This is not even a matter of &quot;artistic choice&quot; of whether or not I want<br>
&gt;&gt;&gt; to follow &quot;one file per class&quot;.  I can achieve thread safety with<br>
&gt;&gt;&gt; &quot;private&quot; ivars and &quot;one file per class&quot;, but if my class is<br>
&gt;&gt;&gt; UITableViewCellContentView (which is an implementation detail that<br>
&gt;&gt;&gt; should be hidden even to most of UIKit) I am now forced to expose that<br>
&gt;&gt;&gt; implementation detail to my entire team.<br>
&gt;&gt;<br>
&gt;&gt;&gt; This places me in the unconscionable situation of choosing between<br>
&gt;&gt;&gt; whether I have thread safety or encapsulation, between whether my<br>
&gt;&gt;&gt; coworker will accidentally create a threading bug or accidentally use a<br>
&gt;&gt;&gt; class they ought not to use and I am unable to appropriately hide.<br>
&gt;&gt;<br>
&gt;&gt; I’m not quite sure what you mean here - exposing that your class is a<br>
&gt;&gt; subclass of UITableViewCellContentView? Or that the rest of your team<br>
&gt;&gt; needs to code in different files from your class in order to maintain encapsulation?<br>
&gt;&gt;<br>
&gt;&gt; It may be that I’m unfamiliar with UITableViewCellContentView (as it is not documented).<br>
&gt;&gt;<br>
&gt;&gt; &lt;snip&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt;&gt; How much effort did you put into your review? A glance, a quick<br>
&gt;&gt;&gt;&gt; reading, or an in-depth study?<br>
&gt;&gt;&gt; I&#39;ve followed this from the earliest discussions.  I&#39;ve rethought my<br>
&gt;&gt;&gt; position somewhat in response to the growing uncertainty about dropping<br>
&gt;&gt;&gt; the NS prefix, which I think exposes some very real problems with visibility in Swift.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; As that situation has developed, I no longer believe this proposal goes<br>
&gt;&gt;&gt; far enough.  But it does go somewhere, and we should not stay where we are.<br>
&gt;&gt;<br>
&gt;&gt; I don’t understand how an access control proposal pertains to changes in<br>
&gt;&gt; the Foundation public API. What is the ideal end state in your mind, and<br>
&gt;&gt; in what way is this a step toward that?<br>
&gt;&gt;<br>
&gt;&gt; -DW<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>