As far as I am aware, Swift lacks the namespace keyword and the ability to explicitly define namespaces. However, one can prefix imported functions and types with the module name they were exported from. There is a workaround using enums or structs together with static functions, but when using these, one has to use fully qualified names, such as MyNamespace1.MyNamespace2.myFunction, which can sometimes be cumbersome. Another workaround involves using typealias.
The question is: what are the best practices regarding this?
Should one simply avoid nested namespaces? Or are they acceptable, and developers should just get used to them? Alternatively, should one define appropriate typealias for convenience? If typealias is considered idiomatic in this case, where should it be defined—within the library itself or in the client code?
Thanks.
P.S.: If there are any factual errors, I would be happy to be corrected.
My approach for this (as far as libraries go) is usually to define a single top-level enum, and nest (via extensions) types in that enum that depend on other types in that namespace.
I think whenever enum or struct is used for anything other than defining enumerations and structures, that's already not idiomatic in Swift.
Sometimes nested types come "naturally", e.g. you may have something like List.Item. But other than that, I don't think there is a nice and let alone idiomatic way to have nested namespaces.
Could you elaborate, how is typealias an alternative to nested namespaces?
After you do it - you can type just cout instead of std::cout
For example if you have MyModule.MyEnum.MyType you can do something like typealias MyType = MyModule.MyEnum.MyType and use MyType without preceeding MyModule.MyEnum
That works for types, importing methods is a bit quirkier, I believe that if you don't care about the named arguments you can just do let myFunc = Namespace.myFunc or define another function that wraps the one you want, but I admit that it is cumbersome to use.
From my experience it's almost never necessary in Swift. Firstly, the module qualifier/prefix is optional. You use it only when there are naming conflicts between modules that you use in the same Swift source file, and you need to disambiguate. So I'd say it's opposite to C++ in a sense that namespaces are not forced but can be disambiguated when necessary.
As for nested types, like MyEnum.MyType, this is not very common, library creators don't do this as far as I can tell, or at least not just for the sake of having a namespace (apart from "natural" cases of nesting that I mentioned before). You will likely force your users to use type aliases anyway, so why bother?
Sometimes you want to group together some global functions under a single umbrella. I usually do it using a class. The naming would be such that the class name and the function names complement each other. For example, instead of