Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Note that the advantages of Rust are not just execution speed: it's also a good language for expressing one's thoughts, and thus makes it easier to find and unlock the algorithmic speedups that really increase speed.

But yeah. Python packaging has been dumb for decades and successive Python package managers recapitulated the same idiocies over and over. Anyone who had used both Python and a serious programming language knew it, the problem was getting anyone to do anything about it. I can't help thinking that maybe the main reason using Rust worked is that it forced anyone who wanted to contribute to it to experience what using a language with a non-awful package manager is like.



Cargo is not really good. The very much non-zero frequency of something with cargo not working for opaque reasons and then suddenly working again after "cargo clean", the "no, I invoke your binaries"-mentality (try running a benchmark without either ^C'ing out of bench to copy the binary name or parsing some internal JSON metadata) because "cargo build" is the only build system in the world which will never tell you what it built, the whole mess with features, default-features, no-default-features, of course bindgen/sys dependency conflicts, "I'll just use the wrong -L libpath for the bin crate but if I'm building tests I remember the ...64". cargo randomly deciding that it now has to rebuild everything or 50% of everything for reasons which are never to be known, builds being not reproducible, cargo just never cleaning garbage up and so on.

rustdoc has only slightly changed since the 2010s, it's still very hard to figure out generic/trait-oriented APIs, and it still only does API documentation in mostly the same basic 1:1 "list of items" style. Most projects end up with two totally disjointed sets of documentation, usually one somewhere on github pages and the rustdoc.

Rust is overall good language, don't get me wrong. But it and the ecosystem also has a ton of issues (and that's without even mentioning async), and most of these have been sticking around since basically 1.0.

(However, the rules around initialization are just stupid and unsafe is no good. Rust also tends to favor a very allocation-heavy style of writing code, because avoiding allocations tends to be possible but often annoying and difficult in unique-to-rust ways. For somewhat related reasons, trivial things are at times really hard in Rust for no discernible reason. As a concrete, simplistic but also real-world example, Vec::push is an incredibly pessimistic method, but if you want to get around it, you either have to initialize the whole Vec, which is a complete waste of cycles, or you yolo it with reserve+set_len, which is invalid Rust because you didn't properly use MaybeUninit for locations which are only ever written.)


Cargo is fantastic... for building Rust code. Once you start trying to also use it to build C code, you're moving outside of Cargo's wheelhouse, using features that Cargo only supports begrudgingly (like build scripts). Cargo is definitely not intended to be an end-all be-all build system for all languages; it's specialized for Rust, and that's what it's great at. For multi-language projects, you want some sort of simple tool to orchestrate the builds (e.g. `just` https://just.systems/man/en/ ) that internally calls out to Cargo (and whatever other build systems you have for whatever other languages you're using). The overall mistake is thinking that Cargo is a replacement for `make`, when it isn't nearly so general.


> or you yolo it with reserve+set_len, which is invalid Rust because you didn't properly use MaybeUninit for locations which are only ever written

`Vec::spare_capacity_mut`[1] gives you a view into the unused capacity. There's nothing "invalid" about it.

[1]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.spa...


Yes, but now you have a slice of MaybeUninit instead of T. This is totally fine for code you control, but out-parameters of the shape &mut [T] are very common for data en/decoding crates, and those require an initialized slice per Rust initialization rules, even if/though most of these will only write to out or reference elements previously written. In practice you can still reserve+set_len, but it is undefined behavior in rust for a &[T] to exist that points to uninitialized memory; at least this is my understanding. If that were not the case, then the spare_capacity_mut API would be kind of pointless?


If something is asking for `&mut [T]`, then yes, it's required that it be initialized. This is a good thing, because a `&mut [T]` permits reading that `T` in safe code, which would be UB if the `T` were uninitialized.

It seems like your complaint is more about "more APIs should accept possibly uninitialized data, but they don't." Which is fair, but I don't know how big of a deal it really is. There is for sure desire to make this work with `std::io::Read`, and indeed, there are unstable APIs for that[1].

[1]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read...


I have empathy for anyone who was required to use cargo on a nfs mounted fs. The number of files and random IO cargo uses makes any large project unusable.

I had to stop telling people to stop syncing their cargo env around nfs so many times, but sometimes they have no choice.


> nfs mounted fs

Anything doing locks on nfs, including trying to use sqlite, is a mistake. This is not a cargo problem this is a nsf problem.




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

Search: