<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>1. One major reason for wanting control over which targets are exported are so packages can control which parts of their API is supported for external use. This is very important to large projects undergoing active development while also trying to support a well-defined, semantically versioned API.</div><div><br></div><div>2. In keeping with #1, and the design of the Swift language, I think the right default is for a module to be private/unexported. This is basically for the same reasons as `internal` is the default access control modifier in Swift. This also relates to the discussion below.</div></div></blockquote><div><br></div><div>I agree keeping things unexported/internal will make sure a certain module is not being used as a dependency when it shouldn&#39;t. I also think the default behaviour of a dependency package being exposed to every target should be discontinued with this proposal and each target which wants to use a certain external dependency should require explicit declaration. This will make the manifest file clearer as to which target exactly depends on what.</div><div>However it might break all currently packages (which is probably okay) but it might also get confusing for beginners that why their package is not compiling after declaring the external package. We can probably provide a useful warning when an external package is declared but there is no reference of it in any of the targets.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>3. If we are going to add this via a new Target attribute, I suggest we do so using a `flags` parameter and accompanying enumeration. This will be equally readable, I think, but more extensible over time. </div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>4. Technically, this proposal is defining two new few features, the public/private exported/imported part and the ability for packages to depend on specific targets. They are related problems, but the proposals (and implementation) are otherwise somewhat orthogonal. I&#39;m fine combining them into one proposal, but if it appears that one part is going to require much more design or discussion than the other (or that the combined discussion is too large) we might consider breaking them up.</div><div><br></div></div></blockquote><div><br></div><div>I agree.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>There is a larger thing we need to consider with regard to the public/private part of the proposal, and that is its relation to hypothetical future support for package-level namespaces, whereby I mean Swift language support for a new level of namespace (and accompanying access control support in some form) for an entire Package. There are several reasons I think that we will ultimately need such a thing, the most major of which is the module-name collision problem (two packages that want to use a shared common name for a module) that cannot be resolved by SwiftPM without language support. Since such a feature is purely hypothetical at this point, I don&#39;t think we need to block forward progress in SwiftPM on it, but I do think we should discuss the consequences.</div><div><br></div><div>Some examples of how these things might be related:</div><div><br></div><div>1. The choice of `public/private` is probably wrong when viewed as a language feature, since they already having existing meanings and `internal` would be a more accurate name within the context of an individual Package. I think we should include some discussion of the best names if we reuse modifier names, or if there is a good argument for finding alternate names (&quot;exported/unexported&quot;?).</div></div></blockquote><div><br></div><div>if things are going to be private/internal/unexported by default, I think we only need to define the public/exported name. Exported seems like the correct name for this behaviour and is well known however I think public is also equally clear (and simple) here.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>2. Suppose Swift added support for a `package` namespace and access control modifier. This might make it somewhat awkward if we had tied expectations of what targets in an external dependency were built to a *manifest*-level construct.</div></div></blockquote><div><br></div><div>If such a feature is added to swift it would probably require to rethink the manifest file but I agree we should try to minimize the damage if possible.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>3. We should call out that public/private in this sense ultimately won&#39;t have any enforcement by the compiler. If a public target exposes a type declared in a private module implicitly (say via a return value), there won&#39;t be any error, even though it breaks the encapsulation this feature would partially be intended to provide. Similarly, nothing will prevent a target from importing a private module from an external dependency if was already a transitive dependency of some other public target.</div></div></blockquote><div><br></div><div>In the current draft proposal I mentioned private target&#39;s dependency can only be another private target for the same reason but I think the approach of having dependencies providing one (or more) well maintained exported target makes more sense. True as of now we cannot enforce this and modules can and will leak out. Maybe we can implement some form of enforcer or checker using SourceKit in future.</div><div> </div></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Ankit<br><br></div>
</div></div>