> On Feb 20, 2017, at 7:56 PM, Robert Widmann via swift-evolution
> <[email protected]> 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
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a> if you
> desire.
>
> Cheers,
>
> ~Robert Widmann
>
> Modular Swift
>
> Proposal: SE-NNNN <https://gist.github.com/CodaFi/NNNN-filename.md>
> Authors: Robert Widmann <https://github.com/codafi>, Jaden Geller
> <https://github.com/JadenGeller>
> Review Manager: TBD
> Status: Awaiting review
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#introduction>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 <applewebdata://D267D5BF-B7AA-49E6-B592-9BE742F01507>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#motivation>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.
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#proposed-solution>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.
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#detailed-design>Detailed
> design
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#syntax>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
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#general-semantics>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
I’ve read this a couple of times now and I keep getting hung up on this. Is
the comment a mistake? I would only expect to get Foo.Bar.Baz here, not
Foo.Bar or Foo itself. If it’s not a mistake, why did you choose this behavior?
>
> // 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 }
> }
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#modules-and-access-control>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.
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#impact-on-existing-code>Impact
> on Existing Code
>
> This proposal is intentionally additive. There is no impact on existing code.
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#alternatives-considered>Alternatives
> considered
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#explicit-modules-everywhere>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.
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#nested-extensions>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.
>
>
> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#deprecations-source-breaking-changes>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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution