Pre-RFC: Documentation conventions

Now that I’m writing more than just the Guide, https://github.com/rust-lang/rust/issues/4361 and friends seem important. So I’ve written up a pre-RFC with some of these guidelines:

What do you think?

I’ve provided some commentary as comments on the commit diff.

Having doc guidelines seems right to me.

The section on alternate block ‘modifiers’ (not sure if this is the common term for these) should probably list the common ones use by Rust projects so people don’t have to guess.

The recommendation to use inline-links instead of citations is counter to what I often prefer, at least in standalone docs (because it’s easier to read the raw format).

If we’re going to encourage a documentation structure of ‘guide + guides (which seemingly need a disambiguating name) + API docs’ we may want to teach rustdoc specifically about this structure so that can produce output that is common across projects; likewise cargo should be able to produce this structure.

Presumably this is intended to be the go-to place for learning how to write Rust documentation. I know that PEP’s (e.g. PEP-8) are used for this purpose but we don’t have a precedent like that yet for RFC’s, and I want to make sure it is discoverable. It could also live with the main documentation - I’m not sure where the line is.

1 Like

Yeah, I’m not sure what the line is either, @brson.

I will say the reason I went with inline over end is because markdown doesn’t have footnote syntax. if it did, I would prefer it as well. Though maybe markdown’s [][] link style would work as psuedo-footnotes?

I found the comments about which sort of block comment to use and so on a little confusing. For example, the block example is not a doc comment, so it seems out of scope for this RFC. In general, formatting issues seem less important than guidelines that affect the structure of documentation or what it will look like after rustdoc (in other words, iiuc, the aim of this RFC is to ensure that rustdoc output across projects follows consistent conventions, not the source itself).

I may be alone in this, but I strongly prefer inner comments for documentation, and I strongly strongly prefer /*! */ to //!. Hence I would write something like:

fn foo() {
    /*!
     * Comment
     */
}

My reasoning is that, when reading the raw code, I want to see the fn name and signature first, and read the detailed comments later. Therefore, I prefer an inner comment. It also means the comment is indented inside of the thing it applies to. You could argue for using //! except that it provokes a “OH MY EYES MY EYES” reaction for me, particularly when repeating across multiple lines. Unfortunately, there are various cases where inner comments can’t be used (commenting fields in a struct, for example), so I could imagine preferring to always use /// for consistency.

Like brson, I prefer non-inline links because they are easier to read in the raw format. I don’t quite understand your comment re: footnotes – are you just saying that the raw notation doesn’t resemble the HTML output?

Some misc inconsistent style things I’ve pondered while prodding at API docs:

Tenses: “gets a reference to the map’s key” vs “get a reference to the map’s key”

Genericity/Specificity: “get a reference to this map’s key” vs “get a reference to a map’s key” vs “get a reference to the map’s key” vs “get a reference to the HashMap’s key” etc

Seemingly trivial/redundant things that need to be doc’d. e.g. if I have:

pub enum Entry {
    Vacant(VacantEntry),
    Occupied(OccupiedEntry),
}

pub struct VacantEntry { ... }
pub struct OccupiedEntry { ... }

I need to document all the types, and the individual variants. Should I duplicate descriptions of the variants on the structs, or should different concerns be addressed at different locations, or should one simply “redirect” the user to the other?

A reason to use // instead of /* */ is that the latter can interfere with commenting out large blocks of code (such as testing an idea without deleting everything).

/*
struct Foo;

// more stuff ...

fn foo() {
    /*! comment */ // <- BOOM
}

*/

The standard for that in the guidelines is

The summary line should be written in third person singular present indicative form. Basically, this means write "Returns" instead of "Return".

The behavior of the struct VacantEntry should (presumably) be documented under VacantEntry, and a reference to this as it pertains to the Entry struct should be documented under Entry. This is the only sane way to recommend documenting Enums in general - imagine an Enum with 50 variants; documenting the types contained in their variants as part of the Enum makes absolutely no sense.

Could you provide some concrete examples of the sort of thing that make a good “cross-cutting” guide? That section is a bit minimalist at the moment.

Ah, good catch! Missed that.

