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.
Naming Collisions
Imagine you have a project MyAwesomeApp
which contains two frameworks MyCoolThing
and 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.
Nesting Swift
By using nested types, and extensions, you can create namespaces to as many levels as you desire (e.g. MyAwesomeLibrary.SuperNetworking.HTTP
).
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 Networking
namespace.
Followed by the definition of HTTP
and FTP
classes within the SteveWilford.Networking
namespace.
Finally, in their own files, the HTTP
and 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 HTTP
/ 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.
goto fail
Gotcha! Unfortunately, for some reason that I cannot fathom this implementation fails to compile.
Essentially the HTTP
extension in SWHTTP.swift
works just fine, but the FTP
extension in SWFTP.swift
doesn’t.
It will work however if the code shown above is moved to the same file where the HTTP
and 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.