> The beauty of Swift 2's access modifiers was that they were based around 
> files and modules, explicitly rejecting types and scopes as units for 
> determining visibility. It seems at base there's a group of people who reject 
> that decision altogether. Hence, new `private`, proposals around `protected`, 
> `friend`, `hidden`, `extensible`, etc.

I suppose, for those coming from an Objective-C only background, any extra 
visibilities are seen as a bonus.

For those coming from a Pascal background, file-based visibility seems more 
natural.

But for those of us who have used languages like C++ and C#, losing the 
visibilities that we have been used to can seriously affect how we think and 
design stuff.

FMPOV, it would seem that one of the "features" of Swift is a much more 
protocol and struct approach to design. Instead of using class inheritance to 
add functionality to an entity, we are encouraged to use extensions.

But, in so doing, those of us who are used to inheritance find that we can no 
longer limit visibility to a "hierarchy" but, instead, when we want to extend a 
type whilst accessing "privileged" members, we either have to put all our 
extensions in the same file as the base type, or raise the visibility of those 
privileged members to internal scope, thus allowing code anywhere in the same 
module to access and/or mutate it.

I have read https://developer.apple.com/swift/blog/?id=11 and I can see the 
reasoning against protected explained there but…

Once again, I see the "it was good enough for Objective-C" reasoning being a 
strong driver here but, this is Swift, where things can be done 
differently/better.

Allowing internal scope visibility is less of a problem when you are the only 
one writing the module and know intimately the intent and purpose of everything 
but when working in a team environment, it is all too easy for another 
developer to start "interfering" with your carefully designed logic by using it 
in ways that you had not anticipated.

I can understand the reasoning behind not using the concept of protected 
visibility but still feel that there are times when restricting visibility only 
to extending entities, whether that be subclasses of a class or extensions of 
any type, including structs and enums.


I would also like to argue that the use of open vs public for classes is quite 
confusing when we already have the option of marking a class or its members as 
final ; which seems to do much the same as leaving a class as public.

Except open is not truly a restriction of visibility, it is more a restriction 
on inheritance.

To quote the above blog, "In contrast, protected conflates access with 
inheritance". Surely "open" also conflates access with inheritance? It affects, 
not what external code can see but how the inheritance chain is controlled, as 
does final. In fact, I would dare to say that the difference between 
open/public and final is possibly too fine to be of sufficient importance to 
justify the existence of both ; or, at least, it is sufficiently confusing to 
encourage newer developers to throw their hands up in despair and simply leave 
everything as internal or public until they stumble across a compilation error.

The only real difference I can make out between open/public and final is that, 
once again, open/public is more module-based, whereas final is class based.

Why, when we are allowed final as a class only modifier, can't we have 
protected as a class only visibility?

Or, as I have mentioned previously, should we have a much more "Swifty" version 
of protected that allows more concisely defined visibility, not only within 
class hierarchies, but also within the full range of Swift "hierarchies", 
otherwise known as extensions?

My suggestion of "extensible" is intended to replace the perceived need for 
"protected" for classes, whilst unifying that concept of privileged access 
within a class hierarchy, with a similar, and increasingly demanded, privileged 
access for extensions of all types.

To elucidate further :

Before Swift, if we wanted a hierarchy of types, all with common base 
behaviour, without having to write the same code in every type, we were limited 
to using classes with their visibilities of private, protected and public.

Now Swift encourages us to declare protocols, which can have extensions that 
can define base behaviour, as long as that behaviour doesn't include stored 
data. We can then "inherit" that behaviour either in classes, structs or enums 
that implement the "base" protocol.

So, an interesting question is : should we look at getting rid of class 
inheritance altogether in favour of "protocol-based inheritance"?


Oh, and finally for this post, can anyone please tell me exactly what 
fileprivate brings to the table?

To my mind, although it allows access to private members of another type, it 
also requires that any type, wishing to take advantage of that privilege, has 
to be declared in the same file ; so, sort of like protected visibility but on 
a file basis.

But what if I have a relatively small abstract type (protocol or class) that is 
the basis of a larger "hierarchy"? Using fileprivate in the base type would 
mean that I would have to declare my whole hierarchy within that one file 
instead of placing each "subtype" or "implementing type" in their own files.

What happened to the "types should only be one screenful" school of thinking? 
:-)

--
Joanna Carter
Carter Consulting

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

Reply via email to