Hacker News new | past | comments | ask | show | jobs | submit login
Rust Cookbook (rust-lang-nursery.github.io)
353 points by ingve 39 days ago | hide | past | web | favorite | 62 comments

Another great book that is completely free and open source. Rust might be a little harder to learn then other languages but you can't deny that it has great resources if you decide to learn it.

The Rust documentation is deep but not wide: unlike Python (for example) the standard library is small, which means that the well-documented area is small. Almost as soon as you try to get anything done, you will end up reading auto-generated function signature docs and browsing through the source code of whatever crate you want to use. This is true for scientific computing and game libraries, and may not be true for networking which I hear is very well-developed.

Because Rust's type system is so good, auto-generated function signatures are actually pretty useful. However this is one area in which the language is clearly immature.

That's what Perl programmers used to say about Python. It couldn't compete with the CPAN library.

While a large set of libraries is helpful, I wouldn't let that stop you if you think Rust is a good fit for your problem.

To be honest, python libraries are wide but the documentation quality isn't always the best (I could be spoiled)

”documentation quality isn't always the best”

Compared to what? (Asking just out of curiosity.)

In general, I find Perl's CPAN to usually have really good documentation that surpasses what Python has, even though I prefer Python over Perl nine times out of ten.

As a full time Perl developer, I've wondered more than once if this is due to the way the way the language shapes the community. Perl has evolved (out of necessity) a very strong level of norms and best practices that users are aware of, and put effort into following (well, most the time, Perl is all about letting you pull out the shiny weirdness and letting it shine where it fits well). Module documentation is part of this. A module could implement an object oriented interface, a procedural interface, both, import function into the main scope on use, or on request, or any number of weird (and depending on your point of view wonderful) things.

Not having good documentation means nobody knows how to use your module without a lot of work reading the code. So modules get documented or they get ignored. Thus, the modules on CPAN you know about and that are commonly used and relied on by other modules are the ones that have good documentation. It's self reinforcing. I imagine in a language that funnels use into a single or small set of idiomatic ways to accomplish most tasks, it might be easier to skimp on documentation and rely on people to fall back on the "obvious" way to things.

I'm not a full-time Perl Dev like you, but do whip up something a few times a year and it is there when I need it. I'm therefore incapable of properly replying to your thoughts although it makes sense to me (Perl is so flexible that you better have good documentation if you make a module and want it used). My thoughts are more along the lines of how much modules and CPAN are pushed in general. Most of my Perl books (Ovid's in particular) go into excruciating detail on publishing packages. It's not a two pager crammed into an appendix either, but is front and center. The Perl community frequently hosts challenges to clean up old modules and such. There is even a guy with the last name of "Anwar" if I recall correctly that is a celebrity in the community for how many modules he maintains that aren't even his (and he has also done challenges like making a new pull-request every day for like a year). That is some real dedication there to making Perl useful. It is one of the things I really like about the community. I'm a little bit of a language hobbyist even though I'm still only a novice coder in my mind. Out of all the languages that I've spent time with (probably 2 dozen) learning superficially, I'd say Perl ranks towards the top of the spectrum when it comes to focusing on this. They've evolved a relatively simple and effective system for allowing users to make, share, and document libraries.

> They've evolved a relatively simple and effective system for allowing users to make, share, and document libraries.

Well, as is often said, simple is not easy. :) There's a large effort by the CPAN testers community to run every module (and every new version of it) against a large array of hardware and operating systems[1], and provide automated reporting to the author of any problems.

This is possible because of (and incentivizes) the other great aspect of CPAN and the public modules which are on it, which is a strong culture of good test coverage of modules, and the CPAN clients running all tests and failing to install by default if any tests fail that weren't expected to. It's another wonderful feedback loop, and one not encouraged or discouraged by most languages specifically, so the fact that so many package managers for languages decided not to do so is unfortunate. When you don't start with that as an expectation, turning it on at a later date likely just results in a horrible user experience as a large number of module just fail to install (or at a minimum spew warnings which are confusing) because they are exposing what was previously something only the author saw most the time.

1: http://matrix.cpantesters.org/?dist=Path-Tiny+0.104

Thanks for the helpful replies. I didn't know that.

Check out docs for elixir. It's a community where the standard library docs set a high standard of quality that quite a few package developers seem inclined to try to aim for. Heck, the documentation for the Float module even is kind enough to warn you about gotchas in IEEE floating point.


