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
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.

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.


On March 24, 2017 at 5:00:33 AM, Jonathan Hull via swift-evolution 
(swift-evolution@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:

https://upload.wikimedia.org/wikipedia/commons/7/7f/Impossible.png
 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to