Right list?

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

···

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

Consider the case where Erica has packages SwiftString, HTMLString,
PGString, IBMString… These modules all have somewhat different dependencies
— so you would not necessarily want to download and build all of them — but
they do form a coherent whole under EricaString. Would this proposal allow
for names like EricaString.Swift, EricaString.HTML and EricaString.IBM?

···

On Mon, 29 Feb 2016 at 10:43 Erica Sadun via swift-build-dev < swift-build-dev@swift.org> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com> > wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com> wrote:

I'll try writing up a proposal. Does everything work the same for
swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

   - Proposal: TBD
   - Author(s): Erica Sadun <http://github.com/erica&gt;
   - Status: TBD
   - Review manager: TBD

<namespacing.md · GitHub;
Introduction

I propose to modify Swift's SPM PackageDescription to allow developers to
assign local module names to avoid module conflicts. Namespacing supports a
decentralized packaging ecosystem that handles the rare case of name
overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in
the "Right List?
<http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.
<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts.
When working with NSView, I take care to differentiate Swift.print, which
outputs text to the console or stream from NSView's print, which creates
a print job. Swift does not yet offer a solution for conflicting module
names.

Like many other Swift developers, I have spent considerable time building
utility packages. Mine use obvious names like SwiftString and
SwiftCollections. Simple clear naming is a hallmark of Swift design. At
the same time, this style introduces the possibility of package name
conflicts.

import SwiftString // mineimport SwiftString // someone else's. oops.

My SwiftString or StringUtility package can't be used alongside someone
else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style
ESSwiftString namespacing feels ugly and antithetical to Swift design.
Swift should encourage recognizable, easy-to-understand module names.
<namespacing.md · GitHub
Design

I first considered namespacing using reverse domain naming in Package
declarations. This offers a traditional approach to identify a module's
source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)

Reverse domain names

   - are relatively short
   - are already well established for Apple app distribution
   - do not rely on a web address that may change should the repo move
   - are less likely to conflict with user names across repo hosts

However concise, using reverse domain names bring unnecessary verbiage to
name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)

In this example, org.sadun.SwiftString.countSyllables places a burden
both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)

   1. This approach requires Swift language modification
   2. Import redeclarations may be required across multiple files

Joe Groff suggested a simpler approach: allow package manifests to take
responsibility for mapping dependencies to source-level module names.
<namespacing.md · GitHub
Design

Under the revised solution, renaming occurs when declaring dependencies.
This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)

Under this proposal, the Package dependency gains an optional localName parameter.
When localName is omitted, a package imports as the name declared in
Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)

<namespacing.md · GitHub
Considered

Swift names should be as simple and elegant as possible without
overlapping with built-in keywords. Other suggestions brought up
in-discussion included:

   - Using GitHub or Bitbucket usernames as namespacing prefixes, e.g.
   erica.SwiftString. This would not be resilient across cross-repo username
   conflicts.
   - Using repo URLs to resolve namespacing conflicts. This would be
   fragile if repos moved and does not address local module name resolution.
   - Introducing a registration index for packages.

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

This looks like a great user model. There's an implementation question, however, about what the "ABI" name of a package's module ought to be. Right now, we mangle the module name into all of the symbols exported by that module's library, which would be problematic under this scheme. If you have a dependency diamond where two modules both transitively require the same version of the same third module, but with different names:

// module A
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "SadunString")
]
// module B
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "EricaString")
]

then we would want to build and link one libSwiftString.1.dylib (or .a) for both. Using the "home" module name is potentially problematic on systems with flat dynamic linker namespaces (everything except Darwin, AFAIK), since even though we've avoided a source-level clash between competing SwiftStrings, we could still have ABI-level symbol collisions.

-Joe

···

On Feb 29, 2016, at 10:42 AM, Erica Sadun <erica@ericasadun.com> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

Thanks for writing this up!

One problem with this proposal as it stands is that it conflates the package name with the module name. The package can contain multiple modules, so "importAs" on the package is ambiguous except for single module packages (and even then, it is weird, because it is naming a module, but in the context where the package is being named).

We eventually need a way for packages to specify what modules they actually export, at which point it would probably be possible to specify this as a rename of the exported module names.

