[swift-evolution] SE-0025: Scoped Access Level, next steps

Andrey Tarantsov andrey at tarantsov.com
Tue Mar 29 02:32:46 CDT 2016

Some responses rolled into a single email:

> I'm going to say that I remain unhappy with these new names. I don't believe that these won't get used, and I don't want them to feel awkward, discouraged, or penalized when they do. The standard library, for example, has in its style guide that all access control should be explicit, which is a reasonable style to enforce.

I enforce that style in my own code, so I'll definitely be using moduleprivate. The point was that, if you don't like moduleprivate, you can establish a code style that omits it. But I personally like it very much, it's an ideal mix of standing out (by virtue of being long), but not standing out too much.

> I also have a small concern that they won't be easy to talk about: "this method is private" "wait, file-private or module-private?" "neither, just private-private".

Nope, you'll just always say file-private and module-private when you mean that. Private continues to mean private. No need to clarify when speaking.

> I've never come across a use of private other than for the scope of the immediate class only.

Yes. Private should be the scoped access level, that's the least surprising definition.

> Delphi does a similar thing to Swift, in that it defines "private" as meaning the scope of the declaring code file

FWIW, Delphi and Ada had a strong tradition of module/unit-based encapsulation (where the module/unit refers to a single file or a header/body pair of files), with each module having public and private parts.

Swift doesn't go all the way here, but it does recognize that it's a useful pattern. I personally like it, and use file-private access regularly to group related entities into a single submodule. (There sure are other ways to define submodules, but this is the most lightweight one, and also the one we already have.)

So “fileprivate” should definitely stay, but yes, it's not nearly as common as “private”.

> I would, respectfully, suggest that "protected" should be allowed for exclusive use in the case of classes that really have to derive from each other

I would personally love this, but it's outside the scope of the current proposal.

> What Swift presently calls "internal" seems to equate more to the C# concept of "internal" and, in my mind, needs no further discussion or change.

I believe “moduleprivate” is a lot more clear than “internal”. “internal” have always bugged me as a seemingly random word.

> Let's say that we go with public, moduleprivate, fileprivate, scopeprivate

God no. “Private” is the most common case, and shouldn't stand out that much. Scoped private will be consistent with every other language out there, so doesn't need clarification.

> I have seen some horrendous abuses of that privileged access, with the gradual growth of single code units to truly gargantuan proportions, just because someone felt that certain classes needed to violate all the rules of common sense and be able to access each others' private parts (if you'll pardon the vernacular).

Respectfully, this is not a valid argument. I've seen horrific abuses in lots of different languages out there. Bad developers will always write bad code, and the intricacies of access level definitions won't help.

> If several types really have to be defined in the same unit, then their relationship to each other needs defining far more strictly than just to say that they have total free reign to interfere where they want.

Yes, this is why certain members should be marked file-private. We don't need explicit friends. If a file grows beyond the size where the purpose is clear, the code needs to be refactored into multiple files.

> public, internal, private, secret.

No. Private needs to mean what everyone expects it to mean, and it should also be the default reasonable (i.e. most restricting) choice.

> +1 to paren syntax for readability, private(module) being the default if nothing declared, private with no parenthesized access keyword can default to either file or scope.

There's nothing readable about private(module). You don't want those parens to grab attention from the code. A longish word is quite enough.

> I still think that "local" expresses the concept exactly, as it restricts visibility to the local scope, doesn't it?

No, to me it's only clear if you stop and think about it. But when coding, it invokes all the wrong associations.

>>> afaics this is the third time someone mentions that "file-private" is uncommon — so I think it's time someone dissents:
>> I'll do the same. There's many instances in my code where I rely on the file-private behavior of Swift 2's private. Mostly this happens when I have a pair of coupled classes that are meant to be used together and that need to access internal details of each other. Most declarations can be scope-private without problem, but it's not that uncommon for me to take advantage of file-private. 
> +1

It *is* fairly common, but:

1) it is *way less* common than just plain private

2) in those cases where I need file-private, I really want to document *which* members are accessed from outside, so the distinction between private and file-private is very useful there

>> I cannot come up with a single use-case in my code for fileprivate and would love
>> some real world examples where you'd want visibility in a single file but not across
>> an entire module.

Here's a quick use case: a private helper class that you don't want to expose to the outside. Maybe it's only used to implement a verbose protocol. It's really a part of the bigger public class, so wants to access some of its members without much ado.

Another use case: a bunch of public structs/classes that can be initialized from JSON, but there's only a single publicly-visible ‘parse’ method that invokes a bunch of private initializers (and maybe mutation methods) on those structs. 

There are tons of cases where you have a compact bunch of classes and you want them to hide the implementation details of one specific feature that involves interaction between them.

Haven't you even declared a bunch of Objective-C classes in a single file so that they all have access to the the private extensions of one another? I did it fairly often, and Swift's file-private is a natural extension of that.

> Abandon the words 'public' and 'private'. [...] I really want Swift to use terms with clear meaning

“Private” has a very clear meaning (not accessible from outside); its current meaning was simply a wrong choice, based on a different look at what “outside” means.

Similarly, “public” is 100% clear; we talk about “public API” all the time.

We also talk about module-private, subsystem-private, framework-private and file-private stuff, so calling them such seems a no-brainer choice. Do you ever say “file-internal” yourself?

> public (unchanged)
> external (module access)
> internal (file access)
> private (scoped access)

This seems logical and something I could live with, but how is it better than moduleprivate and fileprivate? Also, internal has contradictory prior art in C# and Swift 2 (not that it stops us).

And I see the length of moduleprivate and fileprivate as a feature, and external/internal lacks it.

> protected // Java got it wrong. :) This is "protected" against extensions. '

Please leave protected alone, I still hope we can get it into the language in some shape or form, not necessarily bound to subclasses.

> If I may be so bold, as a programmer with over 25 years of experience, in multiple languages…

15 years here, just so that you don't disregard this as a newbie's talk. (I fully expect to be wrong on occasion, though, so I don't consider this to be a part of the argument.)


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

More information about the swift-evolution mailing list