<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On Mar 24, 2017, at 4:59 AM, Jonathan Hull <<a href="mailto:jhull@gbis.com">jhull@gbis.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><div class=""><br class=""></div>Several people have asked: What is the harm it causes?<div class=""><br class=""></div><div class="">I would like to provide a (hopefully) clear answer to that.</div><div class=""><br class=""></div><div class="">There are a couple of problems with the design which are causing Cognitive Dissonance:</div><div class=""><br class=""></div><div class="">1) Private & fileprivate require very different mental models to operate them</div><div class="">2) They are named very similarly to each other</div><div class="">3) There is a third concept of “private to the type” which requires a third mental model, but is spelled the same way in other languages </div><div class=""><br class=""></div><div class="">Any one of these would cause confusion. All of them together mean that even those of us who understand how they work are bothered by them on a subconscious level (similar to how misaligned graphics will give everyone a subconscious feeling that a graphic design is “off” even if they can’t discern why consciously). Even many of those who are arguing to keep private have argued to rename things or to make it work in a more type-based way by extending visibility to extensions. I don’t think anyone is denying there is a problem here with the status quo.</div><div class=""><br class=""></div><div class="">There is a general rule in design that things that look similar (or in this case are named similarly) need to behave similarly to avoid causing confusion (and conversely things that behave differently *need* to look different).</div><div class=""><br class=""></div><div class="">**This is not something that will go away simply by learning the behavior. It will continue to be a rough spot in the language that causes discomfort until the underlying design issue is fixed.**</div><div class=""><br class=""></div><div class="">The ideal solution here would be to choose a single model and make everything coherent under that. We choose either file-based, scope-based, or type-based access control and unify under that.</div></div></blockquote><div><br></div><div>All of Swift's access modifiers are already scope-based. Files and modules form scopes. Maybe this concept is new to a lot of people, but it is not internally inconsistent and does not make it a bad design. I do agree that the current names are not great.</div><br><blockquote type="cite"><div><div class=""><br class=""></div><div class="">For file-based, that means that our sub-modules, when we add them, would need to be file-based as well.</div><div class=""><br class=""></div><div class="">If we choose Scope-based, then it really cries out for some sort of parameterized private. That is you only have private and public, but for private you would be able to name a scope to widen the visibility to the named scope. Submodules would then need to be scope based, and you would probably use the parameterized private with the submodule name to share data within it.</div><div class=""><br class=""></div><div class="">Type-based is very common in other languages, but I fear it would not play nicely with the way Swift has grown to work. The pros are that you could access private variables from extensions, but getting types to work together with the ease they do now would require a lot of design work (and may not even be quite possible). You also have additional complexities around subtypes, etc...</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">We really need to choose a single direction and not mix and match.</div><div class=""><br class=""></div><div class="">Of the three, I am personally most supportive of file-based because it is the closest to where we are now, and it seems to simplify many of the concerns about “friend” types by having visibility be dependent on proximity… which seems very intuitive to me.</div><div class=""><br class=""></div><div class="">As I said before, my preference would be to tentatively accept the change, but delay implementation until we design submodules for Swift 5. That way the design can be more cohesive as we can tackle it all at once. If submodules won’t be in scope until after Swift 5, then we should implement the change now.</div><div class=""><br class=""></div><div class="">I hope that explanation was at least a bit helpful…</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""></div><div class="">Technical note: For the curious, basically we have made a design which is "locally consistent, but globally inconsistent". That is why the effect doesn’t go away after learning the concepts involved. Basically we have made the programming equivalent of the following image:</div><div class=""><Impossible.png></div><div class=""><a href="https://upload.wikimedia.org/wikipedia/commons/7/7f/Impossible.png" class="">https://upload.wikimedia.org/wikipedia/commons/7/7f/Impossible.png</a></div><div class=""> </div><div class=""><br class=""></div></div></blockquote></body></html>