One thing I really like: Unlike in python docs, on all the function calls and most module headings you can click through to the actual elixir source code and see how the functions work under the hood (via the <\> link). You also get this nearly for free when doing docgen on your own modules (it's one line in setup). Also, the HTML is responsive so it's easy to review your own code when on the toilet, if necessary.

And there are python libraries that are horrible offenders. Perhaps it's a matter of taste or experience, but I found the tensor flow docs to be inscrutable and nearly useless

I’ve found latex packages often have quite good documentation. Sometimes elisp packages have good documentation but sometimes they don’t.

Rust at least has auto-generated documentation. Python lacks that. Some python libraries might have documentation up, but there's no docs.rs like thing where you can just find docs for (almost) every library available.

I feel that the quality of auto-generated docs is generally better for Rust than for other languages like C++ (e.g. via doxygen). This is because the tools make it trival to publish and distribute docs for your crate, and people make use of that because it is so easy.

Obviously, these tools don't solve the problem for you. In the same way that some C++ projects use doxygen without writing doc comments and say "but we have auto-docs!", some Rust projects (the rust compiler libraries and official projects, e.g., cargo, libsyntax, etc.) almost completely lack API docs. They do have books (rustc book and implementors guide, cargo book, etc.) so it isn't that they are completely undocumented, but if you want to use these as libraries, the auto-generated API docs are useless.

We’ve been trying to figure out how to improve this, but it’s tough.

Feels like solving a cultural problem.. but one that affects a large part of the software development community. The aversion to writing documentation seems pretty deep set in most developers :)

Perhaps I'm missing something obvious, but cannot a large part of this be addressed by significantly expanding the standard library? A favorite feature of mine in AWS CloudFormation is the ability when writing Lambda functions for the Python runtime to inline the code into the template and sidestep the process of generating and uploading code artifacts. This works because other than the (provided) boto3 SDK, I generally need nothing but the standard library.


Putting things in the standard library can greatly slow down their development as it upgrades when the standard library does and deprecating things can be more painful for library users because it is much easier to choose an older version of some boring library than of the standard library.

Then again, maybe one would want such things to slow down development

There is probably a _right time_ to start pulling more libraries into the standard library.

That comes with all of the downsides of significantly expanding the standard library.

I wouldn’t say harder, like learning c++ well (patterns + concurrency etc) is legit hard. Same for other languages. Rust has surprisingly few concepts, it’s just that they combine nicely.

It's harder like people think static typing is hard.

It's more about how many concepts you need to be aware of to write something. Garbage collection is a complex topic you can ignore at first, for example. Rust pointer management takes immediate investment. Even freeing pointers you can be lazy about at first. Rust makes it easier to write good code at the cost of making it hard to write bad code.

I find myself able to deny that it has great resources. The reference manual is very weak.

It’s going to be a big area of work this year!

This is really good news. Hopefully a more well-developed and thorough reference will allow for a GCC rust frontend to be developed.

I don't think that that's really the blocker there, afterall, mrustc exists. That said, maybe it will give someone enough confidence to step up and do the work, I dunno. We'll see!

It's been awhile since I've done anything resembling C/C++, and have put off looking too much into Rust for the moment, but I was surprised at how readable the examples on CSV processing were: https://rust-lang-nursery.github.io/rust-cookbook/encoding/c...

One of Rust's major advantages over C and C++ and a huge reason why I choose it for new projects that call for a low level language is better learning resources. Others are better, established tools (like cargo), helpful community, sane dependency management, and expressive syntax. Even if it didn't have any of the borrow checking features I'd still use it just for those reasons alone.

It can also be painlessly integrated into Node.js programs as native modules and interoperability makes a Rust + Node combo a perfect mix for many use cases.

If I wrote a different kind of C++ (not competing for state-of-the-art speed), I would absolutely use Rust. Package management, versioning, debugging; everything is just more convenient. It’s not quite as expressive as I’d like, but that may yet change, too.

I'm competing for state-of-the-art speed and I use Rust. Libraries like Rayon are really helpful compared to things like OpenMP, which we wouldn't ship.

What's the problem with OpenMP? From a distance, it seemed to be great.

This is nice, but it looks like some of these rely on third-party dependencies to make the examples trivial. I'm not really sure it's useful to have an example for say argument parsing which is essentially "here's how to use this argument parser from GitHub".

I don’t think implementing your own cryptographically secure cross-plattform RNG bindings would be particularily useful. Same goes for JSON serialization, deserialization with the serde crate.

There are some very well solved problems and I don’t think Rust should hide the fact that you can also rely on those. The idea of a cookbook is to solve common problems — and sometimes the easier way to do this is to use an battletested external dependency.

It might be worth making those "official" then, if it's not worth having everyone reimplementing them? If they're the standard in all but name, to the point where official material is referring to them as the preferred way to do things, I don't see why they should remain as third-party dependencies.

In other for their APIs to evolve independently of the compiler's release cycle.

In Python it is often said that stdlib is where modules go to die, and dependency management in Rust is a particularly different experience to most other languages. A good example of why keeping the standard library lean can be a good idea in the long term would be datetime handling in Java: https://stackoverflow.com/questions/12032051/differences-bet...

Some of these are produced by the rust project itself, but not all.

We can’t just take control of a project just because it’s popular, that’s not really how open source works.

This resource is intended to teach about the crate ecosystem.

A similar resource that focuses more on the language and standard library is Rust by Example:


It's useful for people who want to do argument parsing.

I get that, but that makes it less a "Rust Cookbook" and more "here's some high-quality libraries that do common tasks".

I think that's part of the philosophy of Rust, though. The crate system should be robust enough that the most common tasks can be handled by whatever becomes the community's de-facto standard.

If you need something simpler than the community's choice and don't want a dependency, roll your own. Otherwise, the ecosystem has you covered.