To make this a concrete proposal, I think it would also need to clarify exactly how we would implement the feature. The most straightforward way that I can see would require either SwiftPM specific hacks (which I wouldn't want to see go in), or some level of compiler support. We already need more compiler support for module specification stuff (e.g., to enforce dependencies), so it is possible it could tack on to what we need there, but none of that work has been designed yet.

These two issues bring up a related problem:
- We have packages, and we have modules, and both have names.
- Substantial packages may be composed of a significant number of modules, only some of which are exported. For example, "LLVM" could be a package which exported an "LLVM" module (the client API), but internally had things like "Support".
- The collision likelihood for package-internal module names is quite a bit higher than for packages (because there are likely to be more of them, and because they are implementation details).

One possible direction to take this is that we should gain explicit Swift language support for the concept of package namespaces. It could take the same form as imports, where the package component of the namespace is only required when there are ambiguities.

If we had such a feature, then a package-level rename would probably make complete sense (retaining your current proposal), and we would probably be able to implement it in the package manager (for the most part; I still see problems if a package tree had multiple sources which referred by name to the package being renamed).

- Daniel

···

On Feb 29, 2016, at 10:42 AM, Erica Sadun <erica@ericasadun.com> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

Consider the case where Erica has packages SwiftString, HTMLString, PGString, IBMString… These modules all have somewhat different dependencies — so you would not necessarily want to download and build all of them — but they do form a coherent whole under EricaString. Would this proposal allow for names like EricaString.Swift, EricaString.HTML and EricaString.IBM

In the current system a package can contain multiple modules. But a module cannot have submodules.

So you can have EricaSwiftString and EricaHTMLString modules or you could have a module called Erica that contained classes or structs called SwiftString and HTMLString, and thus you would (well, *could*) refer to them as Erica.SwiftString and Erica.HTMLString.

Your suggestion is perhaps similar to clang submodules (which Swift does not support afaik) coupled with a new capability in Package.swift to allow a user to declare that certain modules/submodules in certain packages should not be built.

Both things could be done. Though I don’t think it should be put in this particular namespacing proposal.

It is my intent that wherever a module name is established, this allows an override of that name at the consuming end and no more. All other behavior would exist as-is, and any dependency trees would adopt the default name or an override name at the time the dependency is declared.

-- Erica

···

On Feb 29, 2016, at 12:33 PM, Jason Dusek <jason.dusek@gmail.com> wrote:

Consider the case where Erica has packages SwiftString, HTMLString, PGString, IBMString… These modules all have somewhat different dependencies — so you would not necessarily want to download and build all of them — but they do form a coherent whole under EricaString. Would this proposal allow for names like EricaString.Swift, EricaString.HTML and EricaString.IBM?

On Mon, 29 Feb 2016 at 10:43 Erica Sadun via swift-build-dev <swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-build-dev

Does that allow us to refer to the names of modules qualified by their
package name? It seems weird to not have hierarchical names for
packages/modules (though I recognize these are not really the same thing,
many languages/systems conflate the package namespace with the module
namespace).

···

On Mon, 29 Feb 2016 at 11:55 Max Howell <max.howell@apple.com> wrote:

Consider the case where Erica has packages SwiftString, HTMLString,
PGString, IBMString… These modules all have somewhat different dependencies
— so you would not necessarily want to download and build all of them — but
they do form a coherent whole under EricaString. Would this proposal allow
for names like EricaString.Swift, EricaString.HTML and EricaString.IBM

In the current system a package can contain multiple modules. But a module
cannot have submodules.

This looks good but I have 1 concern
With this functionality the users of a package can change the package name given by author, to own custom.

Example:
let package = Package(
  name: “MyApp”
  dependencies: [
      .Package(url: "https://github.com/Alamofire/Alamofire&quot;, localName: “Network")
  ]
)

//App.Swift
import Network

When reading this code it’s not clear that Network is just name alias for Alamofire without looking at Manifest.swift file.

···

On 01 Mar 2016, at 21:44, Joe Groff via swift-build-dev <swift-build-dev@swift.org> wrote:

This looks like a great user model. There's an implementation question, however, about what the "ABI" name of a package's module ought to be. Right now, we mangle the module name into all of the symbols exported by that module's library, which would be problematic under this scheme. If you have a dependency diamond where two modules both transitively require the same version of the same third module, but with different names:

// module A
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "SadunString")
]
// module B
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "EricaString")
]

then we would want to build and link one libSwiftString.1.dylib (or .a) for both. Using the "home" module name is potentially problematic on systems with flat dynamic linker namespaces (everything except Darwin, AFAIK), since even though we've avoided a source-level clash between competing SwiftStrings, we could still have ABI-level symbol collisions.

-Joe

On Feb 29, 2016, at 10:42 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

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

