> Le 3 mars 2017 à 23:21, Matthew Johnson via swift-evolution 
> <[email protected]> a écrit :
> 
>> 
>> On Mar 3, 2017, at 9:24 AM, Karim Nassar via swift-evolution 
>> <[email protected]> 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’m including the write-up below, but it’s also available as a gist: 
>> 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
>> 
>> ## 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.
>> 
>> ### 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”
> 
> Can you give concrete examples of use cases where a descendent submodule 
> needs access to symbols declared by an ancestor?  I gave some thought to this 
> when drafting my proposal and came to the conclusion that this runs against 
> the grain of layering and is likely to be a bad idea in practice.  If there 
> are use cases I didn’t consider I am very interested in learning about them.
> 
>> 
>> 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
> 
> Why the double underscore prefix?  To make it sort to the top in a file 
> browser?
> 
> Is this file allowed to have any Swift code?  Or is it limited to 
> submodule-related declarations only?  If the latter, why not use an extension 
> such as `.submodule` or `.swiftmodule` to differentiate it from ordinary 
> Swift files and allow the submodule to be named by the name of this file?
> 
>> //  MyModule
>> 
>> submodule SubA
>> 
>> ```
>> 
>> Then any files within that directory are part of the sub-module:
>> 
>> ```
>> //  Foo.swift
>> //  MyModule.SubA
>> 
>> struct Foo {
>>   private var mine: Bool
>>   internal var sub: Bool
>>   module var mod: Bool
>> }
>> 
>> public struct Bar {
>>   module var mod: Bool
>>   public var pub: Bool
>> }
>> 
>> ```
>> 
>> This creates a sub-module called "SubA" within the module "MyModule". All 
>> files within the directory in which this file appears are understood to be 
>> contained by this sub-module.
>> 
>> If in the future we choose to add additional complexity (versioning, 
>> #availability, etc) to the sub-module syntax, the sub-module declaration 
>> gives a natural home for this configuration.
>> 
>> It's important to note some benefits of this approach:
>> 
>> * Using the "special file" means that not all Directories are automatically 
>> submodules
>> * Any given source file may only be a member of 1 submodule at a time
>> * Use of filesystem structure to denote sub-modules plays nicely with source 
>> control
>> * The sub-module structure is instantly clear whether using an IDE (which 
>> can be taught to parse the `__submodule.swift` files to decorate the UI), or 
>> simple text-editor (assuming a convention of naming the Directory the same 
>> as the sub-module, which is a linter problem)
> 
> If we’re going to use the file system to organize submodules this seems like 
> a reasonable approach.  It allows larger submodules to have folder 
> hierarchies within them and also creates a central location for 
> submodule-related declarations.
> 
> A primary flaw I see in this approach is that Xcode is the dominant IDE for 
> Swift and the way Xcode handles files is not conducive to file-system 
> organization.  I really detest the way Xcode handles this and would vastly 
> prefer that it simply reflected the physical file system hierarchy but I 
> don’t think that will change any time soon.  On the other hand maybe a file 
> system based submodule system in Swift would motivate the Xcode team to 
> better reflect the physical file system organization.

I quite love how Xcode allow me to group my source files as I want without 
having to move them around.
This is specially useful when working with languages that support relative 
#include "". Moving an header in an other group don’t break the code.

Moreover, if you want to create a folder for each group in Xcode, you can 
perfectly do that too as Xcode allows you to define a different path for each 
group. So I don’t see how it would prevent using submodule.





_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to