Can the standard library please ban `println!` and similar functions from doctests?

Sometimes APIs make weak/fuzzy/subject-to-change promises in the prose, e.g. Debug impls. Using println! in the examples matches such prose because you'll get some output while leaving the exact contents unspecified.

And sometimes it's the order in which things happen that's relevant, e.g. when talking about threads or destructors. That is more easily demonstrated with println!. Writing those as asserting tests is far more gnarly.

I like this. Rustdoc could also add the captured output to the rendered code block, similarly to how it displays a tooltip for examples marked should_panic.

Rustdoc does not run tests during doc generation, so it could include the expected output, but not prove that the test is actually passing (which I guess is similar to the existing should-panic/no-compile annotations that assume they are correct).

I feel like the whole point of the documentation example with the print! in a call to .map is not at all to demonstrate the precise behavior of the particular code in question. Instead, it's point is actually to talk about a whole pattern of code, the pattern being ITERATOR.map(|VAR| EFFECTFUL_ACTION(VAR));, and it explains that this pattern of code will not have the desired effect and that for VAR in ITERATOR { EFFECTFUL_ACTION(VAR) } should be used instead.

Since writing this in full generality, with metavariables for the iterator, variable name, and action, would probably be too abstract and thus confusing, some minimal concrete examples are used instead and they implicitly stand for the general case. All of 0..5, x, and print!("{x}") are short, non confusing, trivially simple to understand, and very clearly an instance of the thing they stand for, namely, an iterator, a variable, and an effectful action, respectively.

Any additional complication added to make the completely uninteresting behavior of this code more machine-testable would only obfuscate this intent. Especially if the approaches suggested above were taken, introducing additional mutable variables into the context and modifying them in the .map and the loop, that would quickly and unnecessarily overcomplicate things. Suddenly, you would need to start thinking about the behavior of some loop with mutable state, which would take the focus from the main point of this example.

14 Likes

Suggestion: Instead of println!, use nuke_mars(). Make it clear that it has side effects :wink:

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