Document 'sigils' in std docs?

I do not understand this criticism. "I want to learn all functions in libstd" is also usually not what people do, and yet we have a list of all these functions in the reference. The point of the libstd ref is NOT to be read like a novel, but to be used when you want to find a specific thing that you need or that occurs in the code you read. Having a list of sigils there makes perfect sense to me: When I read code that calls splice, I might want to find out through the docs what that function does; when I see code that contains a ? I might also want to go to the docs and figure out what it does.

6 Likes

Because I thought it would be nice to have them so I added them. :slight_smile:

3 Likes

Second draft.

Planned next steps on my side:

  • For each entry I want to create a bullet list of things I consider writing
  • Move that list to a repo
  • Start discussion how that list should best be added for real (e.g., #[doc(sigil = "...")]?)

I’ll post more once I made progress on that.

Feedback in the meantime is still welcome.

3 Likes

I’m not a big fan of adding sigils in the doc directly. They don’t render really nicely and it’ll very likely but a nightmare for the doc search. Having a book dedicated to it seems like a better idea. What do you think of it?

1 Like

Some unsorted thoughts:

  • I think they probably need to be structured as “sigil | name | description” in the overview where “sigil” is the visually recognizable token with minimal fluff, “name” is the linkable canonical name of that construct, and “description” the typical one-liner.

  • Because they are hard to search I would like to expose them rather prominently

  • I feel they should go wherever “Keywords” go, since the documentation use case is the same to me w.r.t. browsing, ad-hoc look up and information density / target audience.

  • I would love to see them being fuzzy-searchable in the docs search bar. That would probably require a bit of advanced JavaScript edit-distance logic, but in the end, being able to search for <'a, T, R> and getting the suggestions “Lifetimes” and “Type Parameters” would be awesome.

While I generally don’t feel very strongly putting them into std docs, I am a bit concerned not putting them there as of today for use case reasons (compare above); and for audience reasons w.r.t the rest of the docs. In particular:

  • Simply speaking, I think there is no good alternative to put them. The “Section 1” books (Learn Rust) are too verbose for a “late workday I need to get this sorted out” situation. Conversely, the “Section 3” books (Master Rust; The Reference in particular) are trying to be too “correct” (IMO) to be of practical use in the same situation. I think this is why I mostly end up having std docs open while I code.

  • Now there might be the case for another “Section 2” book. However, it probably shouldn’t have sigils alone. At least Keywords should be covered, but what else? Maybe “Pragmatic Rust Anatomy”?

Unless that is solved I fear it might end up being a very thin book, which in turn will make it less likely to be opened, remembered and its content being found when you actually need it.

tl;dr: Not saying sigils should go inside, but they should be next to where “Keywords” are. And both of them should go where “It’s Friday afternoon and I’m on a deadline”-developers will easily find and use them.

1 Like

I very much prefer a “Section 2” “Rust cheat sheet” over more std-specific rustdoc extensions.

One issue I’m seeing is that a beginner might not even be aware that the sigils are explained in the std docs and thus not bother searching for them. For that reason, they probably should be listed somewhat prominently – maybe even above the Keywords section.

Regarding the second draft, I’ve got two comments:

  1. Since the page for the keyword for only explains for for-loops, would it make sense to also add an entry for for<'a>? Right now, HRTBs are not only a niche use-case, but information on them is also hard to find.
  2. The struct-creation sigil is extremely packed, essentially referencing three different concepts. Maybe it makes sense to split it up into three separate entries? Alternatively, it might be enough to split out S { ..s }, the functional record update syntax.
1 Like

I think I’m going to rename this thread to “An Unexpected Journey” …

It took much longer than expected to find something that actually looks good and feels practical. I could probably write a whole post about what I tried, but in short:

  • std docs sigil list - How it started out. Didn’t fly because of table length, and ‘dependency-hell’ between similar symbols. There was no “clear cut” way to segment symbols nicely into practical pages without having ugly tables, or messy entries.
  • Practical Handbook - In retrospect a stupid idea that unconsciously emerged as I was going down the rabbit hole of exploring the “audience x content x design” space. Tried a few variants, but they had too much overlap with the existing docs. Not saying a “practical handbook” wouldn’t be practical, but it’s totally outside the “one guy, couple of weekends” scope.
  • Structured Cheat Sheet – Eventually settled on that one; a single-page document with links to all other docs but slightly more structured than a single list. Tries to be practical by not repeating anything already said in the other documents, but linking “high” and “low” (i.e., to Book and Nomicon alike) instead.

Design-wise I realized I’m not happy with the default mdBook styles and had to take a few iterations tweaking them. Things I eventually changed:

  • Switched from hljs to prism, which gave much nicer inline code blocks. The default blocks (e.g., in the Book’s appendix) are very hard skim.
  • Manually aligned tables to avoid row ‘fluttering’; same reasons as above.

Current version

Rendered / Source

Next steps:

  • I would like to hear your feedback, whether you think this is “helpful” and “looks good”. Other feedback is welcome as well, but I haven’t taken the time to sanity check the document.
  • I would then finish linking the “Sigils” and “Keywords” sections, similar to the ones already done.

However, I am also wondering if this is still internals material. The original plan was to check if “sigils” fit into std docs, but now this seems to become more work and a document on its own. I would love Rust to have a cheat sheet like this, but I don’t want to push something into docs for which there is no ask. In that case I’d rather wrap this up, host is somewhere, and let it live its life. Any thoughts?

4 Likes

This looks to me like it’d make a great appendix in The Book. It’s relatively concise, intuitive, high-level, and stuff that should never become outdated in an incorrect way (as opposed to merely incomplete), but everything it refers to needs a more comprehensive explanation elsewhere.

On the other hand, The Book already has appendices that seem to overlap with… almost all of it?

Actually, now that I’m looking at these side-by-side, it feels like you’ve essentially rewritten these two appendices. Which isn’t necessarily a bad thing, e.g. I think the official “Operators” table includes too much stuff and your version has found a more helpful way to split that up.

The Memory Layout section at the end feels like a completely different document though. Personally, I don’t think it should even be a single chart (does anyone actually find a chart like this a useful reference when programming?) but rather the individual diagrams within it should each show up in the bits and pieces of The Book and std docs that talk about individual containers/smart pointers (if they don’t already).

Actually, now that I’m looking at these side-by-side, it feels like you’ve essentially rewritten these two appendices. Which isn’t necessarily a bad thing, e.g. I think the official “Operators” table includes too much stuff and your version has found a more helpful way to split that up.

The Memory Layout section at the end feels like a completely different document though.

Yes, I merged the previous "sigil lists" with appendix A, B and the memory chart into one document and then edited it for (what I believe is improved) clarity.

I don’t think it should even be a single chart (does anyone actually find a chart like this a useful reference when programming?)

I love that chart but I agree it could be split up. I wish there were similar visual guides for lifetimes, trait bounds and macros-by-example (though macro_railroad is a good alternative).

I'm struggling to think of any "visual" aspect to lifetimes and trait bounds (in their full generality; not just pedagogical simplifcations like "lifetime = pair of curly braces" that fall apart with NLL, HRTB, etc). Did you have any ideas here?

Nice summary. I think a “cheat sheet” like this will be most useful to people coming from another imperative language, such as the C family. I also feel that a Memory Layout section will be helpful to such people, so long as they’re told that it’s examples are not the only possibilities.

Two observations: In the “Entity Creation & Usage” section, don’t you have the slice-like indexing for Range and RangeFull interchanged? Also, I feel that the “Common Operators” section should include Add/AddAssign, Sub/SubAssign, Mul/MulAssign, Rem/RemAssign, BitAnd/BitAndAssign and logical AND.

1 Like

I wanted to post an update and say 'thanks a lot!' to everyone giving feedback.

Although putting a format like this into the official docs didn't work out, I wanted to see it being wrapped up. The result therefore now lives under cheats.rs.

I'm happy to collect more feedback in the repo, my plan to let it live there for a bit and see what the resonance is (and where the rest of the docs go).


And to reply to some of the previous comments:

I’m struggling to think of any “visual” aspect to lifetimes and trait bounds (in their full generality; not just pedagogical simplifcations like “lifetime = pair of curly braces” that fall apart with NLL, HRTB, etc). Did you have any ideas here?

I linked one about lifetimes in the current version. I think it's a start, but (like the container cheat sheet) I would prefer more complex examples. Right now it's more of a vague feeling that it should be possible to do that, although I don't know exactly how.

Two observations: In the “Entity Creation & Usage” section, don’t you have the slice-like indexing for Range and RangeFull interchanged?

Yes, thanks, fixed it!

Also, I feel that the “Common Operators” section should include Add/AddAssign, Sub/SubAssign, Mul/MulAssign, Rem/RemAssign, BitAnd/BitAndAssign and logical AND.

I tried this with a few designs, but always felt the common operators were cluttering the more interesting bits. I now went the opposite and removed that section completely and just point at std::ops.

4 Likes

Gorgeous! You should get this into This Week in Rust.

2 Likes

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