<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=""><div><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=""><div class=""><blockquote type="cite" class=""><div class="">On Apr 5, 2017, at 6:54 PM, Nevin Brackett-Rozinsky via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Apr 5, 2017 at 12:02 AM, Chris Lattner via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<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" class=""><div class=""><div class=""><br class=""></div><div class=""> - fileprivate should really become much more rare, which makes it more meaningful and significant where it occurs. This was the original idea and intent behind SE-0025.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I would like to understand the reasoning here. I just looked back at SE-0025 and I see this same assertion, but I cannot find the reasoning. Could you explain it to me please?</div></div></div></div></div></blockquote></div></div></div></div></blockquote><br class=""></div><div>The idea of a private member is that it’s only visible within the class that declares it. In languages where the class is traditionally declared all at once, that’s straightforward enough; however, the tradition of implementing swift classes as a series of extensions (currently) forces opening much more than should be to any other classes within the file. If class B needs access to one private within class A, it also gets access to every single variable used by an extension to A, and every single function used by an extension outside the one it’s declared in. That’s way more visibility into the class than it should have.</div><div><br class=""></div><div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Certainly I would love to make the *spelling* of “fileprivate” be entirely nonexistent. But all the lines of logic I have come up with lead inexorably to the conclusion that the *semantics* of “fileprivate” should be the common, <i class="">de facto</i>, access level that people reach for when they need encapsulation.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">1. Someone makes a file with a single type in it, and marks the implementation details “private”. At this point, it does not matter matter which meaning “private” has, they all work the same so far.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">2. The developer adds a free function to the file. Or an extension of another type. Or another type entirely. And they put it in the same file because it needs to work with the implementation details of the existing type.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div><div>IMO having a free function access the internals of an object is a huge code smell. It should almost always be a function on the object or the class. And I’d be highly skeptical of any architecture that requires one class to access another class’s privates directly. In general, I’m fairly strongly opposed to having multiple externally accessible classes in the same file (probably influenced by having used Java through most of my education).</div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Now the difference between possible meanings of “private” matters. And if it is anything short of “fileprivate”, then the developer has to go back and change access levels. Things no longer “just work”.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div><div>Well, yes, that’s what I’d expect and want, and that’s the whole point of access levels. If I have a private member and want to use it in another class, I should have to make a conscious decision about whether to open up that member, add an externally visible one, or just do it a different way entirely. (One might argue based on that point that the fix-it to widen the access level is actually harmful.) I’m not sure what your point is here, but I think forcing the dev to stop and think about whether the access needs to be loosened is a *good* thing.</div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">The alternative scenario is that one adds something to the file which doesn’t need privileged access to what’s already there. In which case the questions are, “Why put it in the same file at all?” and “If there is a good reason to put it in the same file, is there any *harm* in it being able to see private members?”</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div><div>Again I’m not seeing your point. Yes, you should think twice about why it’s in the same file. Yes, there is harm because it can now see fileprivate members that it shouldn’t.</div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Most developers most of the time should not have to think about sub-file-level granularity. If things are in the same file it is because they need to work together closely. We should be able to mark members “private” and work with them across the file. This dramatically reduces the cognitive burden, and the amount of time spent fiddling with access levels.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div>Are you arguing for reverting to the Swift 2 definition of private = modern fileprivate? </div><div><br class=""></div><div>I’d argue exposing privates to everything in a file actually *increases* cognitive load because now I have to keep track of which classes are declared in the same file. If private has a sane meaning (initial declaration + “primary” extensions, the level under consideration here) only the class I know I’m working in has access. Much simpler and context-free.</div><div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">With any meaning of “private” less than “fileprivate”, developers end up marking things “private”, then letting the IDE change it to “fileprivate” when the compiler complains. This tells me that people actually want the semantics of “fileprivate”, and they want it to be spelled “private”.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div><div>No, I’d say 99+% of the time that I have to make something fileprivate, it’s only for the benefit of same-file extensions, and the proposal we’re considering here would negate most of the need for that. Exposing those members to anything else that happens to be in the same file is an unfortunate failing of Swift’s access control. Given Swift’s emphasis on extension-based implementations, I expect many others are in the same boat.</div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">The main exception, where people truly desire and intend for tighter-than-file encapsulation, is when certain invariants must be preserved, and should not be touched except by dedicated methods. And *that* is the important case worth making unambiguously explicit.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div><div>Unfortunately, for the most part you can’t really do that properly without allowing stored properties in extensions anyway, because either the variable(s) involved have to be fileprivate or the methods have to go in the primary definition. Either way, more things can access the state than should.</div><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">All the talk about calling out cross-type sharing within a file seems superfluous. That is one of the principle reasons for putting multiple types in one file to begin with. But preserving invariants, now *that* deserves a meaningful and significant syntax, ideally something loud that warns developers not to mess with it.</div></div></div></div></div></blockquote></div></div></div></div></blockquote><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">So, why exactly is there a desire to make the semantics of “fileprivate” rare?</div></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br class=""></div><div>Because it’s more broad than needed. Everything that should be restricted to the type but is declared in or used by an extension has to be fileprivate, exposing its private parts to every other class in the file. Extending `private` to cover same-file extensions lets classes at least put on some underwear.</div><br class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"></div></div></div></div></blockquote></div></div></div></blockquote><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=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Nevin</div></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=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div></div></div></div></blockquote></div><br class=""></div></body></html>