[swift-evolution] [Proposal][Discussion] Modular Swift

Robert Widmann devteam.codafi at gmail.com
Tue Feb 21 20:48:53 CST 2017


> On Feb 21, 2017, at 9:44 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 8:32 PM, Robert Widmann <devteam.codafi at gmail.com <mailto:devteam.codafi at 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.wu at gmail.com <mailto:xiaodi.wu at gmail.com>> wrote:
>> 
>> On Tue, Feb 21, 2017 at 8:15 PM, Robert Widmann via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> On Feb 21, 2017, at 7:46 AM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>>> On Feb 21, 2017, at 1:28 AM, Daniel Duan via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at 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 at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170221/0ea5150b/attachment.html>


More information about the swift-evolution mailing list