Hacker News new | ask | show | jobs
by gnuvince 2830 days ago
Language-wise, Rust is really top-notch, I find it hard to fault any design decision. There are some design choices that annoy me (e.g., two closure types can never be equal), but there is always a fact-based rationale for why things are the way they are.

My two major pain points in Rust are (1) the compile times, (2) the high variance of quality in the ecosystem.

The compiler for Rust is very slow, it takes minutes to build software from scratch. Things are getting better with incremental compilation, but it's definitely not as fast as D or Go to compile, and that can be very grating during development.

Anyone can easily contribute to the crates ecosystem and post their libraries and programs to crates.io. Unfortunately, there is no real way to know what's production-quality and what's a toy. You can try and rely on the number of downloads, the names of the contributors, etc., but there is no system that tells you what other Rustaceans think of a crate. For instance, I tried using an HTTP client with few dependencies (because the most downloaded option, reqwest, has a lot of dependencies), but I found that (a) the library issued a read(2) syscall for each byte that it downloaded, (b) did not always return the full payload for HTTPS. There was no way I could tell from just looking at the crates.io page.

2 comments

Compile times are really a big pain point, even slower than C++, when taking advantage of incremental compilation, linking, binary libraries and experimental modules, while not being crazy with templates.

I am also looking forward to the incremental compilation improvements.

Still think that until cargo actually supports binary dependencies, the experience will not be as fast as it could be.

In our continuous integration system at work, I've enabled sccache with the S3 backend. This reduced the compile times from 20-25 minutes (tests and release build) to 8-9 minutes. Still longer than I like, but it's possible to ease the pain somewhat.
The dependency thing worries me to a fair degree. Amazon has (or at least had when I was there) a build tool fairly similar to cargo. Libraries and software was imported in to the underlying repositories with a version associated. You put that in your list of dependencies and voila when you built your code everything got neatly combined and compiled as needed.

One routine source of pain was when one of your upstream dependencies changed its dependencies. That would happen quite routinely. All was fine, unless you actually had two packages that had dependencies on different versions of a library.

You could work around it by pinning the version of the dependency, but of course that's risky. You don't know if you're exposing yourself to bugs, because you're making software run with a dependency version it hasn't been tested against.

Pretty much every build file I ever saw in Amazon had at least a half dozen or more dependencies pinned. Every now and then you'd find you were getting a new dependency conflict, and that things had become an impossible knot to untangle. All you could do is unpin _everything_ and then figure out all the version pins you needed again from scratch.

I swear I would lose at least one to two days a quarter doing that. The development focussed teams would spend way more than that on fixing conflicts.

I started out with Rust just last weekend. Put a couple of dependencies in the Cargo.toml library and got stunned when it pulled in over 400 dependencies, a number of which I'd expect to have seen in the stdlib, not left to the vagaries of random people's implementations.

For native Rust libraries this is a solved problem. Cargo finds one common compatible version of each library that satisfies requirements of all dependencies, and only when that isn't possible, it allows more than one copy of the library (and everything is strongly namespaced, so there's no conflict).

And it has a lockfile, so your dependencies won't update if you don't want them to.

The only problem is C dependencies like OpenSSL that do break their API, and don't support multiple copies per executable, so there's nothing that Rust/Cargo can do about it (you as a user can avoid them and choose native Rust libs where possible).

In Cargo you can have different libraries use different versions of the same dependency, and as long as those different versions don't interact you're fine. What this means is that if library A depends on Bv1, and C depends on Bv2, then as long as A doesn't expose something from Bv1 that you try to use with an API in C that expects Bv2, you're good.