[swift-evolution] [Review] SE-0159: Fix Private Access Levels

Jonathan Hull jhull at gbis.com
Fri Mar 24 19:53:02 CDT 2017


> On Mar 24, 2017, at 9:41 AM, Drew Crawford <drew at sealedabstract.com> wrote:
> 
>> There are a couple of problems with the design which are causing Cognitive Dissonance:
>> 
>> 1) Private & fileprivate require very different mental models to operate them
>> 2) They are named very similarly to each other
>> 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 
> 
> 
> How would you respond to the allegation that supporting different "redundant" semantic models is actually a *design goal* of Swift?  For example:
> Value semantics vs reference semantics
> Pass-by-owned vs pass-by-shared vs pass-by-reference parameters
> dynamic dispatch vs static dispatch
> associatedtype vs generics
> "complete" types (e.g. Array<Int>) vs  "incomplete" types (Sequence) and which one is permitted after a colon
> strong vs weak vs unowned

It isn’t the fact that there are multiple models, but they way those models interact with each other in the brain.  You can actually have lots of different models without causing confusion, as long as the models fit well together.  It also isn’t the number of access levels that is a problem.  For example, you can have a ton of shirt sizes (XS, S, M, L, XL, XXL, 3XL) and it doesn’t cause more confusion as you add more sizes because they don’t conflict with one another.

A big part of the issue with our current access scheme is how similar the concepts are without being the same.  That is then made worse by the fact that they have been given similar names.

Note also that your list above is a list of typical stumbling blocks for new programmers in most languages. Swift has actually done a remarkable job with most of these through careful design of the way that they are framed / exposed to the programmer.  In general, these things are well separated from each other.  For example, associatedtype and generics have completely different syntax.  Still, each of the above features comes with a significant mental cost.  We are willing to pay that cost because of how useful the distinction is.

Do you feel that allowing both scoped private & file-based private is actually important enough to warrant the significant design work it would take to bring it up to par with these other features?  It is not impossible, but it really doesn’t feel worth the effort to me (say compared to using that time/energy/thought to check off features from the generics manifesto).

> I would argue that supporting whatever the programmer's chosen mental model is actually Swift's greatest strength.  We could have a language with only reference types for example, it would be far, far simpler and easier to teach.  I am glad that we don't have that language.  I don't use all of these in every program, but I use all of them eventually, and each one is right for some situation.
> 
> Many of us don't know half these models half as as well as we'd like.  But we also like less than half of them half as well as they deserve.  Visibility is in line with the trend here.

I disagree that supporting any mental model is a goal of Swift (or even something that it does).  In general, Swift is an opinionated language, which means just the opposite.

>>> Of the three, I am personally most supportive of file-based
> 
> My concern about dropping down to file-based is it doesn't allow any nesting, which isn't powerful enough for several examples posted in this discussion.  Unless by "file-based" we mean "directory-based" which is another proposal that has seen strong opposition from the "it's too complicated" wing.

By file-based, I mean that visibility is thought of in units of file.  That might be a single file or a collection of files, but it would never be part of a file.

You could potentially still have nesting with file-based access, if we feel that is a desirable trait when we design submodules.  The boundaries would just still be in units of file.  The main question there is whether the power is worth the added complexity.

…or we could unify under a scope or type based access system, which would have different strengths and weaknesses.  But by trying to be all things to all people we are just ending up with a muddled mess.

Thanks,
Jon

> On March 24, 2017 at 5:00:33 AM, Jonathan Hull via swift-evolution (swift-evolution at swift.org <mailto:swift-evolution at swift.org>) wrote:
> 
>> 
>> Several people have asked:  What is the harm it causes?
>> 
>> I would like to provide a (hopefully) clear answer to that.
>> 
>> There are a couple of problems with the design which are causing Cognitive Dissonance:
>> 
>> 1) Private & fileprivate require very different mental models to operate them
>> 2) They are named very similarly to each other
>> 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 
>> 
>> 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.
>> 
>> 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).
>> 
>> **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.**
>> 
>> 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.
>> 
>> For file-based, that means that our sub-modules, when we add them, would need to be file-based as well.
>> 
>> 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.
>> 
>> 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...
>> 
>> 
>> We really need to choose a single direction and not mix and match.
>> 
>> 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.
>> 
>> 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.
>> 
>> I hope that explanation was at least a bit helpful…
>> 
>> Thanks,
>> Jon
>> 
>> 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:
>> <F0F862F8-0489-49F0-A06A-BEB6B7AE5C92 at hsd1.ca.comcast.net.>
>> https://upload.wikimedia.org/wikipedia/commons/7/7f/Impossible.png <https://upload.wikimedia.org/wikipedia/commons/7/7f/Impossible.png>
>>  
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170324/a461ed2e/attachment.html>


More information about the swift-evolution mailing list