> On Mar 1, 2017, at 11:56 AM, David Hart <da...@hartbit.com> wrote:
> 
>> 2. Normally, references within the module to submodule symbols need to be 
>> prefixed with the submodule name. (That is, in top-level `Foo` code, you 
>> need to write `Bar.Baz` to access `Foo.Bar.Baz`). As a convenience, you can 
>> import a submodule, which makes the submodule's symbols available to that 
>> file as though they were top-level module symbols.
>> 
>> 3. When you import a submodule, you can mark it with `@exported`; this 
>> indicates that the symbols in that submodule should be aliased and, if 
>> `public` or `open`, re-exported to other modules.
> 
> Could you explain this in more detail?

Let's say you're writing the `WorldOptimization` module, and you have a 
`SpimsterWicket` submodule with a public `WicketShell` type. In the main 
`WorldOptimization` module, you could write:

        class Optimizer: Person {
                var wicketShell: SpimsterWicket.WicketShell?
                …
        }

But if you don't want to write out the name of the `SpimsterWicket` submodule, 
you could import it:

        import WorldOptimization.SpimsterWicket
        
        class Optimizer: Person {
                var wicketShell: WicketShell?
                …
        }

Outside the `WorldOptimization` module, of course, you'd still need to write 
`import WorldOptimization.SpimsterWicket` to get access to the `WicketShell` 
type. (Or perhaps importing `WorldOptimization` would allow you to access it as 
`SpimsterWicket.WicketShell`--it's an open question.) On the other hand, if 
`WorldOptimization` instead included:

        @exported import WorldOptimization.SpimsterWicket
        
        class Optimizer: Person {
                var wicketShell: WicketShell?
                …
        }

Then anyone who imported `WorldOptimization` could access `WicketShell` 
directly, as though they too had explicitly imported 
`WorldOptimization.SpimsterWicket`.

>> I think we need to go back to first principles here. The reason to introduce 
>> a new access level is that we believe that a submodule is a large enough 
>> unit of code that it will simultaneously need to encapsulate some of its 
>> implementation details from other submodules, *and* have some of its own 
>> implementation details encapsulated from the rest of the submodule.
> 
> That's where I disagree. Why would Swift need that level of differentiation 
> and not C# or Java, which have had packages and namespaces without it.

C# has friend assemblies 
<https://msdn.microsoft.com/en-us/library/0tke9fxk(v=vs.100).aspx>, 
PublisherIdentityPermission 
<http://stackoverflow.com/questions/13697390/restricting-the-use-of-an-assembly-from-assemblies-that-are-not-signed>,
 and similar security mechanisms to restrict access to certain APIs. I have not 
been able to locate similar features in Java; instead, people seem to recommend 
circuitous design patterns to make up for it: 
<http://wiki.apidesign.org/wiki/APIDesignPatterns:FriendPackages>

More broadly, though? Swift is trying to reach to lower levels than C# or 
(particularly) Java usually do. If we're serious about Swift as a systems 
language, and we're also serious about the kind of careful layering that 
Apple's OSes are known for, we need some way to expose SPIs to higher layers. 
And it'd be good if that were built into the language.

-- 
Brent Royal-Gordon
Architechies

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

Reply via email to