When Apple announced Swift in June 2014 namespaces was one of the things that caught my attention as I missed the ability to easily modularise code in ways similar to C++ namespaces and Java packages.
However it turned out that namespaces are implicit, and based on the name of the module in which types are included. For example if you create a Swift framework called
MyCoolThing which contains a class called
WidgetX a user of your framework need only use the name
WidgetX in their code and the compiler will know what to do.
Imagine you have a project
MyAwesomeApp which contains two frameworks
SomeOtherCoolThing, what if all three contain a
WidgetX? Well, you should probably have a word with yourself to start with.
While that may be a somewhat contrived example, it could happen, and they anticipated it…
@oleganza You can always explicitly qualify with the module name. F.e., if you define a "swap" you can always get to "Swift.swap" as well.
— Chris Lattner (@clattner_llvm) June 6, 2014
Framework All The Things!?
Creating a framework for each desired namespace seems like it might be a lot of work and added complexity, especially if you’re not planning on distributing / using the frameworks outside of the project. Fortunately Swift also brought nested types to the table, allowing us to achieve namespaces a different way.
By using nested types, and extensions, you can create namespaces to as many levels as you desire (e.g.
An example project for how this is achieved is available on GitHub at https://github.com/NxSoftware/Namespacing and I’ll give a quick walkthrough of what’s going on.
The root class
SteveWilford is defined in it’s own file and, for no particular reason, contains no other code (though it would be fine to put constants or methods in this class). From now on, I’ll refer to this as the top level namespace.
In another file I have defined a
SteveWilford extension which contains a
Networking class which represents the
Followed by the definition of
FTP classes within the
Finally, in their own files, the
FTP classes are populated with methods.
During the process of writing this post I’m started to think that it might be easier to follow if the
FTP classes were fully implemented in their own file instead of being defined at the
Networking namespace level.
Usage is then as simple as referencing each nested type as normal, using the standard dot notation.
Gotcha! Unfortunately, for some reason that I cannot fathom this implementation fails to compile.
HTTP extension in
SWHTTP.swift works just fine, but the
FTP extension in
It will work however if the code shown above is moved to the same file where the
FTP classes are defined. This smells like a compiler bug and I have therefore filed rdar://20337822 and unless you can figure out if I’ve done something completely stupid please duplicate the Radar.
Real World Usage
Would you want to use this in a real-world, production codebase? To be honest, I’m not sure. As I alluded to earlier I’m not 100% sold on the current structure and, so far, has been nothing more than a technical exercise.