<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=""><blockquote type="cite" class="">On Feb 25, 2017, at 5:27 PM, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></blockquote><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">The name that has usually been used for this is `closed`. &nbsp;But no word that expresses a *restriction* is going to fit well into Swift’s access control system. &nbsp;The approach of Swift’s access control system (which I believe to be the best approach) is to express an upper bound on a *capability*. &nbsp;The basic capability is visibility of the symbol. &nbsp;That model is extended by talking about specific things a user might *do* with that symbol and setting an upper bound on that specific use: `internal private(<b class="">set</b>)`. &nbsp;`internal` is the bound on visibility and `private` is the bound on the ability to `set` the property. &nbsp;</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">`closed` is most naturally expressed in this system as `public internal(<b class="">inherit</b>)`. &nbsp;One interesting thing to observe is that `internal` is the default level of visibility. If we extend that default to capabilities as well as visibility the result is to give us exactly the behavior we want from a naked `public` annotation. &nbsp;We want to require an annotation for exposing anything (a symbol *or* a capability) outside the module. &nbsp;This means that `open` is really an alias for `public(inherit)` if we follow the principles underlying the model we have for access control.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Following this line of reasoning to its natural conclusion we can observe that the current interaction of `var` properties with access control *do not* follow the principles we have set forth for Swift. &nbsp;`public` variables *automatically* have `public` getters violating the principle that `internal` is the default. &nbsp;We could fix this by requiring users to say `public(set)`. &nbsp;I imagine there would be a lot of screaming in the short term if we proposed this. &nbsp;But it would put Swift’s access control system on a more consistent and principled footing. &nbsp;</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">I think there are three major reasons people have trouble with the current access control system. &nbsp;The `private` / `fileprivate` name situation is an obvious one. &nbsp;But I think perhaps more important is the fact that the system has idiosyncrasies such as introducing `open` rather than following the capability model of `set` (which would have resulted in `public(inherit)`). &nbsp;Another idiosyncrasy noted above is that `set` defaults to the level of the getter rather than `internal` (but bounded by visibility). &nbsp;Finally, the principle that underlies the access modifiers (modulo the idiosyncrasy of `open`) is that of a bounded scope. &nbsp;But this principle is implicit - each keyword is defined on an ad-hoc basis rather than making the underlying principle explicit and defining any shorthand we want in terms of that (as syntactic sugar for common cases and recommended defaults).</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">This is why I strongly believe the best approach is to make the underlying principle of scopes and capabilities with an `internal` default explicit. &nbsp;I think this principle is easy to teach and easy to understand once it is made explicit. &nbsp;It is a wonderful (but currently rather hidden) aspect of Swift. &nbsp;If we can teach users to understand this principle and to learn the names of scopes and capabilities they will not find it difficult and complex. &nbsp;They will find it as easy to learn as a library function: we would have `scope(&lt;capbability name&gt;, &lt;scope name&gt;)`**. &nbsp;The capability would be defaulted to basic visibility. &nbsp;The scope would be defaulted to the current scope. &nbsp;</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Consider&nbsp;scope(inherit, public)`. &nbsp;It would read like “the scope of inheritance is public”. &nbsp;It tells the reader *exactly* what is happening. &nbsp;We could conceptualize shortened like `open` as something like `accessalias open = scope(inherit, public)`. &nbsp;Tools could even allow you to cmd-Click to the definition to see a definition like this. &nbsp;Users would learn something that is no more complicated than a single function call and any time they are confused by shorthand they could cmd-Click or look up documentation that explains it clearly in terms of this "function call”. &nbsp;Note: `accessalias` wouldn’t be a real thing, just a way to document and explain the shorthand keywords we have for “soft defaults” and common conveniences.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">This seems to me like a very simple and elegant yet extraordinarily powerful system. &nbsp;I think it’s much better than a small collection of ad-hoc definitions of very specific behaviors.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">**Anyone who has been reading my thoughts on this might notice that I am using `scope` rather than `scoped` in this post. &nbsp;As I was writing this I realized that when we think of access in terms of capability it reads better with `scope` than it does with `scoped` (i.e. “inheritance is scoped public” does not read as well as “the scope of inheritance is public".</div></div></blockquote></div><br class=""><div class="">The nice thing about that is that we could declare something as private public(inherit), making it not callable but possible to override, which would be a great fit for methods that are only intended as override points and are not meant to be called directly, like the many such methods on NSView.</div><div class=""><br class=""></div><div class="">Charles</div><div class=""><br class=""></div></body></html>