Hacker News new | past | comments | ask | show | jobs | submit login

One of the things that made me so excited about Rust when I first used it was the capabilities of the Rustdoc system. The built in examples that are also unit tests, the ease of just using markdown... and now the linking is even simpler. It’s one of my favorite things about the language, and I think is why so many crates have such good documentation, because it’s easy to do. (and it’s tested and validated so you know it’s right!)



Not directly related, but when I was learning programming back in highschool (before the Internet) what made it easy was the built in help in Turbo Pascal. You could press F1 over any function or keyword and you were given a detailed description and example of usage. Learning C later using the K&R book and Google was a huge downgrade. Even today I think that language help built into the IDE should be a basic functionality.


In vim if you press K it will bring up the man page for the word under your cursor. It was very useful when learning C, considering that most libc functions have helpful man pages.


Note for people trying this at home, vim is case sensitive.

I still regularly use this feature to look up libc and other things. You can also type 2K to go to ‘man 2’, or 3K to go to ‘man 3’ etc.


And for the sake of completeness, it is not just for man pages either. vim simply calls 'keywordprg' with the word under the cursor, so you can use whatever you feel like. Open a browser tab on your favourite documentation, display an ERD, pop open a picture of a kitten, …

Many filetype plugins come with pre-configured 'keywordprg' settings. Including some non-programming filetypes like git which will execute `git show <word>`, which is great if you're the type of person who often references commits in other commit messages.


TIL. This will make this feature even more useful than I already found it.


I've seen that with Delphi. The unique factor was that the examples were not a basic call of the function but an actual real world practical sample that usually solved the problem one was looking for.


I was a Delphi programmer for a few years, professionally, when it first came out in the 90s. I worked with their developer products (and for Borland directly on Delphi/Kylix/C++Builder, eventually) until the mid-2000s. I've never seen the match of Borland's docs, before or since, particularly as integrated with the IDE's coding features.

There are a number of programming languages and APIs with excellent documentation, but theirs were above and beyond.


The Delphi IDE help was good but the printed Delphi manuals were just outstanding. I have fond memories of learning much through those manuals.


I had forgotten the “brick” you used to buy with a few CDs (or floppies) and a whole stack of books.

Things sure were heavy before the internet got fast.


I have them in print still, including the MS-DOS ones (TP), if you don't have them any longer, they are available at bitsavers.



This is done quite nicely with clojuredocs being intergrated into Cursive / Intellij.

I hover over a Clojure function in INtelliJ and I get a pop up of the clojuredocs with description and example usages for that function.

It's great and I don't know why more IDE's don't do this. Why isn't VS linked to the MSDN for C# / .NET ? SO I can get the information for that function / class / library etc straight in my IDE!


Bringing it back, this works great with Rust and VSCode and rust-analyzer: Any function in any crate shows its doc comment complete with markdown formatting when you hover over it.


And you can assign a hotkey to open the docs in the browser for the symbol under the cursor.


This is one of the things I love about Mathematica, it has a lot of documentation about every keyword and function that you can open with F1.


You could do the same with C in Visual Studio for at least 15 years now


That requires an internet connection and opens a page in your browser.


Nope, because one would install the MSDN documentation locally from the bundled CDs and use Windows help infrastructure.

The Web version came much later.


Which means that currently it requires an internet connection and opens a page in your browser.



Have you actually tried that? I just installed it and it's just a buch of help files that link to the web. F1 continues to work the same way, bringing up websites, often useless ones like this one for a for loop:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.codean...


Have you installed the Help Viewer and configured as advised?


I got it working now, but it's still often giving nonsensical answers for simple queries like a for loop.


I've seen this with bpython


I also like Rustdoc, using markdown and the new linking improvements. It's much better than learning yet another DSL. However, there's one thing I find annoying, and that's the lack of a structure for parameters.

Following the `# Arguments:` convention is redundant (I get it's petty, but I'm annoyed every time I write it), but more than that it's error-prone and limiting. Because arguments names are just a convention that's not strictly enforced, it's not automatically checking the naming is correct, and it limits the ability of tools like cbindgen and flapigen (love them both) to transform param specific docs.


I've seen the argument (not sure if this factored into rustdoc's design or if it's just someone's opinion) that structured per-parameter docs tend toward useless boilerplate, e.g. "foo: a foo object," while a holistic description of the function itself is easier to make useful.


