Deprecate the file scope

I want to challenge and discuss the usefulness of forming an access control system around the notion of files on a disk.

The access control system in Swift 4 favors big code files. Files with a large amount of code are harder to get an overview of, scroll though, and are more susceptible to source control conflicts.

Proposal:

  • Make one big breaking group of changes to finally fix the access control system of Swift.
  • Remove the the notion of files as an enclosing scope for declarations in Swift.
  • Use three accessibility levels: private/protected/public.
  • Overridability and subclassibility is defined by a modifier open/final.

Examples:

  • final on a method means it's not overridable
  • final on a class means it's not subclassable
  • private on a top-level declaration means it's accessible in the module it's declared in. It does not mean it's accessible only in the file it's declared in.
  • private on a member means it's accessible from inside the type.
  • protected on a class member means it's accessible to subclasses and extensions.
  • protected open on a member means it's accessible to subclasses and extensions, and that it's overridable.
  • public open on a top-level class means it's accessible outside the module, and that it can be subclassed.
  • public on a nested class means it's accessible both outside it's enclosing type, and also outside the module if the enclosing type is visible outside the module.
  • protected on a nested class means it's accessible outside it's enclosing type, but not outside it's module.

We just had a major debate and decision about access control in Swift 4, and after herculean travails we landed on the current design. Let’s not resurrect that debate, it is not going to change.

In particular, “protected” was extensively discussed, with strong arguments on both sides. If it is not already in the commonly proposed and rejected list, it probably should be.

The only part of access control we might plausibly look at would be if we introduce a concept of sub-modules, at which point it would be worth considering an access level for them. But even that is outside the scope of Swift 5.

I am quite certain the core team has neither the time nor inclination to return to this topic.

7 Likes

Please no. The first version of scope in Swift was perfect. Each time someone tries to make it more like Java breaks it more. The last time we got that sick private and fileprivate instead of the nice clean private before.

And big code files are a good thing. It's annoying combing though dozens of files that are all interlinked to find the part you need.

8 Likes

Yes, Swift's access control is deliberately lexical. private has poked holes in the overall design, but it's here to stay. It has been said by others that one very good choice if we were to do it again would be to eliminate everything except public and internal. I'd very much like that. But what we have is here to stay.

If someone comes up with a significantly nicer name than fileprivate, however, I do believe that the offer is formally still open to reconsider that name. But that's about all that can change at this point.

Occasionally, local has come to mind as an alternate fileprivate, but I've always either forgotten it or thought it would run afoul of the fact that some languages use it for their scoped private access level.

I clearly do not want to rehash that topic. But does someone recall if simply file was considered?

private - file - internal - public - open

Yes; I suggested it. If this topic is to be reopened, it needs to be something that hasn’t been thought of before, and it needs to be clearly, vastly better.

2 Likes

What was the problem with file or local?

I invite you to peruse the archives of the discussion at your leisure. Now that we have a forum it is quite easy to search and browse old threads.

Please let’s not rehash it here.

3 Likes