# Define rules for summarizing traits and modules

**URL:** <https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160>\
**Category:** libs\
**Created:** [August 10, 2021, 5:01am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160 "2021-08-10T05:01:00Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [August 10, 2021, 5:01am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/1 "2021-08-10T05:01:01Z")

</div>

The [1574-more-api-documentation-conventions - The Rust RFC Book](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text) mostly focuses on documenting functions. Modules and traits don't get the same attention.

For example, for traits:

from [Error in std::error - Rust](https://doc.rust-lang.org/std/error/trait.Error.html)

> `Error` is a trait representing the basic expectations for error values, i.e., values of type `E` in [`Result<T, E>`](https://doc.rust-lang.org/std/result/enum.Result.html).

from [Read in std::io - Rust](https://doc.rust-lang.org/std/io/trait.Read.html)

> The `Read` trait allows for reading bytes from a source.

from [ToString in std::string - Rust](https://doc.rust-lang.org/std/string/trait.ToString.html)

> A trait for converting a value to a `String` .

from [Add in std::ops - Rust](https://doc.rust-lang.org/std/ops/trait.Add.html)

> The addition operator `+` .

The first two are consistent with eachother, but it's redundant. The 3rd starts with "A trait", which is still a bit redundant. The 4th goes straight for "The addition operator". None of these seem like particularly good examples of how to write trait docs. The traits in std::convert, aside from AsRef/AsMut which are consistent with eachother, also seem like quite a ride: [std::convert - Rust](https://doc.rust-lang.org/std/convert/index.html#traits)

Module docs also have similar consistency issues. Also, as a side-note, [std::iter - Rust](https://doc.rust-lang.org/std/iter/index.html) says:

> Composable external iteration.

However, we've had [Iterator in std::iter - Rust](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.for_each) and friends for a while now, and those provide internal iteration. (oh yeah and `Iterator` uses "An interface" as opposed to "A trait"!)

Would it be a bad idea to suggest defining some more conventions about trait and module documentation? Ppl do tend to use std doc guidelines as a starting point for writing their own crate docs, and at least to us it looks like that falls short for traits and modules.

---

<div class="post-metadata">

**Author:** ![H2CO3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/h2co3/32/2849_2.png) [@H2CO3](https://internals.rust-lang.org/u/H2CO3)\
**Post date:** [August 10, 2021, 5:10am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/2 "2021-08-10T05:10:15Z")

</div>

> [@Soni](#):
>
> we've had [Iterator in std::iter - Rust](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.for_each) and friends for a while now, and those provide internal iteration.

From what I can tell, they don't. You have to explicitly consume an iterator (by calling next on it, or putting it in a for loop, etc.) one-by-one in order to receive its elements. That sounds like external iteration to me.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [August 10, 2021, 6:14am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/3 "2021-08-10T06:14:55Z")

</div>

Yeah, "internal iteration" is more akin to a generator imo.

---

<div class="post-metadata">

**Author:** ![semicoleon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/semicoleon/32/7397_2.png) [@semicoleon](https://internals.rust-lang.org/u/semicoleon)\
**Post date:** [August 10, 2021, 8:14am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/4 "2021-08-10T08:14:11Z")

</div>

Documenting interface types is something I find myself stumbling over in any language, so I would love to have some guidelines in place for traits if only so I don't have to think about the phrasing every single time.

I have tentatively settled on opening trait docs by describing the kinds of types that implement the trait rather than the trait.

`Read`

> A source that allows for reading bytes.

`ToString`

> A value that can be converted to a `String`.

`Add`

> A value that can be added via the addition operator `+` .

`Error` might take some more dramatic rephrasing to fit.

I'm not overly attached to this style (and these examples could probably be improved regardless) but it at least feels less repetitive.

I'm not entirely sure how standardizing module documentation would work. In my experience module docs vary wildly, sometimes being closer to a wiki page than code level documentation. Perhaps there could be some guidelines for common cases where the documentation is short and describes the contents of the module?

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [August 10, 2021, 3:06pm UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/5 "2021-08-10T15:06:49Z")

</div>

> [@semicoleon](#):
>
> I'm not entirely sure how standardizing module documentation would work. In my experience module docs vary wildly, sometimes being closer to a wiki page than code level documentation. Perhaps there could be some guidelines for common cases where the documentation is short and describes the contents of the module?

Well, at least the summary (the first line, which shows up in module listings and search and whatnot) could have some guidelines. We're not sure how important it is to make those have a consistent format across modules, but we think it would be helpful to guide users who're writing their own docs.

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbrubeck/32/174_2.png) [@mbrubeck](https://internals.rust-lang.org/u/mbrubeck)\
**Post date:** [August 10, 2021, 3:45pm UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/6 "2021-08-10T15:45:19Z")

</div>

It's not clear from the auto-generated link text, but the link goes to `Iterator::for_each`, which allows internal iteration if the caller and the iterator both opt into it.

---

<div class="post-metadata">

**Author:** ![infogulch](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/infogulch/32/4912_2.png) [@infogulch](https://internals.rust-lang.org/u/infogulch)\
**Post date:** [August 12, 2021, 1:45am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/7 "2021-08-12T01:45:42Z")

</div>

Interesting, they seem to finish the sentence:

> A type that implements this trait is...

> > A source that allows for reading bytes.
> 
> > A value that can be converted to a `String`.
> 
> > A value that can be added via the addition operator `+` .

Yeah seems to fit.

I like this model because it has the same form as the "commit message" pattern, which is something like `A good commit message finishes the sentence: "Applying this commit will..."`. Not trying to start a bikeshed on commit message phrasing strategies 😅, I just thought this was kinda similar.

So then I guess the question is what is the correct start of the sentence that the summary should finish? Is there something better than "A type that implements this trait is..."?

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [August 12, 2021, 2:25am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/8 "2021-08-12T02:25:15Z")

</div>

One wrinkle to that way of wording the trait docs is the naming convention. Traits are ideally named by the action they provide, rather than the thing that they are.

E.g. we have `Read` (not `Input`, `Reader`) and `Write` (not `Output`, `Writer`). We have `Collect` (not `Collection`). Generally, `-able` would be considered a subpar trait name per standard name conventions.

This isn't perfectly followed -- `Iterator`, not `Iterate`; `Future`, not `Await`; `Fn`, not `Call` -- but it's a general guideline that `trait`s are functionality/verbs, and `structs` are things/nouns.

I definitely like the way of presenting the "short first sentence fragment" conventions as "finishes this sentence". It also would implicitly answer the case problem I always run into with e.g. function documentation ("do X" vs "does X") based on the beginning fragment.

---

<div class="post-metadata">

**Author:** ![semicoleon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/semicoleon/32/7397_2.png) [@semicoleon](https://internals.rust-lang.org/u/semicoleon)\
**Post date:** [August 12, 2021, 2:47am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/9 "2021-08-12T02:47:40Z")

</div>

> [@CAD97](#):
>
> One wrinkle to that way of wording the trait docs is the naming convention. Traits are ideally named by the action they provide, rather than the thing that they are.

Hmm I see what you mean, "A `Read` is a source that allows for reading bytes" is awkward. Is that how people would read the docs on first glance though? If the model is "a fragment that finishes this sentence" people would presumably catch on fairly quickly if there was any consistency across the standard library.

---

<div class="post-metadata">

**Author:** ![infogulch](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/infogulch/32/4912_2.png) [@infogulch](https://internals.rust-lang.org/u/infogulch)\
**Post date:** [August 12, 2021, 4:17am UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/10 "2021-08-12T04:17:59Z")

</div>

The naming inconsistency is a reasonable concern. Not that the inconsistency is invalid -- there are many reasons for a name besides "would make documentation follow a nice pattern" 😆 Commit messages don't really have this problem because they aren't subject to interpretation in multiple external contexts.

With that in mind there's nothing saying that the "sentence prefix" _must_ be omitted, you could always just spell it out. This would trade a ittle bit of repetition at the beginning of most summaries for a bit more flexibility when a slightly different phrasing is warranted.

> A type implementing `Read` is **a source that allows reading bytes**.

> A type implementing `Write` is **a sink that allows writing bytes**.

> A type implementing `ToString` is **convertible to a `String`**.

> A type implementing `Add` **can be added via the addition operator `+`**.

> A type implementing `Iterator` **enables external iteration of a sequence of elements**.

> A type implementing `Future` **represents an asynchronous operation**.

> A type implementing `Fn` **can be called with an immutable receiver**.

Here we use that flexibility in order to construct a complete sentence that incorporates the trait name and even references "A type" in the case of `ToString`. I used the verbs `is`, `is a`, `can be`, `enables`, `represents`. I could follow reasonable arguments for three derivations of the above summaries:

1. The whole quoted sentence. Extremely clear. The prefix clearly indicates that it's a trait. A bit long. Somewhat repetitive (though you don't typically read them all in a row like this).
2. The suffix starting from the name of the type. Still a complete sentence, loses the unambiguous indication that it refers to a trait.
3. Just the bolded sections. Shortest. Not a sentence anymore. Could be harder to parse without the implied context of the prefix. Phrasing ends up a little awkward.

I think my favorite is 2. I can understand balking at repeating the name of the type in the summary, though it [works great for Go](https://blog.golang.org/godoc) (e.g. [template](https://pkg.go.dev/text/template#pkg-functions)), where the recommendation is `this comment is a complete sentence that begins with the name of the element it describes`, which is regular enough that it's even checked by default in linters.

It might be worth enumerating potential use-cases / contexts that this summary could be used. Obviously while reading the code or generated docs pages, but it could also be used in an IDE tooltip, etc.

---

<div class="post-metadata">

**Author:** ![mbartlett](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbartlett/32/8691_2.png) [@mbartlett](https://internals.rust-lang.org/u/mbartlett)\
**Post date:** [August 12, 2021, 2:35pm UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/11 "2021-08-12T14:35:53Z")

</div>

What about `Trait` lets you...?

> `Read` lets you read bytes from a source.

> `Add` lets you add values together with `+`.

> `Iterator` lets you iterate values with a `for` loop.

> `Sync` lets you access values from multiple threads at once.

> `OsStringExt` lets you use additional methods on `OsString`.

Or even if you don't mention the trait name:

> Lets you...

---

<div class="post-metadata">

**Author:** ![semicoleon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/semicoleon/32/7397_2.png) [@semicoleon](https://internals.rust-lang.org/u/semicoleon)\
**Post date:** [August 12, 2021, 3:18pm UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/12 "2021-08-12T15:18:36Z")

</div>

> [@infogulch](#):
>
> though you don't typically read them all in a row like this

There's actually a pretty important context where you _are_ likely to read a bunch of trait summaries in a row: the module summary pages rustdoc generates. Here the trait name is immediately to the left of the trait summary. This makes any amount of (leading) repetition between traits stick out, and at least in my opinion harder to read. It also means including the type name looks a little silly, though that isn't actually a problem for readability the same way an identical prefix would be.

Skimming the [std::io module docs](https://doc.rust-lang.org/std/io/index.html) both options 1 and 2 would make trait summaries stick out compared to the docs for the other kinds of items (`Cursor` and `BufReader` being the only structs to include the name in the summary)

Given that rustdoc is so widely used I think optimizing summaries for this specific context would be reasonable.

We could also consider changing rustdoc to remove some set of prefixes (such as the type name) when rendering the summary pages, though there are a whole bunch of pitfalls there.

---

<div class="post-metadata">

**Author:** ![Mokuz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mokuz/32/7225_2.png) [@Mokuz](https://internals.rust-lang.org/u/Mokuz)\
**Post date:** [August 12, 2021, 3:30pm UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/13 "2021-08-12T15:30:17Z")

</div>

+1 for not reapeating the trait name if possible

`BufRead` A type of Reader which has an internal buffer, allowing it to perform extra ways of reading.

`Read` Allows for reading bytes from a source.

`Seek` Provides a cursor which can be moved within a stream of bytes.

`Write` Allows for writing bytes into a sink.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [November 10, 2021, 3:31pm UTC](https://internals.rust-lang.org/t/define-rules-for-summarizing-traits-and-modules/15160/14 "2021-11-10T15:31:16Z")

</div>

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