<div dir="ltr">On Tue, Feb 21, 2017 at 8:15 PM, Robert Widmann via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div class="h5"><blockquote type="cite"><div>On Feb 21, 2017, at 7:46 AM, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-5209089359769303238Apple-interchange-newline"><div><div><blockquote type="cite">On Feb 21, 2017, at 1:28 AM, Daniel Duan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br>It has been my hope that a lightweight module system will remove the need for `private` *and* `fileprivate`.<br></blockquote><br>I really doubt it will. `private`/`fileprivate` works because you can also access `internal` at the same time.<br><br>What I mean by that is, think about code like this:<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>// Foo.swift<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public class Foo {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public init() { … }<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>func doBar() -&gt; Quux {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>return helper(in: randomRange())<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>private func helper(in range: Range&lt;Int&gt;) -&gt; Quux {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>…<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>// Bar.swift<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public class Bar {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public static let shared = Bar()<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>func baz(with foo: Foo) {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>let quux = foo.doBar()<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>process(quux)<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>private func process(_ quux: Quux) {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>…<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br>These classes have `public` APIs that are externally visible, `internal` APIs for communicating with each other, and `private` APIs for implementation details. Now try to reproduce the same design with submodules and `public`/`internal` only:<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public import MyMod.Foo<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public import MyMod.Bar<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>module Foo {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public class Foo {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public init() { … }<br><br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>??? func doBar() -&gt; Quux {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>return helper(in: randomRange())<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>func helper(in range: Range&lt;Int&gt;) -&gt; Quux {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>…<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>// Bar.swift<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>module Bar {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public class Bar {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public static let shared = Bar()<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>??? func baz(with foo: Foo) {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>let quux = foo.doBar()<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>process(quux)<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>func process(_ quux: Quux) {<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>…<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br>The `doBar()` and `baz()` methods have to be either exposed to third parties or kept away from yourself. That&#39;s just not viable.<br><br></div></div></blockquote><div><br></div></div></div><div>If they must communicate, they can be a part of the same (sub)module.  This makes filling in these annotations trivial.  Nobody actually uses modules to wall off their own APIs from themselves like this, they use submodules to encapsulate the internal parts and surface public APIs in the parent.</div></div></div></blockquote><div><br></div><div>I think you&#39;ll find a ton of people on this list who would want to use submodules precisely to wall off their own APIs from themselves. Witness the hundreds of messages about new syntax to do just that.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><br></div><div><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>module Bar {<span class=""><br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public class Foo {<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public init() { … }<br><blockquote type="cite"></blockquote><font color="#5856d6"><br></font><blockquote type="cite"></blockquote><font color="#5856d6"><br></font><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span></span>internal func doBar() -&gt; Quux {<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>return helper(in: randomRange())<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><blockquote type="cite"></blockquote><font color="#5856d6"><br></font><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>internal func helper(in range: Range&lt;Int&gt;) -&gt; Quux {<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>…<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><blockquote type="cite"></blockquote><font color="#5856d6"><br></font><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>// Bar.swift<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>extension Bar {<span class=""><br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public class Bar {<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>public static let shared = Bar()<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span></span>internal func baz(with foo: Foo) {<span class=""><br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>let quux = foo.doBar()<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>process(quux)<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span></span>internal func process(_ quux: Quux) {<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>…<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><blockquote type="cite"></blockquote><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-5209089359769303238Apple-tab-span" style="white-space:pre-wrap">        </span>}</div><span class=""><br><blockquote type="cite"><div><div>-- <br>Brent Royal-Gordon<br>Architechies<br><br>______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></div></blockquote></span></div><br></div><br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div></div>