Thanks for writing this up!

No worries. Let's get this fixed. I warn you the following rambles a bit, but there's a point to it by the end.

State of the art:
So I have two git repos: GitHub - erica/SwiftString: Doing stuff with and to Swift strings and GitHub - nudas/SwiftString

My package looks like this:

import PackageDescription
let package = Package (
    name: "myutility",
        dependencies: [
      .Package(url: "https://github.com/erica/SwiftString.git&quot;,
               majorVersion: 1),
      .Package(url: "https://github.com/nudas/SwiftString.git&quot;,
               majorVersion: 1),
        ]

)

and of course, make fails:

% make
swift build
Cloning Packages/SwiftString
Using version 1.0.5 of package SwiftString
Cloning Packages/SwiftString
/usr/bin/git clone --recursive --depth 10 GitHub - nudas/SwiftString /home/erica/Work/test/Packages/SwiftString
fatal: destination path '/home/erica/Work/test/Packages/SwiftString' already exists and is not an empty directory.

swift-build: Failed to clone GitHub - nudas/SwiftString to /home/erica/Work/test/Packages/SwiftString
Makefile:3: recipe for target 'all' failed
make: *** [all] Error 1

This is my starting point, where I am attempting to import two standalone modules, let alone import a package that contains further
dependencies.

* There are packages. There are modules. Both have names. Neither is distinguished in dependencies or declaration.
* Packages may be composed of modules or packages, and keeping track of modules can be problematic.

Tossing ideas out there:

Change 1: Let modules be declared differently. Instead of

import PackageDescription

let package = Package(
    name: "SwiftString",
)

allow:

import ModuleDescription

let module = Module(
    name: "SwiftString",
    origin: "org.sadun.SwiftString"
)

Let's say there's also github/erica/StringUtilities, a package with 2 modules. It could consume the existing Packages and export them as named modules

on github/erica/StringsUtilities
import PackageDescription
let package = Package (
    origin: "com.sadun.StringsUtilities"
    name: "myutility",
    dependencies: [
       // I'm importing everything as a package and assuming something knows eventually
       // these are actually modules
       .Package(url: "https://github.com/erica/SwiftString.git&quot;,
          majorVersion: 1),
       .Package(url: "https://github.com/nudas/SwiftString.git&quot;,
          majorVersion: 1),
       .Package(url: "http://github.com/erica/SomeStringOtherPackage.git&quot;,
                majorVersion: 1), // just throwing some package in there
    ],
)

From the consuming side, you attempt to build with:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
        .Package(url: "https://github.com/erica/StringsUtilities.git&quot;,
           majorVersion: 1),
   ],
)

the build tool places the modules into separate org.sadun.SwiftString and com.foo.SwiftString build paths but still spits out an error:

org.sadun.SwiftString module name ("SwiftString") conflicts with com.foo.SwiftString ("SwiftString").
Cannot build without adding import name overrides.

So you hop back in and edit:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
        .Package(url: "https://github.com/erica/StringsUtilities.git&quot;,
           majorVersion: 1),
    ]
    importMappings: [
       .Map(origin: "org.sadun.SwiftString", toName: "SwiftString"),
       .Map(origin: "com.foo.SwiftString", toName: "SwiftString2"),
    ],
)

And fixed?

-- Erica

···

On Mar 3, 2016, at 1:30 AM, Daniel Dunbar <daniel_dunbar@apple.com> wrote:

One problem with this proposal as it stands is that it conflates the package name with the module name. The package can contain multiple modules, so "importAs" on the package is ambiguous except for single module packages (and even then, it is weird, because it is naming a module, but in the context where the package is being named).

We eventually need a way for packages to specify what modules they actually export, at which point it would probably be possible to specify this as a rename of the exported module names.

