[swift-evolution] [Discussion] Namespaces

L Mihalkovic laurent.mihalkovic at gmail.com
Fri May 20 15:49:43 CDT 2016


> On May 20, 2016, at 10:30 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> 
>> On May 20, 2016, at 2:48 PM, Leonardo Pessoa <me at lmpessoa.com <mailto:me at lmpessoa.com>> wrote:
>> 
>> We've been discussing some thing like this on another thread about
>> protocols and this looks like a great solution to the problem
>> expressed there with a very simple change in syntax (and no new
>> keyword involved). I'd like to see this turned into a separate
>> proposal (since I'm new on the group and lack the experience, I'm not
>> the most suitable person to write).
>> 
>> I agree with others that we can nowadays subvert the purpose of an
>> existing construct of the language to simulate a namespace and I
>> believe most people here agree that's not the best way to work but
>> that's what we have now. I think that's why we're here discussing the
>> idea of namespaces (or submodules, could someone disambiguate them,
>> please?).
> 
> The big difference is one of encapsulation.
> 
> Namespaces encapsulate names to avoid naming conflicts.  It is common for them to be open to extension across modules, similar to how types in Swift are open to extension across module boundaries.  Empty enums approximate this aspect of namespaces very well.  One thing they do not (currently) support is the ability to import names from a namespace into a lexical scope so they may used directly, without the namespace prefix.  Here’s a hypothetical  example where that limitation is removed:
> 
> enum Foo { // alternatively: namespace Foo
>     static func bar() -> String {}
>     struct S {}
> }
> 
> elsewhere:
> 
> import Foo
> 
> let s = S() // creates an instance of Foo.S which has been imported into the lexical context
> let b = bar() // calls Foo.bar which has been imported into the lexical context
> 
> I think it would be interesting to consider allowing the top-level / static names of a type to be imported into a lexical context whether we have namespaces or not.
> 
> One minor difference between an empty enum and a namespace is that you can define instance methods for an empty enum even though you can’t actually instantiate an empty enum (one could argue that this should not be allowed).
> 
> The duplicate definition issue Tony mentioned is probably the most significant difference between an empty enum and a namespace.  Related to this is the need to use `extension Foo` syntax everywhere except the initial introduction of `enum Foo`.  The ability to use `namespace Foo` everywhere and not worry about duplicate definition is the most important reason why empty enums do not suffice as a substitute for namespaces.
> 
> Submodules are different in that they are first class modules in every respect, they just happen to be compiled as a part of their containing module.  They provide more encapsulation, but because of that they *are not* open to extension in the way that namespaces can be (depending on the design of the namespace feature).
> 
> The big question in my mind is whether we really need a namespace mechanism that is open to extension across module boundaries.  There is a good reason types are open to extension across module boundaries: it allows you to retroactively conform them to protocols, introduce additional methods, etc.  These reasons do not apply to namespaces.  
> 
> If there isn’t a compelling argument that we need such a mechanism submodules will prove to be a better solution.  I believe this will be the right answer for Swift, but am certainly willing to listen to counter-arguments.
> 


import Quartz.PDFKit
import Quartz.ImageKit

Quarts is one of these russian doll modules/submodule structure.

versioning part:

modX.framework
   modX.dylib
   Frameworks/
     modXsub1.framework
        modXsub1.dylib
     modXsub2.framework
        modXsub2.dylib