I don't know if it really factored into rustdoc's design since it was already built when I came to Rust, but when I was part of the team responsible for rustdoc, I did object to suggestions we do this on that basis.

As well as, extending the underlying language (that is, markdown) has to be done really carefully, and so being conservative with how it's done matters. This was a huge part of figuring out the design of intra-doc links in the first place.

(All of this great work is being done by others, and I don't know what their opinion on it really is, so my opinion being -1 doesn't really matter these days.)


Agreed, I find per-parameter docs useful in dynamic languages such as python, or to a lesser extent useful when the type system is weaker (in C), but in Rust I seldom find them useful. This can be useful to express constraints not present in the type system, for instance `fn matmul(a: Matrix<f64>, b: Matrix<f64>) -> Matrix<f64>` will benefit from a documentation describing the constraints and guarantees on the number of rows and cols of each matrix, since this cannot be expressed in the type system (yet).


I also love that it is consistent between projects. The fact that I can just go to https://docs.rs/chrono for any public project and have a consistent interface for reading and navigating is huge.

Of course this is somewhat fickle and makes competing documentation generations harder to get started but as a user when rustdoc is really good it is a nice benifit.


Yeah, this is great. Julia has it since a couple years in the Documenter package. Plus basic Markdown rendering in the REPL when you hit `?func`. Markdown + extension to understand language specific cross-references is powerful! [1]

[1] https://juliadocs.github.io/Documenter.jl/stable/man/guide/#...


I've always found crate documentation to be the worse thing about Rust. Because it auto-generates some documentation, people just assume that's good enough, and you end up with tonnes of crates that seemingly only have a list of functions and structs and what arguments they take, but very little information about how you're supposed to plug everything together.


At least you get that. In the (untyped) Python ecosystem, you're lucky to get "this parameter is a file-like object" even though "file-like" doesn't tell you if it just supports read() and write() or also seek() or close() or truncate(). You have to dig into the source code, which likely just passes the parameter into another function which passes it into another and then across a library boundary and so on. And again, that's the best-case scenario. Just having correct type information is 80% of the battle IMHO.


> people just assume that's good enough

really? I've found that in general the same number of people bother to go deep into explaining compared to e.g. JS, and always having rustdoc for the people that don't is far better than reading the source or TypeScript definitions.


Both are true, in my experience. Lots of good documentation for some crates, while others (usually with fewer maintainers or less intention of reuse) just have the autogenerated index.


Go is the same. Everyone, including the stdlib maintainers seem to think a few lines of comments per method is the same as documentation on how to use the package, best practices, pitfalls, etc.


Rust's stdlib does have a policy of having a runnable code example for every API.


This is the part that blew my mind. For simple functions ("how do I read from a buffer again?"), the code example is more useful than any number of paragraphs of description, especially because its correctness is enforced by the compiler. Switching to learning Node after Rust has been a major step backwards and involves a lot more time on Stack Overflow.

(Unrelated gripe: if I could ban w3schools from my search results, that would be great.)


Java is the same as well


Interestingly, documentation that's only type signatures is also a frequent gripe I've heard about OCaml. So maybe this is a universal phenomenon.

However, some people contrast OCaml and Rust in this regard, contradicting the views of the great grand-parent comment: https://news.ycombinator.com/item?id=25111104


So tldr: people don't like writing documentation, and it's hard to make them care.


If you can’t tell a story with text, you won’t be able to tell it with code either. The thing that makes people want better documentation is the same thing that makes it difficult to get.

I remember years ago using Ant as a build tool and the only way I figured it out was to Googlestalk the author. Given enough answers to questions in enough places I finally developed a theory of the system. It was still supremely weird to convince it to do certain things but at least I was able to.


> If you can’t tell a story with text, you won’t be able to tell it with code either.

I couldn't disagree more. Telling a story with words to humans and telling a story with code to a computer are completely different things.


You’re not telling a story to a computer. You’re telling it to your coworkers. The people’s code that’s most frustrating to work with share your philosophy. They are often so convinced they’re right that they can’t even hear constructive criticism. That’s not my opinion, that’s the consensus view shared over lunches and coffees with their coworkers, across many jobs.


Is it possible to link your local core and library docs yet?

I have my dependencies documented locally, I have the standard library documented locally, both of these work well with the ability to do searches just like the online docs. The problem is they're separate. The local docs for one of my crates cannot link to my local standard library docs; instead, I have to jump around different browser tabs and manually look things up.