I will admit that I don't understand why Random is its own crate, and not in the standard library, however...

Largely because the design wasn't finished in time for the Rust 1.0 release, and they didn't want to commit to the API.

This way of doing things has it's advantages though. People are still coming up with new ways of generating random numbers, and in an external library you can release a major version and remove deprecated functionality without breaking anybody's code.

For comparison, here's how it worked out with C++, which now suffered through not one, but (if you count the original C standard library) two iterations of random number generation APIs with significant flaws in them.


How does that make it less of a Rust Cookbook? Like a real cookbook, it collects "recipes". You need ingredients to cook those recipes. No cookbook tells you how to grow you veggies from scratch.

It's not a Rust Cookbook, it's a "Rust with libraries" Cookbook. For example, in a cake cookbook, I'd generally expect it to teach me how to make a cake, instead of step one being "buy this cake mix and here's how to bake it after you do that". This isn't to say that this wouldn't be useful, but generally I'd expect an "official Rust Cookbook" to only include the "official" standard library.

Ah, I guess the problem is that Rust standard library is quite barebones compared to some languages such as Python and Java. A fitting name for a book for creating stuff with Rust standard library only would be something like "Coding X from scratch with Rust". I think that the metaphor of cooking captures the feeling of using Rust with libraries just fine; especially since the libraries featured in the Cookbook are hand-selected to be of an "almost blessed" status in the ecosystem.

A Rust cookbook is more like a "grilling with gas" cookbook in that sense.

On the other hand, I expect Python Cookbook to use requests, not urllib.

I agree. I’d also like to see random beeing part of the std crate, but while it isn’t it is not really feasable to roll your own there for any project that isn’t yet another random.

I wouldn't. If there was a "Writing Python in the real world" document, that's where it belongs–but the official documentation should only really use things that come with Python, with at most a shoutout to good third-party solutions.

So in other words, you want the Rust Cookbook to be dogmatic instead of pragmatic. Which of those would be more useful to beginner and intermediate Rust programmers?

Personally, I think it's a lot more useful to teach beginners and intermediate Rust programmers the extent of the standard library than teach them to grab the first library they find for everything–this is something that they can find out themselves when they realize that the standard library doesn't do what they want. Especially when it's coming from an first-party source like this one.

The point of this book isn't to function neither as the tutorial or intro to the language, nor as a language refererence or stdlib API referenece. It's purpose is to collect common tasks and show idiomatic and practical way to do them in Rust. In the process, its purpose is to introduce central libraries in the ecosystem. It sounds that you want it – and maybe the model of developing software in Rust itself? – to be something entirely different than it actually is.

It is standard practice by the rust core team to implement as little as possible in the core/stdlib and “bless” 3rd party packages that add otherwise necessary functionality. This allows the language to evolve more quickly.

Cargo, the package management system is very good, and the resulting binary is compiled (therefore you aren’t thrusting 3rd party dependencies on your end users), so there is far less incentive to avoid 3rd party libraries than there might be in Python for example.

Can you parse CLI arguments manually using rust? Of course, but should you?

Where can I go to suggest new "recipes"?

I see that it starts with random numbers, but when I was learning I got tripped up a bit when trying to generate seeded randoms.

The little “edit” button at the top takes you to the github repo, filing an issue is the way to go.

It might take some time to respond to, because this project got really far but not quite across the finish line, and I think the main maintainer has dropped out. We’ll get to it...

I'd like to see an official recipe for using closures as callbacks (for example in a UI library), where variables in outer scopes are potentially modified from within the closure.

See e.g. [1] for a possible approach.

[1] https://gtk-rs.org/docs-src/tutorial/closures

I’m a bit torn about this one, because it’s not universally clear that this is the correct way to build these kinds of systems in Rust. GTK has to due to the constraints of the system it binds to, but there’s a lot of experimentation of different ways that may be more Rust-y and not have the huge pain points this approach has.

Once its sorted, I think comparing and contrasting this kind of thing would be amazing though.

What would be an alternative, equally flexible way to handle callbacks?

https://raphlinus.github.io/personal/2018/05/08/ecs-ui.html is an entry point into the main alternative that’s being explored, see “druid” as a package that’s an implementation of (an evolution of) these ideas, though it’s still early days.

In general, Rust hates big balls of intertwined mutable state. And traditional OOP-y UI frameworks are basically giant balls of intertwined mutable state. You can do it, but it’s not great. We’ll see.

Realistically, this is still a necessity, because even if Rust comes up with its own quality UI frameworks - which takes years, looking at the history of the ones that we have - some people will still need to integrate with what's already there.

Sure, it's still necessary, but that doesn't mean that it needs to be promoted as the correct pattern to use in the general case.

I love all of Rust’s documentation it has really been great to see as I learn the language. I can pick up a language easy enough but to pick up a language’s specific idioms is really hard without examples and this resource is great for that. One issue I have had though is how often the resource is out-of-date in some sense. Rust 2018 switched how modules were included and I constantly was confused what the difference was until I learned one was just older (by like a month). Also error handling is very confusing for me. I used error-chain first and everything worked but then I heard failure was the way to go yet there are very few resources on using either idiomatically.

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