Rust still requires that the variants be documented individually (at least, I recall running into that at one point, maybe that's changed?), so what does one say about trivial wrapper variants? "See <WrappedType> for details"?

On Wed, Sep 17, 2014 at 07:09:38PM +0000, seanmonstar wrote:

/* ... */ comments can be nested, so I don’t think that’s a problem.

Good! Some thoughts:

If we want to only use //! why should we keep /!* */ at all? And what use does #[doc=""] and #[doc="";] have? See #6782.

Do we want to mention runnable examples through playground? See #9403.

Also we might want to standardize whether detailed descriptions and examples go on the type or on the module. See #14967.

Is it # Examples or # Example even if there is only a single example?

As a slight aside: what are the different rustdoc modifiers and where can I find them? should_fail for example.

I personally prefer

[some paper][]

[some paper]: http://www.foo.edu/something.pdf

over

[some paper](http://www.foo.edu/something.pdf)

They render the same but I find it a lot easier to read the source, especially if there are many long links.

You mention that the summary line should be written in third person form. Why not the rest as well?

As @brson said, I see this as a conventions RFC, which means it's more of a "This is how good Rust docs look like" than a specific kind of change to software.

[quote="nikomatsakis, post:5, topic:521, full:true"]I may be alone in this, but I strongly prefer inner comments for documentation, and I strongly strongly prefer /*! */ to //!. [/quote]

I'm just repeating our current guidelines here. I actually feel very much the opposite of you, but that doesn't matter unless we're looking to change the current convention.

[quote="nikomatsakis, post:5, topic:521, full:true"]Like brson, I prefer non-inline links because they are easier to read in the raw format. I don't quite understand your comment re: footnotes -- are you just saying that the raw notation doesn't resemble the HTML output? [/quote]

I'm saying that Markdown does not have a way to express footnotes, and so we would have to develop some sort of custom extension to enable them, if we wanted that as a guideline.

It's an implementation detail, the comments de-sugar to the attributes.

Do we want to mention runnable examples through playground? See #9403.

Rustdoc already inserts these links where appropriate.

Also we might want to standardize whether detailed descriptions and examples go on the type or on the module. See #14967.

Yes, this is a big thing I left out. Good call.

Is it # Examples or # Example even if there is only a single example?

Probably should always be examples for tooling purposes, I'd guess.

I just want to say that the rust.vim scripts help a lot with the usability of line comments over block comments. @seanmonstar makes a good argument for line comments instead of block, but having to repeatedly adjust your text to be properly formatted and include /// or //! at the start of every line can make writing documentation a pain in the ass, and rust.vim’s automatic formatting for new and joined lines is the only reason I’ve favored it over block comments.

Also, for what it’s worth, I’m for third-person form (“sorts a list”) over first-person (“sort a list”). It’s much more readable IMO.

Doc-only modules, e.g. trans/doc.rs and borrowck/doc.rs legitimately use /*! ... */ comments. By the way, I prefer /// or //! for documenting other items.

I wasn't advocating any change to software, I was just saying that your interpretation of "look like", I suppose, includes how the docs look in the original source, whereas my interpretation includes only the formatted output.

I agree that footnote support in Markdown would be nice, but I don't really see how it's relevant to the question of how best to format a link in the raw source.

To clarify what I meant in my reply, let me try again. All I was saying is that suggestions like "use third-person form", making it clear what sorts of items require documentation and which do not, or specifying sections like # Parameters or what have you affect the final rendered output and can be helpful for ensuring a consistent "look and feel" to Rust documentation. On the other hand, the details of how someone wrote their markdown links or which kind of comment they chose do not affect the final output. I am not saying they are necessarily out of scope, but they may be more appropriate for a general coding conventions document, versus something specific to writing docs (or one could imagine the general coding conventions document forwarding to this one).

Since my by e-mail reply failed, I just wanted to point out that this is generally not an issue for documentation comments specifically. That is, if I want to comment out a large block of code, I always use // for many reasons (it's very obvious that things are commented out, for one thing!). (Also, /* and */ can be nested, but I still think // is better for commenting out a big block of code temporarily.)