<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 3, 2017, at 12:35 PM, David Hart &lt;<a href="mailto:david@hartbit.com" class="">david@hartbit.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">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.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>Thanks David,</div><br class=""><blockquote type="cite" class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Comments inline:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">On 3 Mar 2017, at 16:24, Karim Nassar via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class="">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.<span class="Apple-converted-space">&nbsp;</span><br class=""><br class="">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.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I don't think your use cases are outliers. I think your solution really feels more Swifty by starting simple.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">I’m including the write-up below, but it’s also available as a gist:<span class="Apple-converted-space">&nbsp;</span><a href="https://gist.github.com/anonymous/9806f4274f1e13860670d6e059be5dce" class="">https://gist.github.com/anonymous/9806f4274f1e13860670d6e059be5dce</a><br class=""><br class="">—<br class=""><br class=""># Sub-modules<br class=""><br class="">A sub-module solution in Swift should have the following properties:<br class=""><br class="">* Extremely light-weight<br class="">* Low API surface area<br class="">* Adopt progressive disclosure<br class="">* Integrate with Access Control features to enable a level of encapsulation &amp; hiding between the Module and File level<br class="">* Be permeable when desired<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Yes, yes, yes. Very good goals :)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>:)</div><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">## Discussion<br class=""><br class="">As we get deeper into building real applications &amp; 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.<span class="Apple-converted-space">&nbsp;</span><br class=""><br class="">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.<br class=""><br class="">I have seen this proliferation of Huge Sprawling Files (HSFs) in my own code, and seek a way to combat this rising tide.<br class=""><br class="">## Goals<span class="Apple-converted-space">&nbsp;</span><br class=""><br class="">It is a goal of this proposal to:<br class=""><br class="">* Suggest a mechanism for organizing code between the Module and File levels that is as lightweight and low-friction as possible<br class="">* Provide mechanisms for authors to create both "hard" and "soft" API boundaries between the Module and File levels of their code<br class=""><br class="">## Anti-Goals<br class=""><br class="">It is not a goal of this proposal to:<br class=""><br class="">* Move Swift away from filesystem-based organization<br class="">* Significantly alter the current Access Control philosophy of Swift<br class=""><br class="">## Proposal Notes<br class=""><br class="">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.<br class=""><br class="">Unless specified otherwise, all spellings proposed below are to be considered straw-men, and merely illustrative of the concepts.<br class=""><br class="">## Proposed Solution<br class=""><br class="">Two things are clear to me after using Swift and following the Swift Evolution list since their respective publications:<br class=""><br class="">1. Swift has a preference for file-based organization<br class="">2. Vocal Swift Users dislike `fileprivate` and want to revert to Swift2-style `private`<br class=""><br class="">Because of #1, this proposal does not seek to change Swift's inherent file-system organization, and instead will expand on it.<br class=""><br class="">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.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I have posted a proposal which proposes #2. It should hopefully get merged and reviewed soon.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">### Changes to Access Control Modifiers<br class=""><br class="">As part of this proposal, I suggest the following changes to Swift 3's Access Control modifiers:<br class=""><br class="">* Revert `private` to Swift 2's meaning: "hidden outside the file"<br class="">* Remove `fileprivate` as redundant<br class=""><br class="">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.<br class=""><br class="">Changes that *are* necessary are:<br class=""><br class="">* Change the spelling of `internal` to `module` (making `module` the new default)<br class="">* Introduce a new modifier `internal` to mean "Internal to the current sub-module and its child-sub-modules"<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">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.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">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.<br class=""><br class="">The new `module` modifier allows authors to make APIs permeable between sub-modules while still hidden outside the owning Module if desired.<br class=""><br class="">All other Access Control modifiers behave the same as they currently do irrespective of sub-module boundaries, so:<br class=""><br class="">* `public` =&gt; Visible outside the Module<br class="">* `open` =&gt; Sub-classable outside the Module<br class=""><br class="">### Making a Sub-module<br class=""><br class="">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:<br class=""><br class="">```<br class="">// &nbsp;__submodule.swift<br class="">// &nbsp;MyModule<br class=""><br class="">submodule SubA<br class=""><br class="">```<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">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.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div>Thanks, this is exactly why I posted this original concept—to spur conversation.<br class=""><div><br class=""></div><div>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:</div><div><br class=""></div><div>**all spellings are straw-men!**</div><div><br class=""></div><div>```</div><div>// declared in any file</div><div><br class=""></div><div>// this is the same sub-module declaration previously declared in the magic file,&nbsp;</div><div>// and serves the same purpose of declaring the sub-module,&nbsp;</div><div>// and acting as a home for future configuration:</div><div><br class=""></div><div>submodule SubA&nbsp;</div><div><br class=""></div><div><br class=""></div><div>// announced once in any file you wish to include in the sub-module:</div><div><br class=""></div><div>in_submodule SubA</div><div><br class=""></div><div>```</div><div><br class=""></div><div>Some issues I see with this:</div><div><ul class="MailOutline"><li class="">increases the surface area— need to introduce a new declaration for announcing sub-module inclusion</li><li class="">Either:&nbsp;</li><ul class=""><li class="">introduces a new *kind* of declaration… `in_submodule` which can only appear once in a file (which would need to be compiler-enforced), OR:</li><li class="">increases complexity by allowing multiple sub-module declarations in a file</li></ul></ul></div><div><br class=""></div><div><br class=""></div><div>I’ll think further on (and am fully open to ideas for) other approaches.</div><div><br class=""></div><div>Thanks</div><div>—Karim</div><div><br class=""></div></div><br class=""></body></html>