SE-0386: `package` access modifier

The proposal is not arguing that SPI is an unnecessary concept that shouldn't be added to the language; it's just arguing that SPI is not the right tool in every situation. The SPI feature is designed around promoting a tight coupling between a particular interface and its exact expected clients. Sometimes you want that, and in those cases, you should use SPI. However, sometimes you don't want that, and all you want to say is "this interface is just for us, at least for now". Swift's core access control design is based around recognizing existing boundaries that often correspond to a useful sense of "us": the people implementing this specific declaration, or working in this file, or working on this module. In that light, allowing users to recognize a boundary that's broader than a single module but not as broad as the entire program makes sense, because small teams often work on several closely-related modules and should be able to share code without having to make it part of the public API. Different organizations can draw that boundary where they want, but it makes sense for SwiftPM to default to drawing it at the package boundary, and package seems like a good general name for the feature.

It would certainly be more flexible to allow these boundaries to be explicitly named and separately controlled. If you want that, you can use the SPI feature for it. But personally, I think that would not be a good idea. It really needs to be notable for a file to contain an SPI import: seeing one should make programmers and code reviewers immediately question whether it's really needed. That idea is badly undermined if SPI imports are common; if every file contains two or three boilerplate SPI imports just to get access to run-of-the-mill cross-module interfaces, it becomes really easy to miss that one of them is a "true" cross-package SPI usage that should get special attention. In my mind, the only way to avoid that and preserve the value of programmer discipline and code review is to design access control the way Swift does, around ever-larger natural boundaries that programmers intuitively understand. And ultimately, access control within an organization only works because of programmer discipline and code review, because otherwise programmers will just make things public to shut the compiler up.

9 Likes