Thanks for bringing up submodules Robert. I agree it's a good time to discuss them.
There seem to be two broad approaches to submodules. One is more of a physical / encapsulation based view and the other is more of a logical / namespace based view. This proposal falls into the latter group (Brent's pitch falls into the former). Before I offer feedback on this proposal I'm wondering if you can provide some solid examples of what benefits you see in the ability of a single file to participate in more than one submodule. And also, what problems do you foresee if a file were restricted to being in a single submodule (or at the top level of the module)? Sent from my iPad > On Feb 20, 2017, at 7:56 PM, Robert Widmann via swift-evolution > <swift-evolution@swift.org> wrote: > > Good Evening All, > > Jaden Geller and I have been considering a (sub)module system for Swift that > would complement the existing language but also provide sorely needed > modularity. A draft of the proposal is attached to this email, but it can > also be read as a gist if you desire. > > Cheers, > > ~Robert Widmann > > Modular Swift > Proposal: SE-NNNN > Authors: Robert Widmann, Jaden Geller > Review Manager: TBD > Status: Awaiting review > Introduction > > Almost every major programming language supports some form of modular > programming through constructs like (sub)modules, packages, or interfaces. > Swift, though it provides top-level modules to organize code under, does not > provide a complete implementation of any of these concepts, which has led > instead to the proliferation of access control levels. This has not proven an > effective way to decompose programs into manageable parts, and exposes the > need for a real system of modules to solve this modularity problem once and > for all. > > Separation of code into distinct islands of functionality should be a > first-class construct in the language, not dependent on external files and > tools or filesystems. To that end, we propose the introduction of a > lightweight module system for Swift. > > Swift-evolution thread > > Motivation > > Swift has reached a point in its evolution where rich libraries and large > projects that take on many dependencies have matured significantly. To > accomodate the information-hiding and semantics-signalling needs of these > users at the time, Swift began its access control story with just three > access modifiers: public, private, and internal then grew fileprivate and > open as the need to express locality of implementation and "subclassability" > arose respectively. In doing so, Swift's access control scheme has become > anti-modular. > > Proposed solution > > We propose the introduction of a lightweight module system for Swift. More > than simply namspaces, a module declaration interacts with Swift's access > control to provide an API boundary that allows better control over an > interface's design. > > Detailed design > > Syntax > > A module is a named region that introduces a lexical scope into which > declarations may be nested. The name of the module can be used to access > these member declarations. A module, like other aggregate structures in > Swift, may be extended with new declarations over one or more translation > units (files). > > We propose a new declaration kind, module-decl be added to the language. A > proposed grammar using the new modulekeyword is given below: > > GRAMMAR OF A MODULE DECLARATION > > module-declaration -> `module` module-identifier module-body > module-name -> identifier > module-body -> { module-members(opt) } > module-members -> module-member module-members(opt) > module-member -> declaration | compiler-control-statement > GRAMMAR OF A DECLARATION > > + declaration -> module-declaration > General Semantics > > Syntax and semantics for imports, as it already supports referencing > submodules imported from C and Objective-C modules, remains unchanged: > > // The outermost module is given explicitly > // by passing `-module-name=Foo` or exists implicitly, as today. > // module Foo { > public class A {} > > module Bar { > module Baz { > public class C {} > } > > public class B {} > } > > let message = "Hello, Wisconsin!" > // } // End declarations added to module Foo. > To consume this interface: > > // imports all of Foo, Foo.Bar, and Foo.Bar.Baz > import Foo.Bar.Baz > > // imports Foo.A as A > import class Foo.A > // imports Foo.Bar.B as B > import class Foo.Bar.B > // imports Foo.Bar.Baz.C as C > import class Foo.Bar.Baz.C > A module declaration may only appear as a top-level entity or as a member of > another module declaration. The following code is therefore invalid: > > module Foo { > class Bar { > module Baz {} // error: module declaration cannot be nested inside type > 'Bar' > } > } > To extend an existing module declaration, simply reference its module name in > an extension declaration. > > // In module 'Foo' > module Bar { > public class A {} > > module Baz {} > } > > extension Bar { > public struct B {} > } > > extension Bar.Baz { > public enum C { case D } > } > Modules and Access Control > > The semantics of some existing access control modifiers shall also be > extended to support module declarations: > > open and public declarations are exported by a module for consumption by > clients of the module. > internal declarations scope over the entire module and any derived submodules. > By default, to preserve encapsulation of interfaces, modules are "sealed" and > may only be "opened" by explicit named import. However, it is often desirable > to export a module and a set of submodules or even modules from external > dependencies along with a given interface. We propose the public keyword be > used for this purpose: > > // Defines top-level module "Foo" > //module Foo { > public import Foo.Bar.Baz > public import Foundation.Date > //} > Which then causes the following (sub)modules to be imported into scope along > with Foo: > > // imports Foo, Foo.Bar.Baz, and Foundation.Date > import Foo > To support existing Swift packages that cannot have opted into modules, and > to preserve the scriptable nature of Swift, module declarations shall be > optional. Any Swift program that does not declare at least one top-level > module explicitly is considered part of an unnamed special "Global Module" > with the same rules of access control as today. To give declarations in the > Global Module an explicit module without using a module declaration, use the > -module-name flag. > > Impact on Existing Code > > This proposal is intentionally additive. There is no impact on existing code. > > Alternatives considered > > Explicit Modules Everywhere > > Declarations in the top-level of a program exist today in the top-level of > the corresponding module. If desired, this module declaration could be > required to be explicit like so: > > module Foo { > module Bar { > module Baz {} > } > } > However, we feel that imposing such a requirement not only complicates the > outermost scope, it requires inserting needless extension Foo {} scopes in > every file. It also violates the principle of progressive disclosure by > forcing all new adoptees of Swift to learn what a module is without actually > using the module system. > > Nested Extensions > > Nested module extensions may be "expanded" as it were to the following: > > module Foo { > module Bar {} > } > > extension Foo { > extension Bar {} > } > However, this syntax is currently not enabled in general in Swift. This > problem should be revisted in a future proposal. > > Deprecations (Source-Breaking Changes) > > The system described above is intended to be entirely source and binary > compatible. Nonetheless, in its design we feel we have obviated certain > existing features and recommend their deprecation in future proposals: > > fileprivate access can be recreated by creating a private "utility submodule" > containing declarations of at least internal access. > @_exported, the private directive to re-export modules today, should be > deprecated and removed. > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution