# Yet another module modification proposal

**URL:** <https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800>\
**Category:** language design\
**Created:** [August 23, 2017, 3:08pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800 "2017-08-23T15:08:41Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![crlf0710](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crlf0710/32/1987_2.png) [@crlf0710](https://internals.rust-lang.org/u/crlf0710)\
**Post date:** [August 23, 2017, 3:08pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/1 "2017-08-23T15:08:41Z")

</div>

Hi, i’ve been reading several articles about new module design by aturon and withoutboats. Those ideas looks great at their own rights. However i just don’t feel it’s appealing enough to make such a move (i.e. kill old pros together with the cons). I’d like to write down what i’m thinking to see whether other people think one or more of them make sense.

1. deprecate `extern crate foo`.
2. [pub] `mod *;` for module discovery at current level, and [pub] `mod foo;` for loading only `foo.rs`.
3. See anything starting with `::` as absolute, reserve `::self` to refer to current crate.
4. Keep current module visibility rules (See them are restrictions on their items). However, no longer distinguish empty mod and non-existent mod and invisible mod in casual paths. i.e. `use self::empty_mod::*`, `use self::inexist_mod::*`, `use self::empty_mod`, `use self::inexist_mod` all does nothing and doesn’t raise an error, whether pub or not.
5. allow `pub use ::self::**::{foo::Foo, bar::Bar, module::inner_module}` which searches and reexport these types or traits or modules.
6. No changes to `pub(restricted)` and friends. Just read `pub` keyword as “publicity”.

---

<div class="post-metadata">

**Author:** ![rpjohnst](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rpjohnst/32/9524_2.png) [@rpjohnst](https://internals.rust-lang.org/u/rpjohnst)\
**Post date:** [August 23, 2017, 4:18pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/2 "2017-08-23T16:18:20Z")

</div>

I’m not sure how this helps the learnability issues that originally motivated the module system changes to begin with.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [August 23, 2017, 5:25pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/3 "2017-08-23T17:25:33Z")

</div>

This removes some boilerplate, but the main motivation was:

- both `mod` an `use` create items that can conflict with each other, and no other language has equivalent of `mod`, so it’s very weird and surprising to new users.
- In crate root all paths appear to be absolute, but in modules they diverge — paths in code suddenly seem to be relative. This again is confusing and feels inconsistent to new users, and makes learning curve steeper.

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [August 23, 2017, 8:06pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/4 "2017-08-23T20:06:03Z")

</div>

> [@kornel](#):
>
> no other language has equivalent of `mod`

`namespace` in C++ goddamit.  
`mod` is a namespace that can be optionally "outlined" in a separate file in a slightly less verbose way than in C++.  
Many things in the module system are made to look familiar to C/C++ developers (the primary Rust audience) - `namespace` == `mod`, `use` == `using`, same mod separator in paths `::`.

---

<div class="post-metadata">

**Author:** ![rpjohnst](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rpjohnst/32/9524_2.png) [@rpjohnst](https://internals.rust-lang.org/u/rpjohnst)\
**Post date:** [August 23, 2017, 8:08pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/5 "2017-08-23T20:08:12Z")

</div>

`namespace` is not at all equivalent to `mod`. It _is_ equivalent to `mod .. {}`, but it does not trigger or gate the inclusion of a separate file, which is the part that the RFC removes.

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [August 23, 2017, 8:15pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/6 "2017-08-23T20:15:02Z")

</div>

`mod m;` is an additional convenience to avoid separately `include`ing the file containing `mod m { ... }` (like it’s done in C++), it changes nothing fundamentally, “not at all equivalent” is as far from the truth as possible.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [August 23, 2017, 8:51pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/7 "2017-08-23T20:51:40Z")

</div>

I see the similarity. However, there are crucial differences:

- The declaration is _in_ the file, not outside of the file.
- It doesn’t control files. It’s not related to build system at all.
- It can be repeated in multiple files, so can be seen more as a name-prefixing macro (opposite of `use`).
- Compilation units, headers, and some attempts at actual modules make comparisons all muddled.

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [August 23, 2017, 9:20pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/8 "2017-08-23T21:20:12Z")

</div>

There are more crucial differences!  
For example, names from outer namespaces are in scope in inner namespaces, privacy in C++ doesn’t work with namespaces but with classes. (The “declaration is in the file, not outside of the file” doesn’t seem crucial to me though.)  
But knowing `namespace`s and `include`s still provide an excellent starting point into Rust module system because it can be initially explained in these terms. The large scale project structure can be expressed almost identically with "`namespace` + `include` + `using`" and "`mod` and `use`" (`using` is an “item” in C++ too, btw), all that remains is to learn differences in details.

---

<div class="post-metadata">

**Author:** ![rpjohnst](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rpjohnst/32/9524_2.png) [@rpjohnst](https://internals.rust-lang.org/u/rpjohnst)\
**Post date:** [August 23, 2017, 9:25pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/9 "2017-08-23T21:25:06Z")

</div>

The point remains that no other language has an equivalent to the way Rust decides to include files in the build, and that’s the thing that’s weird and surprising.

---

<div class="post-metadata">

**Author:** ![crlf0710](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crlf0710/32/1987_2.png) [@crlf0710](https://internals.rust-lang.org/u/crlf0710)\
**Post date:** [August 24, 2017, 2:23am UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/10 "2017-08-24T02:23:29Z")

</div>

Well,

> The point remains that no other language has an equivalent to the way Rust decides to include files in the build, and that’s the thing that’s weird and surprising.

I don't see "not doing exactly the same as other languages do" as a cons at all. I think writing all things down (explicitly) and to let compiler help you check them is exactly the spirit of the Rust Style.

---

<div class="post-metadata">

**Author:** ![rpjohnst](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rpjohnst/32/9524_2.png) [@rpjohnst](https://internals.rust-lang.org/u/rpjohnst)\
**Post date:** [August 24, 2017, 2:36am UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/11 "2017-08-24T02:36:01Z")

</div>

It’s not _just_ “we should match other languages” by itself. It’s that the module system, of all things, is not something that needs to be different from other languages, because in this particular case that makes it harder for no real gain.

What exactly does the compiler check for you in the current module system that it can’t in the proposed system?

---

<div class="post-metadata">

**Author:** ![crlf0710](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crlf0710/32/1987_2.png) [@crlf0710](https://internals.rust-lang.org/u/crlf0710)\
**Post date:** [August 24, 2017, 3:59am UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/12 "2017-08-24T03:59:53Z")

</div>

In this case, nope in checking. However implicitly load all files in work tree as modules is:

1. Forbidding people to put random files in working tree.
2. Putting an restriction on all external tools that they can’t generate anything with `.rs` unless intended.
3. Allowing `build.rs` to inject code as module very easily. (Which is both good and bad).
4. No longer allow `include!` an `.rs` file (have to use another suffix) since it will be loaded twice.

No, i’m not saying the proposal is bad. It’s just that changing existing users’ habit is … I’m not sure it’s worth it at all. That’s why i suggest using `mod *;` to opt in this behavior.

---

<div class="post-metadata">

**Author:** ![edmccard](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/edmccard/32/2258_2.png) [@edmccard](https://internals.rust-lang.org/u/edmccard)\
**Post date:** [August 24, 2017, 5:16pm UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/13 "2017-08-24T17:16:48Z")

</div>

> [@crlf0710](#):
>
> However implicitly load all files in work tree as modules is...

... easily worked around using the `#![ignore]` attribute in the current RFC.

(Although personally I'd prefer a `.rustignore` file similar to `.gitignore`/`.npmignore`, so that tools such as @BurntSushi's ripgrep, which already know how to use `.gitignore`, don't have to learn how to parse rust's `#` directives to do their job.)

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:28am UTC](https://internals.rust-lang.org/t/yet-another-module-modification-proposal/5800/14 "2019-03-25T08:28:56Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
