The module system provided by Rust is, by most accounts, kind of weird.
But so is Rust in many ways, so it kind of makes sense. However it seems like a side-effect is that some concepts, like the module system, are particularly tricky to figure out.
There was recently a blog post linked on /r/rust, which I think does a really great job of explaining how it works (if you landed here looking for a tutorial, let me send you there instead!).
The conversation on Reddit got me thinking about why it's difficult to understand. People seem to have different opinions on it, and I think a lot of that might have to do with how much everyone's previous experience can vary when coming into the Rust ecosystem.
The Effect of Past Experiences
First of all, I'm going to make an assumption: that the vast majority of people coming into Rust right now, are not doing so with it as their first programming language. They most likely already work in another language, given that Rust is still relatively young. Rust is also, I think, rarely recommended as something one should try learning first.
This assumption is important, because that's what my first point is kind of based on.
No matter what you're learning, you are using your past experiences and accumulated knowledge to help you understand a concept, whether it's something completely novel or a "next step" of something else.
In the psychological sense, priming is "a phenomenon whereby exposure to one stimulus influences a response to a subsequent stimulus, without conscious guidance or intention".
For Rust, I see see at least two potential priming vectors.
The first, is the word "module" itself. In software development, "module" is a very overloaded term. That often means that one of the first things you have to do (mentally) when reading the docs, is disambiguate the word we use to describe a seriously central concept of Rust. Asking "what is a module?" is the kind of question that gets closed on Stack Overflow for being impossible to answer definitively.
This is a kind of example of priming (if you are a native English speaker; more on that in a second), except that you have been primed with what is essentially mush in my opinion. You know we're talking about a collection of code that is separate from the other modules (hopefully), and from there it's just a vague memory of every other kind of module you've ever encountered. Plus any other IRL-kinds of modules you can think of, even if only subconsciously.
I have no idea what it is like coming across terms like module, with English as a second language. I expect the effect is the same, since it's unlikely your last framework or language used anything other than the English word to describe the idea. And I'm also assuming priming works the same way for a "symbol" regardless of what language it's written in. Let me know if you can shed more light on this part!
As for the second vector, the Reddit discussion I linked also indicated that people didn't necessarily expect Rust's module system to be independent of the filesystem. In part, this was based on their previous experience in other languages. Sound familiar? đ
The Effect of Novel Jargon
In addition to using overly ambiguous language adopted from the aether of software engineering, Rust also makes use of its own novel or invented jargon to express ideas. This isn't a criticism of Rust in isolation -- a lot of (most?) software engineering terms are completely made up.
The novel jargon I'm talking about here, is the use of the word crate to describe a Rust package. Or is a crate a module, and the crate in a package? Who knows, unless you can make it through the extra cognitive effort I described earlier to parse the official Rust book. That, or you hope someone writes a well-worded tutorial.
I'm assuming they're called "crates" as a cutesy name derived from Cargo's name, or perhaps it's the reverse.
In either case, if you speak English you think of a crate as something that holds stuff in order to ship it (my internal monologue: "ohhhhh, now I get it!"). And they are managed with what is de facto known as a package manager, called Cargo. Ok, so far so good, as long as crate is a word that already means something to you. And identifying Cargo as a package manager was probably easy.
On packages and crates, the Rust book states:
A crate is a binary or library. The crate root is a source file that the Rust compiler starts from and makes up the root module of your crate (...). A package is one or more crates that provide a set of functionality.
Okay...
Let's look at just the first bit:
A crate is a binary or library. The crate root is a source file
On my first read (or more, maybe), I don't see the word root after the second use of crate. I'm still processing what I was just told a crate is, and then I take in another "a crate is" sentence. My brain immediately aborts. I've got two things a crate is, and none of them are what I expected -- a crate is a binary or library? I thought we installed crates with a package manager...making them packages?
A little further:
that the Rust compiler starts from and makes up the root module of your crate
This is the first place that the word module is used in this section, and it's got the modifier root. But I still don't know what an ordinary module is in this context yet, or a what a crate really is for that matter.
And finally:
A package is one or more crates that provide a set of functionality
Now we learn that a package is really multiple crates. That still doesn't fit what we were primed with, and the explanation hasn't made anything clearer.
I also have to point out how much work the words "a set of functionality" are doing. Speaking of ambiguity!
Altogether, there is quite of bit of jargon thrown at you "just" to learn how things are structured. And a lot of that jargon is pretty ambiguous.
The Solution Space
This isn't meant to be a roast of the Rust book authors. Technical writing is hard (and woefully undervalued as a profession, but that's another post). Overall the Rust book is extremely well written, and it's been useful nearly every day I've worked with Rust.
My overall point, is that I think a lot more care could be taken about the words and phrases that are selected to describe abstract concepts. Maybe not just inside the Rust community, but industry-wide. It may make communicating with each other easier!
Rust is difficult, so I think describing it is going to be more difficult in many cases. Unfortunately, I believe this may ultimately be a case of something requiring a bit more effort (than is maybe even possible right now). Either taking more time with documentation before it's released or dedicating more resources to it. Which is obviously tough, being a (mostly?) volunteer-run project.
The End
If you're still here, thank you! If you have any corrections, please reach out!
Credits
Cover Photo by Brunno Tozzo on Unsplash
Top comments (4)
I don't know what is so hard in Rust module system? Module is a single rust file, it can only exist within Crate. The latter is basically what other languages call a library, and is what you add to your project. You don't share Rust modules, you share crates. That's it
Unfortunately it's not quite so straightforward:
Take for example a file foo.rs:
Above, you have
foo.rs
defining a foo module AND a bar module--all within 1 file. The author is right, it is confusing for people to pick up.I was hoping the author would provide a clarifying succinct definition I could use to help new people "get" Rust's module system...
I didn't try to provide an explanation because I wasn't sure I could do any better than what I've seen out there already. If there's interest though, maybe it'd be worth giving it a shot!
I'll ping here if I post something :)
It's easy for me since I understood it :D