# Namespaces × submodules

**URL:** <https://forums.swift.org/t/namespaces-x-submodules/11673>\
**Category:** Pitches\
**Created:** [April 4, 2018, 11:28pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673 "2018-04-04T23:28:32Z")\
**Posts on this page:** 14\
**Page:** 3

<div class="post-metadata">

**Author:** ![nuclearace](https://avatars.discourse-cdn.com/v4/letter/n/51bf81/32.png) [@nuclearace](https://forums.swift.org/u/nuclearace)\
**Post date:** [May 17, 2018, 5:03pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/44 "2018-05-17T17:03:34Z")

</div>

> [@masters3d](#):
>
> The whole premise of submodules is access control.

Really? Do you consider namespaces and submodules to be the same thing? Because this thread is about namespaces, which I consider less to do with access control and more to do with code structure. People want a way to nest types and functionality in a more granular way than just a top level flat module. And a lot of people want a language level feature to accomplish this rather than nesting it all inside of a degenerate enum.

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [May 17, 2018, 5:14pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/45 "2018-05-17T17:14:31Z")

</div>

> [@nuclearace](#):
>
> ... which I consider less to do with access control and more to do with code structure.

Namespaces are a form of controlling access to code.

Unpopular opinion I guess 🙂

---

<div class="post-metadata">

**Author:** ![Avi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/avi/32/2962_2.png) [@Avi](https://forums.swift.org/u/Avi)\
**Post date:** [May 17, 2018, 5:19pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/46 "2018-05-17T17:19:39Z")

</div>

They don't _have_ to be but I think it would be really odd if they weren't. I suppose it could help only in reducing the number of types exposed at the top level of a module, but that really only matters for auto-complete when you're writing code. Not enough of a reason to add an otherwise-unfunctional addition to the language.

---

<div class="post-metadata">

**Author:** ![karim](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/karim/32/1412_2.png) [@karim](https://forums.swift.org/u/karim)\
**Post date:** [May 17, 2018, 6:35pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/47 "2018-05-17T18:35:23Z")

</div>

> [@masters3d](#):
>
> Scope private inside submodules would be a disaster, sometimes private meaning public othertines internal. Fileprivate in submodules would have access across modules without explicit public access to the submodule.

Maybe I'm missing something. How could `private` in a submodule ever mean `public` or `internal`? How could `fileprivate` have access across Modules?

AFAIK, all that has been proposed/discussed with regard to submodules relates to how code within a single Module can be further subdivided in ways that are less granular than individual files, while allowing the same access control rules that govern Swift currently to apply consistently to that new conceptual boundary.

> [@masters3d](#):
>
> Namespaces are a form of controlling access to code.

I'd disagree with this. My understanding of namespaces is as a form of deconfliction, not access control. Namespaces and access control are orthogonal concepts. In other words, a namespace of `A` or `B` allows you to say: "There's a `Foo` in domain `A` and there's a `Foo` in domain `B`, and `A.Foo` is not the same `Foo` as `B.Foo`."

I gather that @taylorswift 's initial point is that there's some potential common ground between the fundamental concepts of namespaces and submodules since the both generally revolve around the concept of "This code is all relative to a particular domain". If you can describe a domain of logic `A` that is distinct from a domain of logic `B`, then it makes sense to be able to:

- Speak of types being part of `A` or `B` (or neither) domains, and disambiguate `Foo`s in each domain that would otherwise be spelled the same (namespaces)
- Let `A` hide some of _its_ details from other code, let `B` hide some of _its_ details from other code (submodules)

And "Hey, wouldn't it be good if we can solve both parts of this problem with one feature."

---

<div class="post-metadata">

**Author:** ![tim1724](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tim1724/32/450_2.png) [@tim1724](https://forums.swift.org/u/tim1724)\
**Post date:** [May 17, 2018, 6:41pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/48 "2018-05-17T18:41:17Z")

</div>

> [@masters3d](#):
>
> The whole premise of submodules is access control. I just can not think of another reason for submodules but access control.
> 
> I must be missing something. Honestly, what am I missing?

See this thread:

> [@"Submodule" is an ambiguous term](https://forums.swift.org/t/submodule-is-an-ambiguous-term/12484):
>
> A request from me: if you use the word "submodule" to refer to any particular feature or design, please explain what you're using it for. People have a lot of different features they want in Swift that could be called "submodules", and there's not one agreed-upon design that people will understand when you say the word. I'll try to list the most common requests / proposals below. (Note that many proposed designs have combined more than one of these features. I've tried to decompose them for the …

---

<div class="post-metadata">

**Author:** ![Avi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/avi/32/2962_2.png) [@Avi](https://forums.swift.org/u/Avi)\
**Post date:** [May 18, 2018, 4:16am UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/49 "2018-05-18T04:16:56Z")

</div>

This explanation is the best I've read so far.

---

<div class="post-metadata">

**Author:** ![karim](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/karim/32/1412_2.png) [@karim](https://forums.swift.org/u/karim)\
**Post date:** [May 18, 2018, 7:15pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/50 "2018-05-18T19:15:26Z")

</div>

I'm going to use the term `submodule` here, but I'm referring to @taylorswift's combined `namespace`/`submodule` concept in general.

If we assume the following as a straw-man position to get the discussion flowing:

1. No material changes will be allowed to existing open/public/internal/fileprivate/private spectrum
2. A definition of "submodule" which includes the introduction of a visibility and organizational boundary between the file level and the module level

Then it follows that we need to discuss how the existing access modifiers apply to this new boundary.

For the sake of argument, I'll posit that if the "submodule" boundary is functionally _less_ granular than a file, then a single file cannot contain declarations in more than one submodule (ie: file-splitting).

This is a position that does introduce some important differentiation between traditional `namespace` and `submodules` concepts. There's not much of a reason to assert "no file-splitting" for a pure `namespace`, but it might be important for `submodules` to prevent `fileprivate` from being able to artificially bridge submodules (although, having said that... that might be a feature), so for now, let's assume we don't want that. And this is, I think, what @masters3d was warning about.

If we assert no "file splitting" (for now) then we can safely dismiss `private` and `fileprivate`. They will not change whether they are used within a submodule or not. I believe this is good. We want as little to change about existing access control as possible to ensure we can continue to reason about code.

This leaves `internal`, `public`, and `open` to understand. For the purposes of this discussion, I'll refer to all three of these conditions as `public` as in "is it public or not?" Does the submodule boundary impact the meaning of "public", or not?

I'm of two minds on this: On the one hand we need a way to distinguish that boundary. On the other hand we don't want to introduce new meanings of "public" around that boundary.

Does a submodule behave the same as a Module boundary for the purposes of the "public" spectrum (that is: Does `internal` or `public` refer to visibility outside the submodule, and within the parent module)? If so, then we need a way for the module to say "no really, submodule `B` is not just visible to me, but actually public", perhaps something like `export B` (which then allows re-namespacing like `export B as Bar` which could be interesting).

If a submodule _doesn't_ behave the same as Module boundary for the purposes of the "public" spectrum (that is, `public struct B.Foo {}` is already visible outside the Module because of `public`), then how can we declare members of the submodule which live in different files, that know about each other, but aren't visible outside the submodule?

Thoughts?

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [May 18, 2018, 7:48pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/51 "2018-05-18T19:48:13Z")

</div>

> [@karim](#):
>
> This leaves `internal` , `public` , and `open` to understand. For the purposes of this discussion, I'll refer to all three of these conditions as `public` as in "is it public or not?" Does the submodule boundary impact the meaning of "public", or not?

1. What would be the implicit access level inside submodules?

2. I understand that swift’s internal is like Java’s public but this is only true when there is only one module. How is internal public inside submodules?

---

<div class="post-metadata">

**Author:** ![ahti](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ahti/32/604_2.png) [@ahti](https://forums.swift.org/u/ahti)\
**Post date:** [May 18, 2018, 8:50pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/52 "2018-05-18T20:50:27Z")

</div>

> [@karim](#):
>
> then we need a way for the module to say "no really, submodule `B` is not just visible to me, but actually public"

If I'm not misunderstanding, what you are describing is very similar to the way (I think, I've only dabbled in Rust a bit) the [Rust module system](https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html) works (sorry if this has already been brought up, I haven't read the whole thread). Things are either `pub` (public) or not. If they are, they can be accessed from outside the module. Modules can `pub use` their submodules or members of their submodules, which makes them accessible from the outside.

I think a system like that could fit pretty well into Swift, if we extend the semantics of `public`/`open`, `private` and `internal` to always describe visibility outside the current module, including parent modules.

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [May 18, 2018, 9:31pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/53 "2018-05-18T21:31:58Z")

</div>

An idea I have had in this direction is:  
`open`: subclass-able anywhere  
`public`: usable anywhere  
`external`: (_new_) subclass-able in the current module  
???: (_new_) usable in the current module  
`internal`: subclass-able in the current sub-module

This is still source compatible with the current system, because the current system, interpreted in this system, is simply that modules would previously (currently) simply be limited to 1 sub-module per module, so we have only ever had the appearance of sub-modules.

Additionally, I am currently unsure of which of what I have listed as `external` and ??? are more deserving of being called "external", as I do not have a name for ??? yet, and I do not know which I think is more likely to be used.

---

<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 18, 2018, 11:01pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/54 "2018-05-18T23:01:51Z")

</div>

> [@karim](#):
>
> A definition of "submodule" which includes the introduction of a visibility and organizational boundary between the file level and the module level

okay okay, let’s keep a few things straight,, **submodules do not and should not have anything to do with symbol visibility**. That’s the difference between a submodule and a module. Submodules are _purely_ meant to be an organizational tool for the programmer. They should be _completely_ transparent to the compiler. So submodules can have access control (if we want them to!), but no visibility barriers.

---

<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 18, 2018, 11:17pm UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/55 "2018-05-18T23:17:43Z")

</div>

> [@karim](#):
>
> Does a submodule behave the same as a Module boundary for the purposes of the "public" spectrum (that is: Does `internal` or `public` refer to visibility outside the submodule, and within the parent module)? If so, then we need a way for the module to say "no really, submodule `B` is not just visible to me, but actually public", perhaps something like `export B` (which then allows re-namespacing like `export B as Bar` which could be interesting).

1. the term “submodule boundary” makes no sense, if it has a boundary, then it’s a module.
2. something to worry about with `public` submodules: since submodules are namespaces (hence the name of this thread!!), if a submodule is public, then the name of the submodule is part of your library API (and ABI). This is true because even though the submodule is transparent, it affects the qualified names of all of its members (this is true for all namespaces too.) I don’t think this is too different from the considerations involving all other Swift declarations, so I don’t think we’re “introducing new meanings of ‘public’” here.
3. I don’t get what distinction you’re trying to draw here. if something is public, then it’s exported. That’s what “public” means. code in the same module doesn’t care (from an access control standpoint) whether a symbol is public or not. Public only matters to external code.

> [@karim](#):
>
> If a submodule _doesn't_ behave the same as Module boundary for the purposes of the "public" spectrum (that is, `public struct B.Foo {}` is already visible outside the Module because of `public` ), then how can we declare members of the submodule which live in different files, that know about each other, but aren't visible outside the submodule?

we can’t do this. if a submodule has a public member, then the submodule declaration too should be public, since its name is part of the library interface. It it wasn’t, then they would provide no namespacing and there would be no point in having them.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [May 19, 2018, 12:36am UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/56 "2018-05-19T00:36:10Z")

</div>

Here’s how I see things:

• A submodule is not a module. In particular, un-annotated declarations are implicitly `internal`, and thus visible to the entire module, regardless of which (if any) submodule they are in. There needs to be a separate keyword for “visible in this submodule only”, and I recommend we find one that can completely replace `fileprivate`, using the rationale that a file is inherently its own submodule unless specifically made part of another submodule.

• A submodule is not the same as a namespace. Namespaces are a separate concept, similar to an empty enum. A single file can be used for multiple namespaces, and a single namespace can be used in multiple files. By contrast, a submodule is specifically used for grouping related files.

• If a submodule behaves like a namespace, it should be a “transparent” namespace, meaning that its name \*does not\* need to be provided when accessing things inside it (except when necessary for disambiguation).

• Submodules cannot be nested. A module can contain submodules, and a submodule can contain files, and that is that.

• • •

Thus, a submodules is primarily an organizational tool, providing a level of access control intermediate between “one file” and “the whole module”. Anything inside the submodule can be accessed directly, without writing the submodule name, from anywhere that it is visible.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [May 19, 2018, 5:14am UTC](https://forums.swift.org/t/namespaces-x-submodules/11673/57 "2018-05-19T05:14:42Z")

</div>

> [@Nevin](#):
>
> • Submodules cannot be nested. A module can contain submodules, and a submodule can contain files, and that is that.

- Just for clarification, by that you don‘t mean that a submodule cannot depend on a different sub-/module?

- What if I want to break my sub-module into even smaller parts and those parts should be encapsulated from the main module and even partly from the module itself? If we can already do `module A imports module B which imports but not expose module C` then why not allow `module A has submodule B which has a nested own submodule C and D`?

[Previous page](https://forums.swift.org/t/namespaces-x-submodules/11673.md?page=2)
