> On Mar 3, 2017, at 12:35 PM, David Hart <da...@hartbit.com> wrote:
> 
> I strongly agree with all your points. The other submodule proposals are too 
> complex for me so I'm very happy to see a different solution which more 
> closely fits my design priorities.
> 

Thanks David,

> Comments inline:
> 
>> On 3 Mar 2017, at 16:24, Karim Nassar via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> I’ve read through the last couple of Swift (sub)Module proposals put 
>> forward, and since my particular use-cases for a sub-module solution seemed 
>> to be under-served by them, I’ve decided to write up my thoughts on the 
>> matter to prompt discussion. 
>> 
>> Perhaps my use-cases are outliers, and my approach will be deemed naive by 
>> the community… I’m happy to learn better ways of doing things in Swift, and 
>> welcome any thoughts, criticism, or illumination related to these ideas.
> 
> I don't think your use cases are outliers. I think your solution really feels 
> more Swifty by starting simple.
> 
>> I’m including the write-up below, but it’s also available as a gist: 
>> https://gist.github.com/anonymous/9806f4274f1e13860670d6e059be5dce 
>> <https://gist.github.com/anonymous/9806f4274f1e13860670d6e059be5dce>
>> 
>> —
>> 
>> # Sub-modules
>> 
>> A sub-module solution in Swift should have the following properties:
>> 
>> * Extremely light-weight
>> * Low API surface area
>> * Adopt progressive disclosure
>> * Integrate with Access Control features to enable a level of encapsulation 
>> & hiding between the Module and File level
>> * Be permeable when desired
> 
> Yes, yes, yes. Very good goals :)

:)

>> ## Discussion
>> 
>> As we get deeper into building real applications & frameworks with Swift, we 
>> begin to realize that having a way to express relationships between types is 
>> desireable. Currently, Swift only allows us to express these relationships 
>> at two levels, the Module and the File. 
>> 
>> The Module boundary is acceptable for small, focused frameworks, while the 
>> File boundary is acceptable for small, focused Types, but both levels can be 
>> unweildy when dealing with certain cases where a cluster of internally 
>> related types needs to know about each other but may only want to publish a 
>> narrow set of APIs to the surrounding code, or in large complex applications 
>> which are necessarily structured as a single Module. In these cases, we wind 
>> up with large monolithic Modules or (even worse) large monolithic Files.
>> 
>> I have seen this proliferation of Huge Sprawling Files (HSFs) in my own 
>> code, and seek a way to combat this rising tide.
>> 
>> ## Goals 
>> 
>> It is a goal of this proposal to:
>> 
>> * Suggest a mechanism for organizing code between the Module and File levels 
>> that is as lightweight and low-friction as possible
>> * Provide mechanisms for authors to create both "hard" and "soft" API 
>> boundaries between the Module and File levels of their code
>> 
>> ## Anti-Goals
>> 
>> It is not a goal of this proposal to:
>> 
>> * Move Swift away from filesystem-based organization
>> * Significantly alter the current Access Control philosophy of Swift
>> 
>> ## Proposal Notes
>> 
>> Please take the following proposal wholely as a Straw-Man... I would be 
>> equally satisfied with any solution which meets the critera described at the 
>> top of this document.
>> 
>> Unless specified otherwise, all spellings proposed below are to be 
>> considered straw-men, and merely illustrative of the concepts.
>> 
>> ## Proposed Solution
>> 
>> Two things are clear to me after using Swift and following the Swift 
>> Evolution list since their respective publications:
>> 
>> 1. Swift has a preference for file-based organization
>> 2. Vocal Swift Users dislike `fileprivate` and want to revert to 
>> Swift2-style `private`
>> 
>> Because of #1, this proposal does not seek to change Swift's inherent 
>> file-system organization, and instead will expand on it.
>> 
>> Since I personally fall into the camp described by #2, and most of the 
>> community response to this has been "Lets wait to deal with that until 
>> sub-modules", I'm making this proposal assuming that solving that quagmire 
>> is in-scope for this propsoal.
> 
> I have posted a proposal which proposes #2. It should hopefully get merged 
> and reviewed soon.
> 
>> ### Changes to Access Control Modifiers
>> 
>> As part of this proposal, I suggest the following changes to Swift 3's 
>> Access Control modifiers:
>> 
>> * Revert `private` to Swift 2's meaning: "hidden outside the file"
>> * Remove `fileprivate` as redundant
>> 
>> This is potentially a source-breaking change. However, it is interesting to 
>> note that this change is **not** required for the following proposal to 
>> function.
>> 
>> Changes that *are* necessary are:
>> 
>> * Change the spelling of `internal` to `module` (making `module` the new 
>> default)
>> * Introduce a new modifier `internal` to mean "Internal to the current 
>> sub-module and its child-sub-modules"
> 
> I like that you introduce only one access level and maintain source 
> compatibility. This is also what makes the proposal fit the "progressive 
> disclosure" goal: you don't need to learn or worry about the `module` access 
> level until you start working with submodules.
> 
>> These changes are *not* source-breaking because the new `internal` modifier 
>> acts exactly as the old `internal` modifier unless it is used within a 
>> sub-module. The specific spelling of this new `internal` modifier is 
>> necessary to maintain backwards source compatibility.
>> 
>> The new `module` modifier allows authors to make APIs permeable between 
>> sub-modules while still hidden outside the owning Module if desired.
>> 
>> All other Access Control modifiers behave the same as they currently do 
>> irrespective of sub-module boundaries, so:
>> 
>> * `public` => Visible outside the Module
>> * `open` => Sub-classable outside the Module
>> 
>> ### Making a Sub-module
>> 
>> To create a sub-module within a Module (or sub-module) is simple: The author 
>> creates a directory, and places a "sub-module declaration file" within the 
>> directory:
>> 
>> ```
>> //  __submodule.swift
>> //  MyModule
>> 
>> submodule SubA
>> 
>> ```
> 
> Like the previous response, I think this potentially the weakest part of he 
> proposal. I like the idea of a file-system based submodule system but I'm not 
> sure I like this version of it. People are going to be very vocal about this 
> too. Perhaps you could rewrite the proposal with several solutions for this 
> part? Let people discuss the different solutions.

Thanks, this is exactly why I posted this original concept—to spur conversation.

An alternate approach might be to eliminate the “magic file” and directory 
dependency and replace them with explicit sub-module adoption per file. 
Something like this:

**all spellings are straw-men!**

```
// declared in any file

// this is the same sub-module declaration previously declared in the magic 
file, 
// and serves the same purpose of declaring the sub-module, 
// and acting as a home for future configuration:

submodule SubA 


// announced once in any file you wish to include in the sub-module:

in_submodule SubA

```

Some issues I see with this:
increases the surface area— need to introduce a new declaration for announcing 
sub-module inclusion
Either: 
introduces a new *kind* of declaration… `in_submodule` which can only appear 
once in a file (which would need to be compiler-enforced), OR:
increases complexity by allowing multiple sub-module declarations in a file


I’ll think further on (and am fully open to ideas for) other approaches.

Thanks
—Karim


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to