> If there is a compelling argument for open namespaces then the question becomes whether the benefit is sufficient to support them either *instead of* or *in addition to* submodules.  
> 
> -Matthew
> 
> 
>> 
>> 
>> On 20 May 2016 at 12:45, Matthew Johnson via swift-evolution
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> On May 20, 2016, at 10:21 AM, Austin Zheng via swift-evolution
>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> I think namespaces are definitely worth exploring.
>>> 
>>> Here's something that might be interesting to research. Right now, you can
>>> have two protocols that have associated types with the same name. If you
>>> adopt both protocols, you have to make the associated types the same, even
>>> if they really don't have anything to do with each other. I think this might
>>> be a good argument for how namespaces can make your code more expressive:
>>> 
>>> protocol A {
>>>  associatedtype Thing
>>>  func foo(x: Thing)
>>> }
>>> 
>>> protocol B {
>>>  associatedtype Thing
>>>  func bar(x: Thing)
>>> }
>>> 
>>> struct Foo : A, B {
>>>  func foo(x: Int) { }
>>>  // Error: type 'Foo' does not conform to protocol 'B'
>>>  // protocol requires function 'bar' with type 'Thing'
>>>  func bar(x: String) { }
>>> }
>>> 
>>> In this example, I want to use "Int" for A's Thing type, and "String" for
>>> B's Thing type, but I can’t.
>>> 
>>> 
>>> This is totally orthogonal to namespaces.  C# provides a mechanism to
>>> clarify implementation of multiple interfaces with the same requirements and
>>> it has nothing to do with C# namespaces.  For example, it might be possible
>>> to just prefix member declarations with the name of the protocol.  These
>>> implementations would not be visible via the primary type interface.
>>> 
>>> struct Foo : A, B {
>>>  typealias A.Thing = Int
>>>  typealias B.Thing = Bar
>>>  func foo(x: Int) { }
>>>  func bar(x: String) { }
>>> }
>>> 
>>> We could also allow you to omit the protocol-specific declaration for one of
>>> the conflicting protocols if you wanted that to be visible through the
>>> interface of your concrete type.
>>> 
>>> struct Foo : A, B {
>>>  typealias A.Thing = Int
>>>  func foo(x: Int) { }
>>>  func bar(x: String) { }
>>> }
>>> 
>>> The same mechanism could work for any members (properties, methods, etc).
>>> In this case, `foo` is scoped specifically to the implementation of `A` even
>>> though it is not resolving any ambiguity.  It is not visible via the
>>> interface of the concrete type `Foo`.
>>> 
>>> struct Foo : A, B {
>>>  typealias A.Thing = Int
>>>  func A.foo(x: Int) { }
>>>  func bar(x: String) { }
>>> }
>>> 
>>> 
>>> Best,
>>> Austin
>>> 
>>> 
>>> On May 20, 2016, at 5:16 AM, Adrian Zubarev via swift-evolution
>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> I want to revive this topic.
>>> 
>>> Is there any technical reason why we can’t have namespaces in Swift? I’ve
>>> found just a few threads about namespaces, but most of them had arguments to
>>> use modules instead.
>>> 
>>> I’m fine with modules but they just don’t serve everything I would want to.
>>> I can’t enforce the developer to use the modules name if there is no naming
>>> conflict.
>>> 
>>> I asked in the SwiftPM mail list for a easier Xcode integration of modules,
>>> but the response is exactly the opposite for using modules for namespaces
>>> (read below).
>>> 
>>> If I’m building one huge project I don’t want to build a lot of different
>>> modules just shiny namespaces and clean code.
>>> 
>>> So I ask the community again why can’t we have optional namespaces?
>>> --
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> Am 19. Mai 2016 bei 22:33:19, Daniel Dunbar (daniel_dunbar at apple.com <mailto:daniel_dunbar at apple.com>)
>>> schrieb:
>>> 
>>> Right now modules are most appropriately used at the same granularity that
>>> frameworks or shared libraries would be used in C/Obj-C/C++. This is the
>>> situation for which the variety of access control modifiers in Swift and
>>> things like Whole Module Optimization were designed for. While there are a
>>> lot of reasons to like modules as a way to provide namespaces, they really
>>> haven't been designed to provide these very fine grained namespaces.
>>> 
>>> My guess is that the right answer here doesn't really involve the Xcode
>>> integration, but rather figuring out the right way that these concepts fit
>>> into the language in a first class way. I would expect concepts like
>>> submodules or namespaces to be language concepts that Xcode just exposes,
>>> not something that was coupled together.
>>> 
>>> - Daniel
>>> 
>>> On May 18, 2016, at 12:37 PM, Adrian Zubarev via swift-build-dev
>>> <swift-build-dev at swift.org <mailto:swift-build-dev at swift.org>> wrote:
>>> 
>>> I’d like to discuss an idea that will make development in Xcode easier. I
>>> assume that SwiftPM will see its Xcode integration when the final version
>>> will be released.
>>> 
>>> Problem I’ll try to describe is mostly about namespaces. Right now some
>>> people abuses enums, struct or classes to create a namespace for a specific
>>> need.
>>> 
>>> class Reference {
>>>    class String { … }
>>>    class Character {
>>>        enum Error { … }
>>>    }
>>> 
>>>    private init() {}
>>> }
>>> 
>>> This will create a pseudo namespace for the nested types:
>>> 
>>> * Reference.String
>>> * Reference.Character
>>> * Reference.Character.Error
>>> 
>>> One could argue of using modules instead of abusing a class here, which is a
>>> great argument.
>>> 
>>> The problem that comes to my mind here is that we will have to create
>>> subprojects inside our main project file and using the references to them
>>> just to achieve that shiny namespace.
>>> One could also use SwiftPM, which is awesome, but there is a need to
>>> re-build the module if any changes have been done. As soon as we’ll create
>>> some complex dependencies between different modules this will get messy.
>>> 
>>> Before posting here I asked Joe Groff if there is any mailing list I can use
>>> to discuss my idea. He told me this might be a good place, because I was
>>> referring to the package manager. Then I’ve done my research to not create
>>> any redundant thread, but I only found one topic about the integration of
>>> SwiftPM in Xcode:
>>> https://lists.swift.org/pipermail/swift-build-dev/Week-of-Mon-20160215/000272.html <https://lists.swift.org/pipermail/swift-build-dev/Week-of-Mon-20160215/000272.html>
>>> 
>>> So here are my thoughts about a deeper integration of SwiftPM here:
>>> 
>>> - What if Xcode will introduce two new types of groups (the folder color
>>> could be orange like Swift for example, or even contain the bird icon).
>>> - These groups are analogous to already existing group types except they’ll
>>> represent Swift modules / packages
>>> - Basically we’ll have a single project file with multiple modules, where
>>> these modules should only exist inside that project (this is my own need
>>> right now)
>>> - Such a package / module group will have a configurable utilities, where
>>> one could configure the modules
>>> - This will reduce the re-building process, allow us to keep everything (not
>>> only .a or we’ll be able to hide .a files and just keep the sourcefiles
>>> inside such groups) inside a single project, gain the shiny namespaces like
>>> above, and make the file management way easier
>>> - This also should allow us create cross-dependencies if there is a good
>>> need for that in our project
>>> 
>>> + MainProject
>>> |
>>> +—Reference (module)
>>> |
>>> +—+— Magic (module)
>>>      |
>>>      +— SomeSubMagic (module)
>>> 
>>> We could easily create cross dependencies between modules here by just using
>>> the modules names and the types they provide.
>>> 
>>> // SomeSubMagic is a sub module of Magic
>>> class SomeSubMagic {
>>>    var magic: Magic // referring to its parent module
>>> }
>>> 
>>> What do you think about this?
>>> 
>>> --
>>> Adrian Zubarev
>>> Sent with Airmail
>>> _______________________________________________
>>> swift-build-dev mailing list
>>> swift-build-dev at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-build-dev
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160520/7a7a755b/attachment.html>


More information about the swift-evolution mailing list