New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline module syntax is confusing when learning modules #1904
Comments
I don't know about this. Inline modules are a somewhat niche case, but also one that appears in all cargo-generated projects through the Maybe we should be more upfront about the various ways modules are instantiated? Presenting the three ways (inline definition; explicit declaration, implicit definition in a file; explicit declaration, implicit definition as a directory) and their typical use cases (respectively: unit tests; general project organization; ditto, but with submodules), before we even go to how modules control privacy and appear in paths? With that out of the way, we could move forward and say something to the effect of "in the wild, you will generally see modules defined in files, but in this book and other online resources (e.g. playground) it is more convenient to use inline modules to explain how modules work, as it allows us to stay inside of a single file." Maybe it generally wouldn't hurt to also draw a comparison to similar concepts in other languages (although I don't know if the book does this for other areas and if it is a good practice for the book), to especially emphasize that modules are somewhat different from these concepts. There are few obstacles I stumbled upon when first learning modules (mostly the "Things to keep in mind about modules" in this message) because it was defying my expectations coming from other languages. Some of these, and others bullet points could maybe be summarized somewhere in the page? Again, I don't know if this kind of "common mistakes" paragraph is a good fit for the book, though. |
I haven't seen people struggle with privacy that much. Rust's But every time I teach modules, I see people really struggle with My hypothesis is that it's easier to teach files first, and then inline modules. The split into files is the hard part, because it needs understanding that Once you know how modules work, then seeing |
Please note that this chapter has had revisions and no longer contains the
There are a few places we mention other languages, but we're trying not to make too many assumptions about which programming language the reader comes from. This is definitely a challenge. |
The new revision of the chapter IMHO still has the same overall issues: it still uses inline modules as if it was a normal thing to do, and still leaves splitting into files to last. And the multi-file example still includes This sentence strikes me as particularly odd:
I haven't seen people actually start with an inline module and grow it. To me having the project structure reflected in the filesystem is not merely an unfortunate necessity caused by files getting too big, it's a goal in itself. The book puts a lot of focus on privacy around modules, but to me this is an entirely different concern, of lower priority even. For example, in JS where the privacy basically doesn't exist, people still split into files as a way to organize the project: https://github.com/webpack/webpack/blob/master/lib/OptionsApply.js even when the file is totally unnecessary (and could have been inline): https://github.com/webpack/webpack/blob/master/lib/MemoryOutputFileSystem.js So my perspective is I want files, I have files, and how do I make the module system load my files? It's entirely opposite way of thinking from the book's approach of having modules, privacy boundaries and maybe splitting them also as files. |
I've grepped all .rs files in all crates from crates.io:
There is a Inline But of general usage, 94% of module uses are to split code into files. |
The new file example is close to the thing I've struggled the most with:
because it sort-of implies that you have to have a I didn't get that when I was learning modules. I've only literally "understood" that
and was flabbergasted why the compiler doesn't like it, so I've tried deleting
and that didn't work either, so then I've replaced all in lib.rs:
and because that finally worked, I also tried keep using the "working" version also in backyard.rs:
and again was frustrated that the compiler can't find it, while the exact same syntax worked just a second ago! I had Now I have the curse of knowledge so I can't really tell if I'd learn modules from this chapter, but I'm not seeing it address the points of confusion I remember I had. And I remember being really angry at inline modules, because I had no idea how they map to files, and I felt the documentation was about oranges, and I wanted apples. |
I agree that modules would be easier to understand if they were explained files-first. I saw that you were unable (and unwilling) to rewrite this part of the book - why is that? Meanwhile there are a few gradual improvements I think would at least somewhat help:
|
I'm going to give this a close for the same reason; we are not revisiting this chapter anytime soon, and if we do, I will be coming back to this thread. There's no reason to leave the issue open though. |
Another case where a user misunderstood that chapter, and used inline syntax where it didn't make sense: https://users.rust-lang.org/t/modules-with-multiple-files/54752 |
https://doc.rust-lang.org/book/ch07-02-modules-and-use-to-control-scope-and-privacy.html
This chapter introduces modules first by showing the inline module syntax. I understand that this syntax is easier to demonstrate in the book than separate files. However, I think it's only convenient for the teacher, not for the student:
https://internals.rust-lang.org/t/data-point-about-the-new-module-system-learnability-and-musings-about-language-stability/9770/27
Looks, but doesn't work like, namespace/package syntax in other languages
This syntax has a potential to be more confusing than helpful. The
mod foo {…}
statement is syntactically very similar tonamespace foo {…}
in C++ or PHP, but has very different semantics. If the reader has intuition based on these languages, they will be utterly confused thatmod
doesn't work the way they expect.Rust's modules are different from namespaces in the other languages in the sense that a "parent" file names and declares existence of a "child" module ("I have a module X"). In C++, PHP and Go the "child" file itself declares that it's a module ("I'm a module X"). This is a common point of confusion, and the inline syntax muddles it.
File-based example still uses inline syntax
The first example about splitting into separate file mixes inline and file-based modules. This requires paying special attention to the fact that there were multiple modules, and only one of them has changed.
It can be easily misinterpreted as the C++/PHP/Go-like syntax which requires module to declare itself in the file.
For example, in Go, a very similar syntax could be a valid and idiomatic usage:
but has quite different meaning from Rust's! This false analogy is quite dangerous, because the reader may think "aha! I get it now!" and totally not get it.
To reiterate, there's a subtle difference how the syntax splits modules into files in Rust and other languages.
I'm marking
-
(red) lines that are moved to an external file. Rust's way:vs C++/PHP/Go way:
and this chapter uses an unfortunate syntax and examples that don't clarify that point of confusion.
Shows uncommon case, delays most common
Apart from an occasional
mod test {}
, I don't see many inline modules used in Rust code. The modules are overwhelmingly a way to split project into separate files. But the reader isn't warned about that, and file separation is mentioned last.I think it'd be better to explain modules with separate files from the start, so that C++/Go users will see that
mod
is closer to being#include
/import
, rather thannamespace
/package
constructs. Neither analogy is very good, but the former is less harmful to understanding than the latter. I'd probably go as far as not showing the inline syntax at all, apart from some advanced chapter or appendix.The text was updated successfully, but these errors were encountered: