# An Enum Based Approach to Namespaces

**URL:** <https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487>\
**Category:** Discussion\
**Created:** [May 8, 2018, 7:07pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487 "2018-05-08T19:07:35Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [May 8, 2018, 7:07pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/1 "2018-05-08T19:07:35Z")

</div>

As [@jrose](https://forums.swift.org/t/submodule-is-an-ambiguous-term/12484) has correctly pointed out the term "submodule" is quite ambiguous, so I will not use that term to refer to my idea, but instead refer to it by the more specific term: "namespace"

## Current State of the Art

Currently, in order to create a standalone namespace smaller than a module, one must create an `enum` with no cases (aka an 'empty' `enum`). This has a few problems:

- The namespace looks like a type to coders unfamilar with the use of `enum` as a namespace, and to further confusion can be extended to conform to protocols.
- All non-type declarations inside the `enum` must be marked `static` which adds boilerplate and reduces readability.
- There's no way to specify that a member of a nested type should only be visible within its enclosing `enum`.

## Proposed Solution

Introduce a new declaration `namespace`. This acts as an empty `enum` except as follows:

- It may not be used as a type in any context, including generic parameters. Nor may it conform to protocols.
- A `namespace` may not be generic and may not be nested inside of a generic type.
- All non-type declarations are effectively `static`. Explicitly specifying a top-level `namespace` variable as static is an error.
- Declarations with less than `public` access in nested types or `namespace`s are only visible within the enclosing `namespace` or an extension of that `namespace`, which must still be inside the declaring module or file for `internal` and `(file)private` declarations respectively.
- Protocols may be declared inside of a `namespace` (we might want to allow that in type declarations in general).
- A `namespace` may only be extended from the module it is declared in (although the types inside it may be extended as normal).

## Example of Use

```
public namespace Random {
    // `DefaultRNG`s initializer defaults to `internal`.
    public struct DefaultRNG: RandomNumberGenerator {
        public func next() -> UInt64 { ... }
        ...etc...
    }
    public var defaultRng = DefaultRNG() // initializer is visible here.
}

var otherRng = Random.DefaultRNG() // intializer is not visible here, so compilation fails.

```

## Future Directions

- Allowing `namespace`s to be declared inside of generic types. This probably depends on whether and how we decide to handle static stored declarations in generic types. We could always just require that `namespace`s inside generic types only have computed properties.
- Allowing one to import a public declaration from a `namespace` (or all of the public declarations) directly into the current module. Individual declaration import would also be nice to have in general.
- Sugar for placing the contents of an entire file inside of a `namespace`. This is purely additive.

## Alternatives Considered

- Do nothing.
- Allow prefixing `enum` declarations with `static` to make all enclosed non-type declarations `static`, which would solve only the boilerplate issue.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [May 8, 2018, 7:21pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/2 "2018-05-08T19:21:24Z")

</div>

Here's another issue with enums-as-namespaces that should be mentioned: the enum is still a type, and so it generates type metadata in the binary that must be unique or else you end up with duplicate symbols at link time.

This means that if you spread out the definitions in a namespace across multiple files, you may only have a single `enum Foo` declaration, and the rest are `extension Foo`. It's asymmetrical and awkward when all you really want is for the declarations to be grouped together and have their names mangled in the same way in the final binary.

It's easy to imagine code generation scenarios where you might want to piece together a number of related declarations across multiple files into the same namespace, and the restriction above forces the generator to have to ensure that there's only a single instance of the actual type declaration instead of just being able to independently produce the namespaced symbols.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [May 8, 2018, 7:21pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/3 "2018-05-08T19:21:54Z")

</div>

related: [Namespaces × submodules](https://forums.swift.org/t/namespaces-x-submodules/11673)

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [May 8, 2018, 7:53pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/4 "2018-05-08T19:53:23Z")

</div>

That's a good point. That probably makes it worthwhile to just use `namespace Foo` everywhere that a namespace is used instead of allowing `extension Foo`.

@taylorsift I feel like your idea and my idea are very close. At the very least the `func Namespace.foo() { }` syntax is trivial sugar over my proposal, and even if we did base the implementation on `enum` internally we'd still want something akin to your `namespace = Foo` syntax. I'm not sure I like the `namespace Foo(import Bar)` syntax though.

---

<div class="post-metadata">

**Author:** ![David\_Catmull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_catmull/32/1007_2.png) [@David\_Catmull](https://forums.swift.org/u/David_Catmull)\
**Post date:** [June 21, 2021, 9:34pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/5 "2021-06-21T21:34:31Z")

</div>

I'm reviving this thread because the `enum` as namespace thing bugs me every time, and I think this proposal covers the issue really well. There are other threads on this topic too, and AFAICT the arguments against mostly boil down to "let's avoid adding more keywords". But I think the differences between `enum` and the proposed `namespace` are valuable.

For example, this nonsense compiles:

```swift
enum MyNamespace { ··· }

protocol Silliness
{
  func impossible() -> MyNamespace
}

```

There may be cases where an uninhabited enum makes sense as a return type (like `Never`, of course), but not for one that's supposed to be a namespace, and I want to be able to express that.

As proposed, a `namespace` is mostly a more restricted version of an `enum`, except for being able to include protocols. If this were to be implemented, what are the potential complications of allowing nested protocols?

---

<div class="post-metadata">

**Author:** ![David\_Catmull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_catmull/32/1007_2.png) [@David\_Catmull](https://forums.swift.org/u/David_Catmull)\
**Post date:** [October 13, 2021, 3:15pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/6 "2021-10-13T15:15:01Z")

</div>

..or at least, I thought I was reviving the thread 🙂

I'll try again because I really am curious about what the answers might be. As I said, the counter-arguments I've seen tend to be essentially that it's not worth adding another keyword. IMO this thread has some decent arguments that it _is_ worthwhile, so I'd like to see other angles addressed as well.

Can anyone comment on whether namespaces, especially as proposed here, might be hard to implement? Or why they might otherwise be actively bad?

---

<div class="post-metadata">

**Author:** ![blobs](https://avatars.discourse-cdn.com/v4/letter/b/7cd45c/32.png) [@blobs](https://forums.swift.org/u/blobs)\
**Post date:** [April 4, 2022, 2:50am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/7 "2022-04-04T02:50:55Z")

</div>

Reviving this as well lol, right there with you @David_Catmull

I am always using caseless `enum`s as a way to organize my constants, _inside_ of my types... ex:

```swift
class MyView: UIView {}

// MARK: Constants

extension MyView {
    enum Layout {
        enum Label {
            static let maxLines = 3
        }

        enum Image {
            static let margin = 5
        }
    }

    enum Style {
        static let background: UIColor = .white

        enum Image {
            static let background: UIColor = .purple
        }
    }
}

```

I use a lot of nesting, since it makes it really nice on the calling side where each context level is its own namespace, ex calling `Layout.Image.margin` inside of `MyView`... and you can use the same identifiers, just in different contexts, ex calling `Style.background` or `Style.Image.background`

* * *

After browsing different discussions in these forums about `submodules` and `namespaces`, I don't think the idea of a submodule really satisfies my use case... from my understanding of the [Namespaces × submodules](https://forums.swift.org/t/namespaces-x-submodules/11673) proposal, submodules can be nested within each other, sure... but they can't be nested within _types_... and I don't want to have to define a `MyViewConstants` submodule outside of `MyView` just to be able to define constants, for these reasons:

- Naming conflicts
- `MyViewConstants` should _never_ be more visible than `MyView` -- which could happen if they were both top level types

* * *

What I would like to see is a `namespace` type that is `non-instantiable`, `non-returnable`, `non-extendable`, can be nested inside of other types, and where you don't need to mark `static` on everything... purely for the intention of better organization and code readability.

imo that outweighs the argument for not cluttering Swift with more keywords. I've also seen an argument in the forums that caseless enums are an established pattern that people are used to, but in my experience it's usually a pretty opinionated debate about `struct with a private initializer` vs `caseless enum`... since it's considered an anti-pattern to what an `enum` should really be.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [April 4, 2022, 4:25am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/8 "2022-04-04T04:25:03Z")

</div>

> [@blobs](#):
>
> What I would like to see is a `namespace` type that is `non-instantiable` , `non-returnable` , `non-extendable` , can be nested inside of other types, and where you don't need to mark `static` on everything... purely for the intention of better organization and code readability.
> 
> imo that outweighs the argument for not cluttering Swift with more keywords. I've also seen an argument in the forums that caseless enums are an established pattern that people are used to, but in my experience it's usually a pretty opinionated debate about `struct with a private initializer` vs `caseless enum` ... since it's considered an anti-pattern to what an `enum` should really be.

an alternative:

```swift
enum Namespace:Never 
{
    ...
}

```

that said, i just don’t see much utility in statically guaranteeing that an `enum` is empty. i don't think i've ever accidentally added a case to a namespace enumeration.

---

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [September 22, 2022, 7:44am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/9 "2022-09-22T07:44:05Z")

</div>

In the mean time, I am going to console myself by chanting this:

**enum** is an **e** xcellent **n** amespace **um** brella

before each time I employ the services of an uninhabited enum 🙂

But there still remains the problem of protocol names floating in global namespace ☹

---

<div class="post-metadata">

**Author:** ![sssilver](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sssilver/32/33875_2.png) [@sssilver](https://forums.swift.org/u/sssilver)\
**Post date:** [January 31, 2024, 5:19am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/10 "2024-01-31T05:19:49Z")

</div>

Playing the devil's advocate here.

Namespacing within a module only becomes necessary if your module is large.

Why not decompose your large modules into smaller modules? Once you reach a point where your namespacing needs are addressed through module decomposition, you may find that you now actually have modules that "do one thing and do it well", that your project is more idiomatic, modular, and maintainable, and that you've benefitted in areas you weren't even expecting.

Free namespacing through the existing modules-as-namespaces paradigm will just be the cherry on top.

---

<div class="post-metadata">

**Author:** ![Dmitriy\_Ignatyev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dmitriy_ignatyev/32/11340_2.png) [@Dmitriy\_Ignatyev](https://forums.swift.org/u/Dmitriy_Ignatyev)\
**Post date:** [January 31, 2024, 1:39pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/11 "2024-01-31T13:39:03Z")

</div>

> [@sssilver](#):
>
> modules that "do one thing and do it well", that your project is more idiomatic, modular, and maintainable, and that you've benefitted in areas you weren't even expecting

This come at a price, it is not for free. Separating into small modules need knowledge, expertise and time. Projects can have a lack of one or all of this.

The second point is about api design. Even if all your modules are small, well formed and designed, you can get ergonomic benefits in cases like `UITableView.Delegate` instead of having `UITableView` class and `UITableViewDelegate` protocol.  
NameSpaces help better organize code even in small modules.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [January 31, 2024, 1:51pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/12 "2024-01-31T13:51:25Z")

</div>

Also, at present, Swift modules all share the same single-level namespace. This doesn't scale well at all for many large codebases, which is why Bazel for example defaults to a `path_based_module_naming` approach. It's consistent (vs. everyone in a shared monorepo choosing names for every one of their modules, which would be horribly unpredictable), but it's also an ugly wart on our Swift usage.

Submodules have been discussed off-and-on, but (if based on the Clang definition) they alone wouldn't solve that problem because submodules aren't just naming hierarchies like Java packages are; some parent module fully contains its submodules and are imported as such.

Even if that weren't the case, there are some limited situations where a namespace that can span modules would be useful. SwiftProtobuf also does a `Package_Based_Name_Mangling` for generated types because protobuf's concept of "packages" doesn't map cleanly to Swift modules. It would be nice to be able to say that module M1 and module M2 can both define namespaces that are effectively merged if a client imports both M1 and M2. But this might be too niche of a case to rationalize.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [February 1, 2024, 12:13am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/13 "2024-02-01T00:13:03Z")

</div>

I believe the increasing number of uninhabited enums being used in the standard library to namespace things like atomics and unicode are sufficient proof that we need some form of namespacing in Swift. Just organize your code better isn't a very compelling argument against namespaces.

The problem is implementing them. Until someone can spare the time and effort to implement proper namespaces for Swift, there's not going to be any movement on this.

---

<div class="post-metadata">

**Author:** ![Datagram](https://avatars.discourse-cdn.com/v4/letter/d/7cd45c/32.png) [@Datagram](https://forums.swift.org/u/Datagram)\
**Post date:** [February 1, 2024, 1:14am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/14 "2024-02-01T01:14:35Z")

</div>

I completely agree that Swift needs namespace.

Here we are using enum to create a namespace but hoping we will be able soon to replace with true namespace.

Please Swift compiler team, consider this for Swift 6.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [February 1, 2024, 2:55am UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/15 "2024-02-01T02:55:47Z")

</div>

> [@allevato](#):
>
> Even if that weren't the case, there are some limited situations where a namespace that can span modules would be useful. SwiftProtobuf also does a `Package_Based_Name_Mangling` for generated types because protobuf's concept of "packages" doesn't map cleanly to Swift modules. It would be nice to be able to say that module M1 and module M2 can both define namespaces that are effectively merged if a client imports both M1 and M2. But this might be too niche of a case to rationalize.

this is not a niche use case to me, i use this pattern extensively. but i do not see the motivation for new language features here. can’t we already do this by selectively re-`@_exported`ing the enum namespaces?

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [February 1, 2024, 1:20pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/16 "2024-02-01T13:20:59Z")

</div>

> [@taylorswift](#):
>
> this is not a niche use case to me, i use this pattern extensively. but i do not see the motivation for new language features here. can’t we already do this by selectively re-`@_exported`ing the enum namespaces?

I'm not sure I follow. If you have the following independent modules:

```swift
// GeneratedModule1
public enum Com {
  public enum MyCompany {
    public struct MyType1 {}
  }
}

// GeneratedModule2
public enum Com {
  public enum MyCompany {
    public struct MyType2 {}
  }
}

```

What are you proposing that avoids this error, if the goal is to avoid requiring module-qualifying the names?

```swift
import GeneratedModule1
import GeneratedModule2
let x: Com.MyCompany.MyType1 // error: `Com` is ambiguous
let y: Com.MyCompany.MyType2 // ditto

```

Footnote: Interestingly, _function call_ resolution collects candidates differently, so the following _does_ work without error:

```swift
import GeneratedModule1
import GeneratedModule2
let x = Com.MyCompany.MyType1()
let y = Com.MyCompany.MyType2()

```

But any attempt to use them in _type_ position will fail without module qualification. I'm not sure if that inconsistency is desired behavior, though?

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [February 1, 2024, 9:56pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/17 "2024-02-01T21:56:32Z")

</div>

> [@allevato](#):
>
> I'm not sure I follow. If you have the following independent modules:
> 
> ```swift
> // GeneratedModule1
> public enum Com {
> public enum MyCompany {
> public struct MyType1 {}
> }
> }
> 
> // GeneratedModule2
> public enum Com {
> public enum MyCompany {
> public struct MyType2 {}
> }
> }
> 
> ```
> 
> What are you proposing that avoids this error, if the goal is to avoid requiring module-qualifying the names?

you would create a third module that contains just the namespace enum (e.g. `_Com`), and then the two other modules would import the namespace with:

```swift
@_exported import enum _Com.Com

```

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [February 1, 2024, 10:03pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/18 "2024-02-01T22:03:03Z")

</div>

What happens when both those modules then declare their own `MyCompany` in extensions of `Com`, and a client imports both and tries to reference one of them? Seems like the same problem all the way down.

This doesn't feel like it scales any better than the original approach. The goal is to avoid needing a single canonical definition of the namespace anywhere, because—especially for code generation—you don't always have a full view of the world and you can't guarantee that you'll create exactly one of those things.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [February 1, 2024, 10:21pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/19 "2024-02-01T22:21:32Z")

</div>

> [@allevato](#):
>
> What happens when both those modules then declare their own `MyCompany` in extensions of `Com`, and a client imports both and tries to reference one of them? Seems like the same problem all the way down.

you would do the same thing: create a single-type module that imports `_Com` and defines the `MyCompany` namespace, and libraries that use the two-level namespace would reexport that namespace instead.

> [@allevato](#):
>
> This doesn't feel like it scales any better than the original approach. The goal is to avoid needing a single canonical definition of the namespace anywhere, because—especially for code generation—you don't always have a full view of the world and you can't guarantee that you'll create exactly one of those things.

i’m not seeing the motivation for using macros to define the namespaces themselves, in my mind namespaces are so large and few in number that the macros should be sticking to populating the namespaces with extensions.

i suppose if you have a very high number of namespaces that you want to generate with a macro, then that should be a separate tool that has the sole responsibility for creating the canonical namespace definitions.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [February 1, 2024, 10:53pm UTC](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487/20 "2024-02-01T22:53:07Z")

</div>

I'm not referring to macros; by "code generation" I mean a build system generating Swift code from some other external input, like protobufs.

> [@taylorswift](#):
>
> i suppose if you have a very high number of namespaces that you want to generate with a macro, then that should be a separate tool that has the sole responsibility for creating the canonical namespace definitions.

This by your own definition requires some task in the build system to have a full view of the world, which is precisely what needs to be avoided. Such tasks become bottlenecks during build planning because introducing a new namespace anywhere in the build graph requires the whole set to be recomputed.

[Next page](https://forums.swift.org/t/an-enum-based-approach-to-namespaces/12487.md?page=2)
