[swift-evolution] Simplifying Access Using 'Hidden'

Vladimir.S svabox at gmail.com
Wed Feb 15 08:28:02 CST 2017


On 15.02.2017 14:29, Joanna Carter via swift-evolution wrote:
>> 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.
>

Was surprised that you expressed exactly what I'm thinking about this subject.

I do believe even in Swift we need a way to say "only code that *knows* 
what it does should see this" and to not force us to write(and manage) the 
the code in same file.
Yes, some implementation details that shouldn't be used by "users" of the 
type, but can be used by "extenders" of our type. At least in the same module.

While reading, the question was raised(if was discussed, let me know pls): 
what if we extend the meaning of 'private' to 'visible to current 
type/scope and subtypes and extensions in the *same module*' ?
This will help us to split types by files, help to better model access 
policy for fields/methods(i.e. only scope that can know about details can 
see them) while 'private' still will be hidden outside of the module even 
for subclasses/extensions.

So, we'll have such situation:

"modifier" -> "can be accessed from"
-------------------------------
public -> outside of the mondule
internal -> inside the module only
fileprivate -> the same file only
private -> the same type/scope, or subtype, or extension in the same 
module. I.e. some kind of 'internal' but scope-oriented.

Actually I still believe we need current 'private' and additionally some 
'protected' with meaning "access from subtype, or extension" probably with 
this limitation: "only in the same module". But suggested extended 
'private' will be also OK for me.

Thoughts?

Vladimir.

> 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


More information about the swift-evolution mailing list