To make this a concrete proposal, I think it would also need to clarify exactly how we would implement the feature. The most straightforward way that I can see would require either SwiftPM specific hacks (which I wouldn't want to see go in), or some level of compiler support. We already need more compiler support for module specification stuff (e.g., to enforce dependencies), so it is possible it could tack on to what we need there, but none of that work has been designed yet.

These two issues bring up a related problem:
- We have packages, and we have modules, and both have names.
- Substantial packages may be composed of a significant number of modules, only some of which are exported. For example, "LLVM" could be a package which exported an "LLVM" module (the client API), but internally had things like "Support".
- The collision likelihood for package-internal module names is quite a bit higher than for packages (because there are likely to be more of them, and because they are implementation details).

One possible direction to take this is that we should gain explicit Swift language support for the concept of package namespaces. It could take the same form as imports, where the package component of the namespace is only required when there are ambiguities.

If we had such a feature, then a package-level rename would probably make complete sense (retaining your current proposal), and we would probably be able to implement it in the package manager (for the most part; I still see problems if a package tree had multiple sources which referred by name to the package being renamed).

- Daniel

Consider the case where Erica has packages SwiftString, HTMLString, PGString, IBMString… These modules all have somewhat different dependencies — so you would not necessarily want to download and build all of them — but they do form a coherent whole under EricaString. Would this proposal allow for names like EricaString.Swift, EricaString.HTML and EricaString.IBM

In the current system a package can contain multiple modules. But a module cannot have submodules.

Does that allow us to refer to the names of modules qualified by their package name? It seems weird to not have hierarchical names for packages/modules (though I recognize these are not really the same thing, many languages/systems conflate the package namespace with the module namespace).

The current system does not allow Package name to be used as a namespace, unless it is a package of one module and that module uses the same name as the Package.

Not that I’m saying this wouldn’t be a good thing.

The proposal looks great. This would be easy to use and could be handy
someday!

···

On Tue, Mar 1, 2016 at 1:28 AM, Jason Dusek via swift-build-dev < swift-build-dev@swift.org> wrote:

On Mon, 29 Feb 2016 at 11:55 Max Howell <max.howell@apple.com> wrote:

Consider the case where Erica has packages SwiftString, HTMLString,
PGString, IBMString… These modules all have somewhat different dependencies
— so you would not necessarily want to download and build all of them — but
they do form a coherent whole under EricaString. Would this proposal allow
for names like EricaString.Swift, EricaString.HTML and EricaString.IBM

In the current system a package can contain multiple modules. But a
module cannot have submodules.

Does that allow us to refer to the names of modules qualified by their
package name? It seems weird to not have hierarchical names for
packages/modules (though I recognize these are not really the same thing,
many languages/systems conflate the package namespace with the module
namespace).

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

--
Ankit

Practical answer: module collision is expected to be a very rare event. Even the need to differentiate NSView.print and Swift.print almost never happens.

Philosophical answer: It is not the role of a language or package manager to interfere with a developer's ability to make bad naming choices.

With regard to your example: I think it's unlikely that anyone would use more than one Alamofire implementation, and if they do, they have control over what name that is given, whether it is Alamofire_1, Alamofire_Network, Network, etc. Renaming is not going to be a common or recommended event.

I'd even go as far as to recommend that the SPManager warn when names are given to packages where there is not a collision.

-- E

···

On Mar 2, 2016, at 9:09 AM, Kostiantyn Koval <konstantin.koval1@gmail.com> wrote:

This looks good but I have 1 concern
With this functionality the users of a package can change the package name given by author, to own custom.

Example:
let package = Package(
  name: “MyApp”
  dependencies: [
      .Package(url: "https://github.com/Alamofire/Alamofire&quot;, localName: “Network")
  ]
)

//App.Swift
import Network

When reading this code it’s not clear that Network is just name alias for Alamofire without looking at Manifest.swift file.

Also, how would this deal with transitive dependencies?

E.g. for the example below, if you included a library that had AFNetworking as a dependency, which would expect it to use the official name inside itself. Would it be able to access the original un-namespaced version of the library which would be separate from the top level namespace’d version?

···

--

[ ·/ ] Orta Therox

w/ Artsy <http://artsy.net/&gt;
CocoaPods <http://cocoapods.org/&gt; / CocoaDocs <gt3captcha-ios-xcframework - CocoaDocs.org; / GIFs.app <https://itunes.apple.com/us/app/gifs/id961850017?l=en&mt=12&gt;@orta <http://twitter.com/orta&gt; / orta.github.com <http://orta.github.com/&gt;
On Mar 2, 2016, at 11:09 AM, Kostiantyn Koval via swift-build-dev <swift-build-dev@swift.org> wrote:

This looks good but I have 1 concern
With this functionality the users of a package can change the package name given by author, to own custom.

Example:
let package = Package(
  name: “MyApp”
  dependencies: [
      .Package(url: "https://github.com/Alamofire/Alamofire&quot;, localName: “Network")
  ]
)

//App.Swift
import Network

When reading this code it’s not clear that Network is just name alias for Alamofire without looking at Manifest.swift file.

On 01 Mar 2016, at 21:44, Joe Groff via swift-build-dev <swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>> wrote:

This looks like a great user model. There's an implementation question, however, about what the "ABI" name of a package's module ought to be. Right now, we mangle the module name into all of the symbols exported by that module's library, which would be problematic under this scheme. If you have a dependency diamond where two modules both transitively require the same version of the same third module, but with different names:

// module A
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "SadunString")
]
// module B
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "EricaString")
]

