> On Feb 21, 2017, at 9:44 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 8:32 PM, Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>> wrote:
> There’s an important distinction between the ability to wall off, and this 
> particular instance of doing so.  By definition, a module allows for the 
> encapsulation and export of a subset of an API, the same way access modifiers 
> allow types to expose an interface.  If the sub-parts of that API must 
> interact, they must by definition share the same concerns and belong together 
> under the same submodule.  If their implementations require separation then 
> further subdivisions can be made with further submodules.  This is the design 
> practice encouraged, and put to good use, by every other language with 
> modules since the heyday of Modula, and breaking that contract by creating 
> unnecessary parent divisions to introduce headaches for yourself is just 
> another case of anti-modular use of a modular system.  There’s nothing we can 
> do to stop you from asking for this, but that also doesn’t excuse the poor 
> design choice here - especially when it can be rectified by reshuffling your 
> own dependency graph.
> 
> Indeed, I won't disagree with you wrt _modules_. I notice you titled this 
> thread "submodules" but propose a syntax that uses the word `module`. Left 
> unsaid, I'd imagine, is that you regard a submodule as a 
> module-within-a-module.
> 
> This is *not*, as I understand it, what most people on this list are asking 
> for wrt _submodules_. Instead, they are asking for a unit of code greater 
> than a file but less than a module. To parallel that new facility, they want 
> an access level greater than fileprivate but less than internal. This draft 
> proposal (in its failure to acknowledge this frequent ask) explicitly but 
> _silently_ rejects those motivations.

So they want to be able to aggregate interfaces and define their exportability, 
while also maintaining the ability to scope a declaration to a particular 
grouping.  This is, quite literally, the semantics we have defined - with 
modules enabling aggregation and `internal` stretching to become this “new” 
access control kind.

> 
>> On Feb 21, 2017, at 9:19 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> On Tue, Feb 21, 2017 at 8:15 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Feb 21, 2017, at 7:46 AM, Brent Royal-Gordon via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> On Feb 21, 2017, at 1:28 AM, Daniel Duan via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> It has been my hope that a lightweight module system will remove the need 
>>>> for `private` *and* `fileprivate`.
>>> 
>>> I really doubt it will. `private`/`fileprivate` works because you can also 
>>> access `internal` at the same time.
>>> 
>>> What I mean by that is, think about code like this:
>>> 
>>>     // Foo.swift
>>>     public class Foo {
>>>             public init() { … }
>>> 
>>>             func doBar() -> Quux {
>>>                     return helper(in: randomRange())
>>>             }
>>> 
>>>             private func helper(in range: Range<Int>) -> Quux {
>>>                     …
>>>             }
>>>     }
>>> 
>>>     // Bar.swift
>>>     public class Bar {
>>>             public static let shared = Bar()
>>> 
>>>             func baz(with foo: Foo) {
>>>                     let quux = foo.doBar()
>>>                     process(quux)
>>>             }
>>>             
>>>             private func process(_ quux: Quux) {
>>>                     …
>>>             }
>>>     }
>>> 
>>> 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:
>>> 
>>>     public import MyMod.Foo
>>>     public import MyMod.Bar
>>> 
>>>     module Foo {
>>>             public class Foo {
>>>                     public init() { … }
>>> 
>>> 
>>>                     ??? func doBar() -> Quux {
>>>                             return helper(in: randomRange())
>>>                     }
>>> 
>>>                     func helper(in range: Range<Int>) -> Quux {
>>>                             …
>>>                     }
>>>             }
>>>     }
>>> 
>>>     // Bar.swift
>>>     module Bar {
>>>             public class Bar {
>>>                     public static let shared = Bar()
>>>                     
>>>                     ??? func baz(with foo: Foo) {
>>>                             let quux = foo.doBar()
>>>                             process(quux)
>>>                     }
>>>             
>>>                     func process(_ quux: Quux) {
>>>                             …
>>>                     }
>>>             }
>>>     }
>>> 
>>> The `doBar()` and `baz()` methods have to be either exposed to third 
>>> parties or kept away from yourself. That's just not viable.
>>> 
>> 
>> 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.
>> 
>> I think you'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.
>>  
>> 
>>      module Bar {
>>              public class Foo {
>>                      public init() { … }
>> 
>> 
>>                      internal func doBar() -> Quux {
>>                              return helper(in: randomRange())
>>                      }
>> 
>>                      internal func helper(in range: Range<Int>) -> Quux {
>>                              …
>>                      }
>>              }
>>      }
>> 
>>      // Bar.swift
>>      extension Bar {
>>              public class Bar {
>>                      public static let shared = Bar()
>>                      
>>                      internal func baz(with foo: Foo) {
>>                              let quux = foo.doBar()
>>                              process(quux)
>>                      }
>>              
>>                      internal func process(_ quux: Quux) {
>>                              …
>>                      }
>>              }
>>      }
>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
> 
> 

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

Reply via email to