[swift-evolution] [Draft] scope-based submodules
matthew at anandabits.com
Fri Feb 24 16:33:14 CST 2017
> On Feb 24, 2017, at 3:56 PM, Vladimir.S <svabox at gmail.com> wrote:
> Matthew, thank you for sharing this great text!
> Unfortunately was not able to read it in details yet, but after looking for proposed solution, have a quick question.
Thanks for taking a look! I’m looking forward to more feedback later.
> You are proposing to have 'submodule' keyword in each file of that submodule. How can we then solve such issue: imagine that I have swift file with some code in it. I got this file from external source(repository/site), I will periodically update it with newer version for example. I want to use this file in my two submodules, but don't want to 'share' or 'make visible' types/classes/funcs etc from this file with other code outside of these submodules.
> As I understand, with your suggestion the only way is have two copies of that file and append 'submodule' keyword in each. Or I understand the whole idea incorrectly? (Sorry then)
Great question. First, I want to caution that a submodule system in a programming like this is not really intended to facilitate the use of external 3rd party code. It is nothing like git submodules, for example. You’ll almost always be better off using a solution like Carthage or CocoaPods or SwiftPM.
Of course those tools do not allow you restrict the visibility of the external module within your code. It might be interesting to explore ways to restrict the import of external modules to a specific submodule scope in the future. I’m not sure how that might look but I think we could come up with something. That would allow you to integrate a third party dependency in a more robust fashion while restricting access to it in exactly the way you want.
All that aside, I’ll discuss how you could do what you asked using the tools the current proposal offers.
In order to make a file available to more than one submodule without exposing it more broadly you need to create a scope that includes both submodules that use the file as well as a submodule that contains the file. The way you create a scope like this is to place them inside a common parent (or ancestor) submodule. Here is what the structure would look like:
Inside the file you downloaded you would need to declare `submodule Downloaded`.
Inside the parent submodule you include an export of `Downloaded` scoped to `Parent`:
scoped(Parent) export Downloaded
This export statement means that only `Parent` and its descendants are able to see `Downloaded`.
Inside the files in `Child1` and `Child2` you just say `import Downloaded` to import the symbols from the `Downloaded` submodule.
By default both `Child1` and `Child2` will be available for import everywhere in the module (modulo circular dependency and descendent restrictions).
A couple of caveats: you will not be able to see `internal` symbols declared in the file. Those will be scoped to `Downloaded` only. If you need to access `internal` symbols you would have to add a new file of your own in `Downloaded` and wrap those symbols. Second, if the file contains scope references to ancestor submodules you would not be able to use the file as-is because those ancestors would not exist in the context you placed it in your module (unless you want to be evil and couple your module structure to that of a copy-and-paste dependency).
> On 24.02.2017 22:34, Matthew Johnson via swift-evolution wrote:
>> I didn't expect submodules to be a part of the Swift 4 discussion. When it
>> came up I was pleasantly surprised. I have been thinking about the design
>> of a submodule system for quite a while but was planning to wait until it
>> was clearly in scope to draft a proposal. Now that the topic has been
>> introduced I decide to write down the design I've been thinking about,
>> along with the motivation and goals that underly it. I understand
>> submodules may not be in scope for Swift 4 but wanted to contribute this
>> design while the discussion is fresh in everyone's mind.
>> I am including the contents of the proposal below. You can also find it on
>> Github: https://github.com/anandabits/swift-evolution/blob/scope-based-submodules/proposals/NNNN-scope-based-submodules.md
>> I am very much looking forward to everyone's feedback!
More information about the swift-evolution