I feel like rust has some good sweet spots right now. I care about these but maybe not everyone else does.
- Parsing untrusted inputs. nom[1] is a joy to use, and lets you kind of effortlessly and fearlessly process random input from wherever and turn it into useful data structures. If your data is very regular or in a standard format, then serde[3] is very hard to beat if it just boils down to 'derive(Deserialize, Serialize)' on your Rust struct.
- Bulk data processing. rayon[2] makes pegging your machine easy if you have a lot of work do to, and the Rust semantics around thread safety, data ownership, and explicit copying make it kind of trivial to reason about how your data gets from input to output and tuning it to be crazy fast.
- Generic systems language. Maybe this one is personal, but I find it's more productive to write generic cli applications and whatnot in Rust over C, ruby, or python. There are some nice libs to make part of this pleasant (structopt[4]) but this really boils down to reliability. Because Rust makes it obvious where things can fail so I can deal with it I have way higher 'just works' outcomes in Rust than other languages. I might spend slightly more time making it compile, but I spend basically zero time debugging runtime failures and this is kind of indescribably amazing.
Something like the cxx crate[1]? You specify your shared objects between C++ and Rust, and it spits out code for both sides.
The guy who maintains it said in the reddit thread[2] about this same topic that the Google people have been sending him good PRs, which is presumably related to integrating Rust into Chrome.
We built a new project in all "modern C++". It is 100% shared_ptr, unique_ptr, std::string, RAII, etc. It initially targeted C++17 specifically to get all the "modern C++" goodness.
It segfaults. It segfaults all the time. It is entirely routine for us to run a new build through the CI process and find segfaults. We fuzz it and find dozens of segfaults. Segfaults because of uninitialized memory. Segfaults because dereferencing pointers. Segfaults because running off the end of arrays. Segfaults because trusting input from the outside world ("the length of this payload is X bytes").
This is where the "modern C++" people tell me we must be doing it wrong. But the reality is that "modern C++" isn't as safe or as foolproof as the advocates say it is. But don't take my word for it - this whole thread is about Google people coming to the same conclusion.
Meanwhile I can throw a new dev at Rust and watch them go from zero to works in a week or so, and their code doesn't segfault, doesn't panic, and actually does what it is supposed to do the first time. Code reviews are easy because I don't have to ponder the memory safety and correctness of every line of code. Reasoning about unwrap() is trivial. Finding unsafe {} is trivial (and removing it is also usually easy).
Sorry if you interpreted my comment as advocating for tossing out grep or ls - that certainly wasn't what I was getting at. As one of the OpenBSD people that happens to quite like Rust, I'm aware of some of the other devs who have been using it, and we've talked a bit about Rust in general on occasion. The things that people appreciate about Rust tend to align with the things they like about OpenBSD, because the two projects have similar values. That's all I meant.
There are actually several of the OpenBSD devs that have been writing Rust lately. Some are doing it for work, some from personal interest. Opinions vary on how much people like it.
Rust and OpenBSD share a lot of technical values though so maybe this isn't surprising. Rust values safety and correctness. OpenBSD values safety and correctness. Rust values 'Just Works' with all the nice things cargo does and the whole 'fearless refactoring / concurrency' thing. OpenBSD values 'Just Works' with sane defaults and the 'batteries included' base system.
FlatBuffers, Protobuf, Cap'n Proto, etc., all require an external schema configuration that you compile into a code chunk that you include into your program. Without this it is impossible to make sense of the data. In our case, the data is semi-structured and changes frequently. The prospect of maintaining a schema registry for all the data users and keeping everyone up to date and backwards compatible is enough of a burden that it was excluded.
Avro also uses schemas, but since the schema is embedded in the file it is self-describing so the reader does not need to do anything special to interpret the data. But Avro's C library is buggy and the python deserialization performance was terrible, so Avro was not selected.
At my work we recently went through a large exercise to decide on a common data storage format. The contenders were JSON, MessagePack, and Avro. MessagePack won because:
- Msgpack serialization and deserialization is very fast in many languages - often 100x faster then JSON
- Msgpack natively supports encoding binary data
- Msgpack has type extensions, making it trivial to represent common types in an efficient way (eg. IPv4 address, timestamps)
- Msgpack has good libraries available in many languages
If you do not care about those things (no binary data, no need for extended types, not performance critical) then JSON is just fine.
- Parsing untrusted inputs. nom[1] is a joy to use, and lets you kind of effortlessly and fearlessly process random input from wherever and turn it into useful data structures. If your data is very regular or in a standard format, then serde[3] is very hard to beat if it just boils down to 'derive(Deserialize, Serialize)' on your Rust struct.
- Bulk data processing. rayon[2] makes pegging your machine easy if you have a lot of work do to, and the Rust semantics around thread safety, data ownership, and explicit copying make it kind of trivial to reason about how your data gets from input to output and tuning it to be crazy fast.
- Generic systems language. Maybe this one is personal, but I find it's more productive to write generic cli applications and whatnot in Rust over C, ruby, or python. There are some nice libs to make part of this pleasant (structopt[4]) but this really boils down to reliability. Because Rust makes it obvious where things can fail so I can deal with it I have way higher 'just works' outcomes in Rust than other languages. I might spend slightly more time making it compile, but I spend basically zero time debugging runtime failures and this is kind of indescribably amazing.
[1] https://docs.rs/nom/6.1.0/nom/index.html
[2] https://docs.rs/rayon/1.5.0/rayon/
[3] https://serde.rs/
[4] https://docs.rs/structopt/0.3.21/structopt/