[swift-evolution] [Proposal][Discussion] Modular Swift

Xiaodi Wu xiaodi.wu at gmail.com
Tue Feb 21 20:44:37 CST 2017


On Tue, Feb 21, 2017 at 8:32 PM, Robert Widmann <devteam.codafi at gmail.com>
wrote:

> There’s an important distinction between the ability to wall off, and this
> particular instance of doing so.  By definition, a module allows for the
> encapsulation and export of a subset of an API, the same way access
> modifiers allow types to expose an interface.  If the sub-parts of that API
> must interact, they must by definition share the same concerns and belong
> together under the same submodule.  If their implementations require
> separation then further subdivisions can be made with further submodules.
> This is the design practice encouraged, and put to good use, by every other
> language with modules since the heyday of Modula, and breaking that
> contract by creating unnecessary parent divisions to introduce headaches
> for yourself is just another case of anti-modular use of a modular system.
> There’s nothing we can do to stop you from asking for this, but that also
> doesn’t excuse the poor design choice here - especially when it can be
> rectified by reshuffling your own dependency graph.
>

Indeed, I won't disagree with you wrt _modules_. I notice you titled this
thread "submodules" but propose a syntax that uses the word `module`. Left
unsaid, I'd imagine, is that you regard a submodule as a
module-within-a-module.

This is *not*, as I understand it, what most people on this list are asking
for wrt _submodules_. Instead, they are asking for a unit of code greater
than a file but less than a module. To parallel that new facility, they
want an access level greater than fileprivate but less than internal. This
draft proposal (in its failure to acknowledge this frequent ask) explicitly
but _silently_ rejects those motivations.

On Feb 21, 2017, at 9:19 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Tue, Feb 21, 2017 at 8:15 PM, Robert Widmann via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> On Feb 21, 2017, at 7:46 AM, Brent Royal-Gordon via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> On Feb 21, 2017, at 1:28 AM, Daniel Duan via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> It has been my hope that a lightweight module system will remove the need
>> for `private` *and* `fileprivate`.
>>
>>
>> I really doubt it will. `private`/`fileprivate` works because you can
>> also access `internal` at the same time.
>>
>> What I mean by that is, think about code like this:
>>
>> // Foo.swift
>> public class Foo {
>> public init() { … }
>>
>> func doBar() -> Quux {
>> return helper(in: randomRange())
>> }
>>
>> private func helper(in range: Range<Int>) -> Quux {
>>>> }
>> }
>>
>> // Bar.swift
>> public class Bar {
>> public static let shared = Bar()
>>
>> func baz(with foo: Foo) {
>> let quux = foo.doBar()
>> process(quux)
>> }
>>
>> private func process(_ quux: Quux) {
>>>> }
>> }
>>
>> These classes have `public` APIs that are externally visible, `internal`
>> APIs for communicating with each other, and `private` APIs for
>> implementation details. Now try to reproduce the same design with
>> submodules and `public`/`internal` only:
>>
>> public import MyMod.Foo
>> public import MyMod.Bar
>>
>> module Foo {
>> public class Foo {
>> public init() { … }
>>
>>
>> ??? func doBar() -> Quux {
>> return helper(in: randomRange())
>> }
>>
>> func helper(in range: Range<Int>) -> Quux {
>>>> }
>> }
>> }
>>
>> // Bar.swift
>> module Bar {
>> public class Bar {
>> public static let shared = Bar()
>>
>> ??? func baz(with foo: Foo) {
>> let quux = foo.doBar()
>> process(quux)
>> }
>>
>> func process(_ quux: Quux) {
>>>> }
>> }
>> }
>>
>> The `doBar()` and `baz()` methods have to be either exposed to third
>> parties or kept away from yourself. That's just not viable.
>>
>>
>> If they must communicate, they can be a part of the same (sub)module.
>> This makes filling in these annotations trivial.  Nobody actually uses
>> modules to wall off their own APIs from themselves like this, they use
>> submodules to encapsulate the internal parts and surface public APIs in the
>> parent.
>>
>
> I think you'll find a ton of people on this list who would want to use
> submodules precisely to wall off their own APIs from themselves. Witness
> the hundreds of messages about new syntax to do just that.
>
>
>>
>> module Bar {
>>
>> public class Foo {
>>
>> public init() { … }
>>
>>
>>
>> internal func doBar() -> Quux {
>>
>> return helper(in: randomRange())
>>
>> }
>>
>>
>> internal func helper(in range: Range<Int>) -> Quux {
>>
>>>>
>> }
>>
>> }
>>
>> }
>>
>>
>> // Bar.swift
>>
>> extension Bar {
>>
>> public class Bar {
>>
>> public static let shared = Bar()
>>
>>
>> internal func baz(with foo: Foo) {
>>
>> let quux = foo.doBar()
>>
>> process(quux)
>>
>> }
>>
>>
>> internal func process(_ quux: Quux) {
>>
>>>>
>> }
>>
>> }
>> }
>>
>> --
>> Brent Royal-Gordon
>> Architechies
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170221/a2e88fd9/attachment.html>


More information about the swift-evolution mailing list