> On Feb 21, 2017, at 9:37 PM, Xiaodi Wu <[email protected]> wrote:
>
> On Tue, Feb 21, 2017 at 8:22 PM, Robert Widmann <[email protected]
> <mailto:[email protected]>>wrote:
>
>> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution
>>> <[email protected] <mailto:[email protected]>> 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.
>
>> - 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? 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.
>> 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
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution