<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 Feb 26, 2017, at 10:58 AM, Charles Srstka &lt;<a href="mailto:cocoadev@charlessoft.com">cocoadev@charlessoft.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><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></blockquote><div><br></div><div>That's interesting. &nbsp;I hadn't thought about this. &nbsp;It would complicate the model a little bit - I have been thinking in terms of capabilities as additive to the basic capability (i.e. when a setter is available so is the getter, when you can override you can also call, etc). &nbsp;</div><div><br></div><div>That said, there have been requests for override-but-not-call and you're right that this can be an important guarantee for a library. &nbsp;Would you expect override to imply the ability to call super? &nbsp;Or would you expect this contract to be used in cases where the subclass is not allowed to call super at all? &nbsp;That latter obviously fits the semantics of this access control model better and I imagine it is often what you would want (for example if the override points are part of a template method pattern).</div><div><br></div><div>There have also been requests for set-only properties although I'm not as familiar with the use cases for that.</div><div><br></div><br><blockquote type="cite"><div><div class=""><br class=""></div><div class="">Charles</div><div class=""><br class=""></div></div></blockquote></body></html>