Jim Blandy and Jason Orendorff, Programming Rust: Fast Safe Systems Deployment.
Wait, didn't I read this book before? Well, sort of. It's still an O'Reilly Early Release book, so it's still minimally edited and incomplete, just a little less incomplete than it was before. This time I read the Seventh Early Release, dated 2016-11-21. There have been a number of changes since the draft I read earlier this year, partly as the book is getting more complete and more polished, partly as the Rust language itself has evolved.
One of the new parts: chapter 13, on iterators, is now written. Rust iterators are basically in the Java/Python style of iterators (i.e. objects that produce values when you repeatedly call next), as opposed to STL-style iterators. In STL terms they're the moral equivalent of input iterators. And since the Rust library doesn't have STL-style iterators, it also doesn't have the STL notion of decoupling algorithms from data structures with iterators as mediation. The Rust standard library does have some of the basic algorithms I'm used to, but scattered in a number of places: some of them appear as methods in the iterator trait (which makes them more generic than that sounds: it means they're defined for arbitrary iterators, including user-defined ones), some, like ones related to sorting and binary search, appear as methods on ranges, which gives them a very different feel, and some, like intersection and difference, appear as methods of more specialized traits or types. I don't know where something like merge would go if the Rust standard library had it.
Pretty obviously the STL itself couldn't be written in Rust without some big changes, since the whole point of STL-style iterators (at least forward iterators and above) is that they're a generalization of pointers, that they're handles pointing into some range and that two iterators can point into the same range; one of the main points of Rust is to do away with that notion, and make it impossible to have two mutable pointers that point to the same thing. That's a pretty fundamental incompatibility. I still wonder, though, if something in the same spirit as the STL could be written, something that makes it possible to write algorithms abstracted from the data structures they operate on.
I continue to find Rust interesting, and I plan to follow its evolution. I'm glad someone is attempting to design a language that supports abstraction and and safety without loss of efficiency. I'm also thinking more about Rust's (deliberate) limitations, though. The chapter on containers makes the observation that none of the containers in Rust's standard library can be written in safe Rust; they all require the “unsafe” escape hatch, which this book doesn't even cover. And again, that makes sense. How can you write a doubly linked list unless you have nodes with references to each other? That, too, is something that Rust's strict lifetime system deliberately prevents. If I were trying to write something real in Rust, would I find that I only needed to use the escape hatch once in a blue moon, or would I constantly find myself struggling to see how to express myself in safe Rust, failing, and constantly reaching for the escape hatch? No way to tell without trying, but I'm worried if you need to use esoteric and discouraged language features for something as pedestrian as a doubly linked list.