Should we keep Including 'obvious' imports in code examples?

I’m a newcomer to Rust but certainly not to programming, so here’s my feedback :smiley:

I learn primarily by examples and by copying/pasting examples to play with. To find that an example doesn’t compile is discouraging as it heavily slows down the compile-run-modify feedback loop, which is already slow enough being a non-REPL language.

The missing main() confused me at first: seeing expressions in what appears to be the outer-most scope of a file is initially misleading.

Omitting “use” would be much worse, as trying to locate the appropriate symbol in the API reference is not trivial either - so many things appear under different namespaces: which is the “right” one?

I find it very unintuitive to see code snippets that, as a beginner, are not obviously missing something. The more experience you gain, the more obvious what is omitted, of course.

In my opinion, expandable examples would be ideal, hiding main() and "use"s by default, so long as the full example is available on expansion.

5 Likes

[the feedback loop ...] is already slow enough being a non-REPL language.

Perhaps rusti might help? It's a work in progress, though.

(Edit: rusti, not rustic. Damn autocorrect)

1 Like

I really don’t think every piece of example code in the docs should be a compilable Rust program. I think the cost of everyone ever having to dig through the boilerplate is greater than the gain for users who don’t understand the role of main() or Rust’s import system (who will, after learning these concepts, now have to dig through boilerplate).

I don’t think an example which includes all the necessary components, without explaining why, is particularly more helpful than the compiler errors that will ensue from attempting to compile let map = BTreeMap::new();. If those compiler errors aren’t helpful enough, that should be improved. (I know import errors are very helpful, usually proposing the correct import to add).

There’s a difference between:

  1. At the function/method level, importing the crate/type which defines the function/method documented. I think these imports should be hidden.

  2. At the type level, importing the type itself for high-level example code. I think these imports should be visible.

  3. Importing another type which is fundamental to how a function/method works (e.g. the type of one of its parameters). I could go either way on whether or not these should be visible.

  4. Importing types that are needed for the example code to work but not relevant to what is actually being documented. These example codes should be rewritten to use prelude included types unless the example is specifically to document how to use this item to manipulate those types and not the general documentation for this item, in which case probably do import.

I expect that by the time they look stuff up, they would already know of the use keyword. That is, they would already have read some basic tutorial.

This is demonstrably not true, at least for people that swing by #rust, and also, see things like A Simple Web App in Rust, Part 1 and the two follow-ups. People often just try stuff out without reading tutorials.

That doesn't mean we have to cater to that audience, but they do exist, and my intuition says in very large numers. The book is 250 pages, people are going to skim at the very least.

It's not because you know how to use the keyword use that you know what you should import with it. It's not always trivial to know which modules you should import for your code to work, even for people who are comfortable with programming in other languages.

When you learn a new language you have to familiarize yourself with so many new things (keywords, concepts, std, best practices, ...) some people integrate it faster than others, but as a new language we should strive to make it as easy as possible for everyone to adopt rust.

Beginners are not going to read the whole book before they start experimenting, that is even more true for people who already have a programming background. The urge of writing something that works as fast as possible is very real :wink: And I think it's a good learning method. You can't expect people to first read through 250 pages of syntax and concepts before they start to experiment...

People should not have to integrate every concept of rust before being able to use the language. For comparison, when you learn C, you don't have to learn how to use pointers right away. You can perfectly write simple programs without it. Of course, somewhere along the way the need for that specific feature will increase and you will eventually learn it. Making you wonder how you lived without it afterwards.

But being able to learn parts of the language at your own pace makes the learning curve less steep, which is, in my opinion, important for Rust because it tries to target a really broad audience.


To come back to the presence of use in the docs, I think it should be present! Learning through repetition (experience) is the most important form of learning in the programming world. Having one more repetition of use (or any other concept for that matter) in the docs isn't going to kill anyone, on the contrary it makes beginners learn quicker.

Experienced users lose a little convenience because of the "noise" but beginners lose sometimes hours just because they didn't think about some import. Not because they didn't know how..., but just because there is so much else that could go wrong for them, they forget it could be as simple as an import error... (I know I'm exaggerating :blush: but still..)

I am however in favor of collapsed examples and info blocks (when clearly indicated) to make it easier to quickly find the section that you need and expand just that.

1 Like

Rarely in my life too much documentation was a problem. If the code needs use X to compile, the use X should be there.

If you want to make docs look better, than make it possible to “fold/unfold” the lengthy and noisy use sections. This way while glancing through documentation, they won’t obstruct the view, but once a person wants to copy&paste them, “show full source” button can be clicked and complete example reveled.

2 Likes

When I was starting the obvious imports weren't obvious to me at all.

I would be fine with omitting them only if rustc suggested relevant use statement on error, e.g.:

Path::new("foo")

Use of undeclared type or module Path
hint: use std::path::Path

3 Likes

rustc already does this for traits, it would be very nice if it did it for types as well.

Some types like Error will unfortunately give several results.

Even then a good ordering will be really helpful. I know some startup in Germany who have built the Eclipse Code Recommenders 2.0 engine; basically they use statistics to guess the most likely type/methods/etc. based on the surrounding code.

We already have inference, which may help, too.

The lack of imports is what I dislike about Java snippets floating around, therefore about Java itself.

1 Like

I expect that by the time they look stuff up, they would already know of the use keyword. That is, they would already have read some basic tutorial.

Unfortunately, this isn't necessarily the case. I'm personally very new to the Rust language, and although I've read the introductory tutorials and seen the use syntax, I have not yet memorized it.

I appreciate how many code examples are available in the Rust docs and tutorial because seeing the patterns of a small, working Rust program over and over again help me learn what's universal to all programs in the language vs what's specific to any individual example. This type of pattern recognition is easiest when every example is an independent, working program.

Additionally, I often find examples in the documentation via a search engine, which drops me straight into the sample code without the context of having read several pages of background information earlier in the tutorial. Although it'd be ideal for new users to read every tutorial thoroughly and memorize its concepts before trying to write anything, many people learn by jumping in and trying to build something before reading all the docs. Since sample code will often be found to solve a specific problem rather than encountered in the context of its surrounding documentation, I feel that the benefits of making each sample program work on its own outweigh the drawbacks of being slightly more verbose.

Regardless of what the decision is on this particular issue, having a documentation policy would be awesome! It would be especially helpful for people who want to contribute to the language by writing and editing documentation, and show that the community values non-code contributions.

3 Likes

I agree with this: at this point I don’t have confusion with std very often, but I find it much easier to get started with a random library off crates.io if the imports in the docs are spelled out.

2 Likes

another vote for keeping the imports visible

I am in favor of keeping the use statements. I often played import whack-a-mole when I was starting out. I really did not understand the module system that well. I think time to first successful compile is something we should strive for.

1 Like

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