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

Xiaodi Wu xiaodi.wu at gmail.com
Tue Feb 21 21:03:13 CST 2017


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

>
> On Feb 21, 2017, at 9:37 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Tue, Feb 21, 2017 at 8:22 PM, Robert Widmann <devteam.codafi at gmail.com>
> wrote:
>
>>
>> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>>
>>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution
>>> <swift-evolution at swift.org> wrote:
>>>
>>> To my mind, any submodule system for Swift should be designed to relieve
>>> the pressure for long files, and make it easy to group tightly related
>>> files into a single unit with shared visibility. That way developers can
>>> easily organize their code into smaller files while utilizing Swift’s
>>> pattern of providing protocol conformances in extensions and keeping
>>> implementation details hidden from the rest of the module at large.
>>>
>>>
>>> Wonderful, because that’s absolutely supported by this proposal.  To
>>> group tightly related files into a single unit, simply declare a submodule
>>> for them and extend it in each of your related files.
>>>
>>
>> It's supported, but it isn't first-class. By this I mean: there are two
>> distinguishable uses supported by your proposal, lumped together by the
>> fact that they are both about grouping units of code together. Put crudely,
>> one use case is grouping lines of code, while the other is about grouping
>> files of code. The merits of supporting both have already been debated in
>> this discussion. The issue I'll touch on is supporting both with the same
>> syntax. The chief drawbacks here are:
>>
>>
>> What exactly would be required to *make* it first class?  Referencing
>> file names in the module declaration?
>>
>
>  See below.
>
>> - It makes sense to use braces to group lines of code, but it makes no
>> sense to use braces to group files of code; this just causes entire files
>> to be indented.
>>
>>
>> If braces aren’t used to demarcate scopes, nesting modules becomes
>> ambiguous.
>>
>
> Again, let's observe the distinction about grouping files vs. grouping
> lines.
>
> Grouping files does not require braces: if the intended use of your
> feature were to label files X, Y, and Z as belonging to one submodule and
> A, B, and C to another, it would not matter if X, Y, and Z belonged to
> Foo.Bar and A, B, and C to Foo.Bar.Baz: your syntax would not require
> braces.
>
>
>> It’s important to note that indentation is one particular style.  LLVM
>> code style, in particular, chooses not to indent after namespace
>> declarations.  This issue also crops up when dealing with nested type
>> declarations, and I distinctly remember it not being a big enough deal to
>> "fix this" at the time when a proposal to “flatten” these declaration was
>> brought up.
>>
>
> Mine is not a critique of the syntax itself; I don't particularly care
> about indents, nor do I mind not indenting namespaces.
>
> What I'm saying is, you would not have chosen to require braces if your
> proposed feature were aimed at making the grouping of files into submodules
> as simple as possible. You chose to accommodate grouping lines using the
> same syntax as grouping files over the simplest design for grouping files.
> Make no mistake, this promotes one use over another.
>
>
> Ah, I see.  Yes, one of the stated goals is to become
> filesystem-independent.  We certainly cannot do that by encouraging the
> alternative.
>

Swift's current design is deliberately not file system-independent. A
submodule design built on top of Swift could preserve that. Your draft
proposal makes two changes: it introduces a design for submodules; and, it
eliminates files as a unit of code by default (not least by declaring
`fileprivate` redundant). To my mind, you have presented no justification
for the second change other than to say that it is a stated goal--but why?

>
> - Because some lines of code necessarily precede some other lines of code,
>> it makes sense to declare the first group using `module` and to extend that
>> with the second group using `extension`. However, because a file of code
>> does not necessarily precede another file of code, it is arbitrary which
>> file is surrounded with a `module` declaration and which one is surrounded
>> with an `extension` declaration.
>>
>>
>> Absolutely.  But it is similarly arbitrary which public APIs are exposed
>> in a type declaration and which are exposed in an extension declaration.
>>
>
> Not entirely, no. Stored properties must be in the type declaration. Enum
> cases must be in the type declaration. Perhaps you regard these as
> temporary inconveniences of the current grammar; I see them as quite
> reasonable ways to give some consistency as to what's written where in a
> language where types can be retroactively extended. In a very real sense,
> you must read the type declaration before you read the extensions in order
> to understand the latter. By comparison, there is nothing that must be in
> your proposed module declaration.
>
>
>> My hope is that the module declaration itself will become the
>> one-stop-shop for re-exports and general public bookkeeping just as
>> aggregate declarations are today.  Module extensions exist to accommodate
>> users that wish to break related functionality across files or into
>> separate independent regions within the same file for the same reasons type
>> extensions exist.
>>
>
> Indeed, that you phrase it this way supports Nevin's argument. _Module
> extensions_ exist to accommodate his use case; however, his use case
> (which, mind you, is what I think most people are thinking of when it comes
> to submodules, given previous threads on this topic) isn't the raison
> d'etre for your submodule proposal. Quite simply, a syntax that
> accommodates both grouping lines and grouping files cannot make the latter
> first class, because the former necessarily requires more ceremony.
>
>
> Okay, but the question still stands: what do we need to make Nevin's
> use-case first class?
>

We need to have either *two* spellings for a submodule feature that
supports both grouping files and grouping lines of code, or we need to have
*two* features, one for grouping files and another for grouping lines of
code. In any case, the spelling for grouping files should:
- Not require braces
- Not require one file to be a `module` and another to be an `extension`

The simplest such spelling would be:

File A:
```
module Foo
// rest of file
```

File B:
```
module Foo
// rest of file
```

To my mind, we’ve offered a syntax and semantics internal to the language
> that supports file-only aggregation because file-only aggregation enables a
> subset of the actual use cases of this module system.  We aren’t enforcing
> this by compiler-fiat because it is a stylistic choice that can be enforced
> by a linter.
>

It's not enough to offer a syntax and semantics that supports it; if it is
the intended major use case, the design ought to reflect that by making
that use case no less cumbersome than necessary.

Any variables defined with `internal` access will be visible across those
>>> files to those extensions and only those extensions (see the section on
>>> access control and modules).  Any variables declared fileprivate or private
>>> will, obviously, not be visible across these files.  As an example:
>>>
>>> // FooUtilities.swift
>>> //
>>> // -module-name=Foo
>>> // module Foo {
>>> // Defines Foo.Utilities
>>> module Utilities {
>>>   public func exportableOutsideThisSubmodule() {}
>>>   func visibleInThisSubmodule() {}
>>>   private func invisibleToOtherFiles() {}
>>> }
>>> //}
>>>
>>> // FooUtilities+MoreUtilities.swift
>>> extension Utilities {
>>>   private func privateHelper() {
>>>     visibleInThisSubmodule()
>>>   }
>>> }
>>>
>>> I’m not sure where you got the impression that we were just trying to
>>> make another fileprivate happen.
>>>
>>>
>>> Nevin
>>> _______________________________________________
>>> 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/cf883d99/attachment.html>


More information about the swift-evolution mailing list