There used to be some hacks that could work around this, but those hacks stopped working.


Interesting question. Does RUSTDOCFLAGS="--extern-html-root-url std=file:///path/to/std/docs" cargo doc work? You can repeat it for std, core, alloc, proc-macro, etc.


You need a -Z unstable-options in there too, but this does not work for me with the latest nightly.


Hmm apparently there is a cargo feature for it now: https://github.com/rust-lang/cargo/blob/master/src/doc/src/r...

So something like this in .cargo/config:

[doc.extern-map]

std = "local"

And then cargo +nightly doc -Zrustdoc-map.


Very cool!


This is a great feature, but it is also present in many languages. For example, doctest[1] is included with Python, and allows for tests in docstrings.

[1] https://docs.python.org/3/library/doctest.html


Elixir also has this feature called doctests[0]. That said, rust documentation is also really good.

[0] - https://elixir-lang.org/getting-started/mix-otp/docs-tests-a...


I mean doctests are not exactly new. The `doctest` module was added to Python in 2.1, back in 2001. And even that is largely just a weak shade of semi-literate programming, to say nothing of actual literate programming.


This is one of the things I really love about Rust, and also one of the things that's most challenging for its adoption. Not a ton of stuff in Rust is new, but it does present a new mix of old things, and often, those things are new to many people, even if they're actually old.


Rust took out the things considered best practice and provided them to users by default, or checked for them by default. This includes simple things as explicit names for types like u8 instead of char (as you are going to assume the size of char anyway, let's be honest... most code won't work on 16 bit char platforms). But it also includes stuff like unifying naming conventions, or providing a good package manager. C++ has multiple package managers, as does js. But rust had a great one from the start and for now there doesnt seem to be the need for people to use alternatives, because nobody had to come up with them. So no balkanization of standards and the costs for users that this entails. Maybe with age this will change, but for now Rust is doing quite well.


I had to suffer with coworkers that would write doctests, bad docs and bad tests together at last!

The solution here is to write real tests and hyperlink them in a marked up form to the functions they actually test. Coding inside of a doc string is an epic troll.

This is a warning to anyone getting seduced by doctests, stay away! They invert the problem, when one should just write tests, it is a problem with the documentation and code discovery tools that makes this seem like a good idea.


I think there's another perspective on doctests, that seems more convincing to me: doctest functionality allows testing for the documentation, not a way of writing tests in documentation.

In particular, it's great if the documentation includes clear and simple examples for learning from, and it's even better if these are validated as working. This means that the focus of the code in documentation is typically different to a test (it doesn't need to include such precise validation or look at all the edge cases or regressions), but it's still really useful to have them automatically run.


What is the distinction between a "real" test and a doc test that you're making? At least in Rust, they are the same thing.


I'd guess their coworkers decided to write all tests as doctests, rather than use doctests to ensure examples run fine?

Python's doctests are also formatted and in some ways behaving like an interactive shell session, with

    >>> code here
    output here
rather than just "literate code" so the execution context is a bit strange. This makes complicated doctests hard to inspect and debug. Doubly so because there's almost no tooling which understands doctests.

And of course on the flip side the best tests make for absolutely terrible examples since they try to exercise weird corner cases.


Yes, this. I don't disagree in theory, I disagree in practice.


I think it's between a test written inside a comment (where smart IDE features don't apply) versus `#[test]` in normal code, where you have a rich editing environment and instant feedback (including `cargo build` failing immediately on errors).

Perhaps it's just my perception, but doctests (in comments) seem slower to run.


Ah; rust-analyzer syntax highlights doc tests (though not perfectly), but the higher order bit of "IDE features don't work as well" makes tons of sense, thanks!


This is also part of my complaint. At least in Python, doctests limit the ability for the IDE to be effective.

They hinder the writer as well as the consumer, since they make it harder to write effective tests. What I am saying is, that all tests should be first class wrt the documentation.


I am so glad to learn about these features in Rust and Elixir. I'm coming from Python originally, so I always want them!

https://docs.python.org/3/library/doctest.html

https://docs.pytest.org/en/stable/doctest.html


I had no idea that Python had a library for this, nice! Skimming that doc, it's especially impressive how well it looks to handle exception tracebacks.


This is how ddoc works in D, too. Markdown arrived recently as well




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: