[swift-evolution] [Proposal] Qualified Imports and Modules

Robert Widmann rwidmann at apple.com
Mon Jul 18 19:33:49 CDT 2016


> On Jul 18, 2016, at 5:26 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
> 
>> On Jul 18, 2016, at 4:50 PM, T.J. Usiyan <griotspeak at gmail.com> wrote:
>> 
>> * You may need to split a single submodule across multiple files, but this rule doesn't allow that.
>> 
>> You can, internally, have several modules and then create one that imports those smaller ones publicly with the name that you desire. 
> 
> They wouldn't have access to each others' internal scopes by default, would they?
> 
> In general, I get the sense that this proposal is hostile to the current idea that a module (or submodule) consists of multiple files, each of which has both intra-file privacy and inter-file sharing with other parts of the module. I think this is a natural and extremely useful way to design software. Moreover, I think throwing this concept out goes explicitly against the grain of current Swift access control mechanisms. In a world where every file is its own module, what's the difference between `internal` and `fileprivate`? Are we going to end up in an Objective-C-style situation of giant import lists at the top of every file, listing stuff that's in the same module? Doesn't that go against the goal of reducing boilerplate?
> 
> I would prefer to see:
> 
> 1. Each file is allowed one `submodule` declaration as the first non-comment line of code in the file. It does not include the main module name, only the submodule name (so `UIKit.UIGestureRecognizerSubclass` would simply have `submodule UIGestureRecognizerSubclass` at the top). If there is none, the file is part of the main module. (It *might* make sense to have both public submodules, which anyone can import, and internal submodules, which can only be imported within the top-level module, but I'll need to think about that.)

That is one of the alternatives considered.  It may be possible through annotation of the module itself to express this kind of thing.

> 2. Filenames are freeform; any file can declare itself to belong to any submodule. Obviously, best practice would be to give your files sensible names that have some kind of link to the submodule name, but this would be a linter concern.

How does this interact with duplicate declarations?

> 
> 3. Each submodule has its own `internal` scope. Submodules can import the `internal` scopes of specific peer modules with an annotation like `@testable` (but probably renamed). 

"Peer modules” is something we can lock down without having to introduce even more scopes and fits well within this proposal.  A restriction like “a module may only import private members from submodules 1-level deeper than themselves” for example.

> Tests are treated as a submodule of the main module, so they can participate in this mechanism just like everyone else.

Or we could keep the existing @testable import syntax.  It will still work exactly the way it always has under this proposal.

> 4. `import` only ever imports the `public` (or `internal`, with the `@testable` equivalent) symbols in the specified submodule. It re-exposes them with the access modifier on the `import` statement, or `private` by default. It does not re-expose `internal` symbols as `public`. `using`, `hiding`, and `renaming` apply to all comers, not just the current file.

We do not allow you to re-export any API that is not public.  The wording around the section you keep bringing up is vague and needs to be fixed.

> 
> I think this approach would harmonize much better with current Swift features and code organization practices, while offering several new features (umbrella modules, exposing certain symbols only when a submodule is explicitly imported, multiple `internal` scopes within a top-level module) which would be very useful.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 



More information about the swift-evolution mailing list