<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Oct 8, 2016 at 3:24 PM, Karl <span dir="ltr">&lt;<a href="mailto:razielim@gmail.com" target="_blank">razielim@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class="gmail-"><blockquote type="cite"><div>On 8 Oct 2016, at 21:01, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="gmail-m_1533204940674928951Apple-interchange-newline"><div><div dir="ltr" style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote">On Sat, Oct 8, 2016 at 12:02 PM, Karl via swift-evolution<span class="gmail-m_1533204940674928951Apple-converted-space"> </span><span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-<wbr>evolution@swift.org</a>&gt;</span><span class="gmail-m_1533204940674928951Apple-converted-space"> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><span><br><div><blockquote type="cite"><div>On 8 Oct 2016, at 16:47, Braeden Profile &lt;<a href="mailto:jhaezhyr12@gmail.com" target="_blank">jhaezhyr12@gmail.com</a>&gt; wrote:</div><br class="gmail-m_1533204940674928951m_3837719418597257116Apple-interchange-newline"><div><div style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite"><div><br>On Oct 8, 2016, at 6:58 AM, Karl via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail-m_1533204940674928951m_3837719418597257116Apple-interchange-newline"><div><div style="word-wrap:break-word">I was thinking that the domains themselves could be associated with a domain, so you could create alternate domains which are also publicly-visible, but distinct from the default, “public” domain.<div><br></div><div>For example, if you have a bunch of methods which should be visible to subclasses, but you don’t want them to clutter your regular interface. Perhaps they have names which are confusingly-similar to the public API. I believe that is what “protected” is typically used for.</div></div></div></blockquote><div><br></div><div>Yes, but “protected&quot; was specifically put down by the core team, seeing that any code from outside the library should see the class as one well-designed whole, not something with complicated, visible implementation details.  If your class-internal methods are confusing (and aren’t necessary for normal use), they shouldn’t be made public in any way.  Subclasses would too easily confuse the distinction between your implementation methods and your public ones.</div><div><br></div><div>For what it’s worth, I was only confused by “private” and “fileprivate” for a minute or two until I looked up the actual proposal.  I haven’t had trouble with it, and it does actually provide more flexibility for code access at the file level than we had before.  Even if the syntax is clunky.</div></div></div></blockquote></div><br></span><div>I’m not saying that (file)private is confusing - it’s very clear about what it does. But it is limiting; anything that wants access to those semi-private details needs to live in the same file. That’s clearly not scalable. Enormous files many thousands of lines long are easy for the compiler to digest, but less easy for humans to understand and navigate. In fact, I believe this whole “file-based” access control originally came out of the compiler’s implementation details.</div></div></blockquote><div><br></div><div>I&#39;m interested in more information about this. What sorts of code have you been writing where a file would have to be thousands of lines long in order to accommodate `fileprivate`? Many entire modules are only thousands of lines long--is there a reason this code couldn&#39;t be refactored into a module of its own? As mentioned by Matthew, isn&#39;t this calling for some notion of submodules?</div><div><br></div></div></div></div></div></blockquote><div><br></div></span><div>The tab controller was one example:</div><div><br></div><div>- final class TabController : UIViewController</div><div>- final class TabControllerView : UIView</div><div>- final class Tab : UIView</div><div><br></div><div>All of these required knowledge of semi-private implementation details of each-other due to the API I wanted to achieve. I wasn’t interested in factoring out the interfaces in to protocols because they’re all final classes and only supposed to be used with each other. For example, Tab.close() called a fileprivate function in TabController to actually close the tab given an instance of the underlying TabItem data structure.</div></div></div></blockquote><div><br></div><div>That&#39;s interesting. And if you put all the uses of `fileprivate` members of TabController in the same file, that file would be thousands of lines long? Have you explored options where you nest types (e.g. `TabController.View`, which would be able to access private members of `TabController`?)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div>In that case, submodules wouldn’t really help. I could technically define the TabController as a submodule and use “internal”, but that’s also much less than optimal. I want to expose a handful of functions to a handful of other types (and not expose those functions anywhere else - e.g. from my module-internal UIViewControllers which happen to contain a TabController). Also, how would I expose things from the TabController module to the outer module without making it fully &quot;public”?</div></div></div></blockquote><div><br></div><div>If you want to expose only a handful of functions to a handful of other types, it sounds like that would be a good use case for `fileprivate` that would result in a very readable file, no?</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><span class="gmail-"><blockquote type="cite"><div><div dir="ltr" style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>What it would basically come down to is that the interface of the object would be separated in to blocks based on your access privileges. When viewing the interface, it wouldn’t look much different to an extension:</div><div><br></div><div><b>access(public)</b><span class="gmail-m_1533204940674928951Apple-converted-space"> </span>class TabController {</div><div>   var tabs : [Tab] { get }</div><div>   func closeTab(at: Int)</div><div>}</div><div><br></div><div><b>access(TabBarStuff)</b><span class="gmail-m_1533204940674928951Apple-converted-space"> </span>extension TabController {</div><div>   <span class="gmail-m_1533204940674928951Apple-converted-space"> </span>func close(tab: Tab)</div><div>}</div><div><br></div><div>I definitely want something between internal and fileprivate, at least. I don’t see any reason at all why objects shouldn’t be allowed to present optional “slices” of their interface to appropriate clients. In fact, that is what access control is all about. I just want to generalise it to allow for user-defined visibility scopes (as well as the default ones for public, module, file and scope). That leads to the question of what visibility those user-defined scopes would have; and if you leave them entirely open to adopt any scope (except themselves), then you end up with the ability to slice your API for different use-cases. Or we could be boring and limit them to the module they are defined in.</div><div><br></div><div>The whole reason I’m bringing this up is because I don’t like the “file” part of fileprivate. How I split my files up is a readability decision.</div><div><br></div><div>Karl</div></div><br>______________________________<wbr>_________________<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/mailma<wbr>n/listinfo/swift-evolution</a></blockquote></div></div></div></div></blockquote></span></div><br></div></blockquote></div><br></div></div>