then we would want to build and link one libSwiftString.1.dylib (or .a) for both. Using the "home" module name is potentially problematic on systems with flat dynamic linker namespaces (everything except Darwin, AFAIK), since even though we've avoided a source-level clash between competing SwiftStrings, we could still have ABI-level symbol collisions.

-Joe

On Feb 29, 2016, at 10:42 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-build-dev

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

The law of Demeter would seem to argue against modules exposing submodules;
or against packages exposing sub-packages. But I am not sure which.

···

On Mon, 29 Feb 2016 at 14:08, Max Howell <max.howell@apple.com> wrote:

Consider the case where Erica has packages SwiftString, HTMLString,

PGString, IBMString… These modules all have somewhat different dependencies
— so you would not necessarily want to download and build all of them — but
they do form a coherent whole under EricaString. Would this proposal allow
for names like EricaString.Swift, EricaString.HTML and EricaString.IBM

In the current system a package can contain multiple modules. But a
module cannot have submodules.

Does that allow us to refer to the names of modules qualified by their
package name? It seems weird to not have hierarchical names for
packages/modules (though I recognize these are not really the same thing,
many languages/systems conflate the package namespace with the module
namespace).

The current system does not allow Package name to be used as a namespace,
unless it is a package of one module and that module uses the same name as
the Package.

Not that I’m saying this wouldn’t be a good thing.

My feeling here is the module name for an import can be different per module. This requires compiler support.

This package A imports B as C and package D imports B as E but C and E are both still B. The build artifacts are separately named.

···

On Mar 2, 2016, at 8:26 AM, orta therox via swift-build-dev <swift-build-dev@swift.org> wrote:

Also, how would this deal with transitive dependencies?

E.g. for the example below, if you included a library that had AFNetworking as a dependency, which would expect it to use the official name inside itself. Would it be able to access the original un-namespaced version of the library which would be separate from the top level namespace’d version?

--

[ ·/ ] Orta Therox

w/ Artsy
CocoaPods / CocoaDocs / GIFs.app
@orta / orta.github.com

On Mar 2, 2016, at 11:09 AM, Kostiantyn Koval via swift-build-dev <swift-build-dev@swift.org> wrote:

This looks good but I have 1 concern
With this functionality the users of a package can change the package name given by author, to own custom.

Example:
let package = Package(
  name: “MyApp”
  dependencies: [
      .Package(url: "https://github.com/Alamofire/Alamofire&quot;, localName: “Network")
  ]
)

//App.Swift
import Network

When reading this code it’s not clear that Network is just name alias for Alamofire without looking at Manifest.swift file.

On 01 Mar 2016, at 21:44, Joe Groff via swift-build-dev <swift-build-dev@swift.org> wrote:

This looks like a great user model. There's an implementation question, however, about what the "ABI" name of a package's module ought to be. Right now, we mangle the module name into all of the symbols exported by that module's library, which would be problematic under this scheme. If you have a dependency diamond where two modules both transitively require the same version of the same third module, but with different names:

// module A
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "SadunString")
]
// module B
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "EricaString")
]

then we would want to build and link one libSwiftString.1.dylib (or .a) for both. Using the "home" module name is potentially problematic on systems with flat dynamic linker namespaces (everything except Darwin, AFAIK), since even though we've avoided a source-level clash between competing SwiftStrings, we could still have ABI-level symbol collisions.

-Joe

On Feb 29, 2016, at 10:42 AM, Erica Sadun <erica@ericasadun.com> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts
Proposal: TBD
Author(s): Erica Sadun
Status: TBD
Review manager: TBD
Introduction

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List?" thread.

Motivation

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

Original Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

Revised Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
Alternatives Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

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

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

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

Problem 1: Module names can conflict.
Solution: uniquely namespace the origins of modules at the point of origin

Problem 2: Namespaced modules are unwieldy.
Solution: Update the language to support import namespaced as local name

Problem 3: There are packages. There are modules. Both have names. Neither is distinguished in dependencies or declaration.
Solution: Create a way to mark modules as distinct from packages and require a origin identifier plus a name

Will that do it?

-- E

···

On Mar 3, 2016, at 12:37 PM, Max Howell via swift-build-dev <swift-build-dev@swift.org> wrote:

My feeling here is the module name for an import can be different per module. This requires compiler support.

This package A imports B as C and package D imports B as E but C and E are both still B. The build artifacts are separately named.

On Mar 2, 2016, at 8:26 AM, orta therox via swift-build-dev <swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>> wrote:

Also, how would this deal with transitive dependencies?

E.g. for the example below, if you included a library that had AFNetworking as a dependency, which would expect it to use the official name inside itself. Would it be able to access the original un-namespaced version of the library which would be separate from the top level namespace’d version?

--

[ ·/ ] Orta Therox

w/ Artsy <http://artsy.net/&gt;
CocoaPods <http://cocoapods.org/&gt; / CocoaDocs <gt3captcha-ios-xcframework - CocoaDocs.org; / GIFs.app <https://itunes.apple.com/us/app/gifs/id961850017?l=en&mt=12&gt;@orta <http://twitter.com/orta&gt; / orta.github.com <http://orta.github.com/&gt;
On Mar 2, 2016, at 11:09 AM, Kostiantyn Koval via swift-build-dev <swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>> wrote:

This looks good but I have 1 concern
With this functionality the users of a package can change the package name given by author, to own custom.

Example:
let package = Package(
  name: “MyApp”
  dependencies: [
      .Package(url: "https://github.com/Alamofire/Alamofire&quot;, localName: “Network")
  ]
)

//App.Swift
import Network

When reading this code it’s not clear that Network is just name alias for Alamofire without looking at Manifest.swift file.

On 01 Mar 2016, at 21:44, Joe Groff via swift-build-dev <swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>> wrote:

This looks like a great user model. There's an implementation question, however, about what the "ABI" name of a package's module ought to be. Right now, we mangle the module name into all of the symbols exported by that module's library, which would be problematic under this scheme. If you have a dependency diamond where two modules both transitively require the same version of the same third module, but with different names:

// module A
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "SadunString")
]
// module B
dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;, majorVersion: 1, localName: "EricaString")
]

then we would want to build and link one libSwiftString.1.dylib (or .a) for both. Using the "home" module name is potentially problematic on systems with flat dynamic linker namespaces (everything except Darwin, AFAIK), since even though we've avoided a source-level clash between competing SwiftStrings, we could still have ABI-level symbol collisions.

-Joe

On Feb 29, 2016, at 10:42 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar@apple.com <mailto:daniel_dunbar@apple.com>> wrote:

Yup!

- Daniel

On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?

-- E

First draft: namespacing.md · GitHub

Looking forward to feedback, questions, and corrections. -- E

Disambiguating SPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<namespacing.md · GitHub

I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles the rare case of name overlaps without requiring a central package registry.

This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149&gt;&quot; thread.

<namespacing.md · GitHub

Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's print, which creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and SwiftCollections. Simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.

import SwiftString // mine
import SwiftString // someone else's. oops.
My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.

<namespacing.md · GitHub Design

I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:

import PackageDescription

let package = Package(
    name: "SwiftString"
    origin: "org.sadun"
)
Reverse domain names

are relatively short
are already well established for Apple app distribution
do not rely on a web address that may change should the repo move
are less likely to conflict with user names across repo hosts
However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.

import org.sadun.SwiftString
import com.other.SwiftString

...

// Use my implementation of countSyllables
let count = org.sadun.SwiftString.countSyllables(myString)
In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.

Adapting import statements resolves symbols but has negative side effects:

import org.sadun.SwiftString as SadunString
import com.other.SwiftString as OtherString

...

// Use my implementation of countSyllables
let count = SadunString.countSyllables(myString)
This approach requires Swift language modification
Import redeclarations may be required across multiple files
Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.

<namespacing.md · GitHub Design

Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1),
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1),
    ]
)
Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
    .Package(url: "https://github.com/erica/SwiftString.git&quot;,
                 majorVersion: 1, localName: "SadunString"), // import SadunString
    .Package(url: "https://github.com/bob/SwiftString.git&quot;,
                 majorVersion: 1, localName: "BobString"), // import BobString
    .Package(url: https://github.com/erica/SwiftCollections.git&quot;,
                 majorVersion: 1), // import SwiftCollections
    ]
)
<namespacing.md · GitHub Considered

Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:

Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
Introducing a registration index for packages.

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-build-dev

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-build-dev

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-build-dev

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