7 ms·
I tend to disagree. - Compile speed. Why do people care so much? Use debug for correctness and iterating your code. You're hardly going to change much between
by lordnacho 11mo ago
I tend to disagree.
- Compile speed. Why do people care so much? Use debug for correctness and iterating your code. You're hardly going to change much between runs, and you'll get an incremental compile. Let rust-analyzer tell you if there are errors before you even try compiling. Let your CI do release optimization in its own time, who cares if CI is slow?
- The cloudflare bug was not caused by rust. Every language needs some way to say "hey this thing is invalid", and that's what happened when the list of AI tools got too long (or whatever their business issue was). Making the app panic was a design choice, not a language choice. Every language has a way to not handle errors.
- Things having unsafe {...} does not make them unreliable. On the contrary, if you run into a memory issue in a rust program, you know where to look for it. The problem in c++ was that the whole program was unsafe, and you then had no way to narrow it down. Memory safety errors are like type errors: a large class of errors that are worth checking for. If you're writing good c++, you have a linter that checks similar things anyway, and if you're disciplined, you've also upgraded warnings to errors. FWIW, I do think the marketing over-emphasizes memory management, because there are a lot of these hard learned lessons that are default in rust but optional in c++.
- Mutable shared state: make bad designs hard to write. Mutable shared state is another one of these eternal bug sources. Use channels and pass messages.
Honestly, it reads like a lot of critiques of Rust: people haven't spent enough time with it, and are not over the learning curve yet. Of course everything is cumbersome before you're used to it.
- josephg 11mo ago> The cloudflare bug was not caused by rust Yeah. Rust’s Option::None as like null in C++. Unwrapping an option is like checking if something is null and crashing. This "crash from an unwrap" is just a null pointer exception / segfault in any other language. The same bug would be trivial to write in any other language, and with more or less the exact same result. Its just - weirdly news because it was rust code. What? > Honestly, it reads like a lot of critiques of Rust: people haven't spent enough time with it, and are not over the learning curve yet. Exactly. I’ve spent years with rust and my complaints are very different. Well, I still wish it compiled faster but all the other stuff is noobie problems. As someone with more experience, my frustration points are things like how async blocks do compiler magic you can’t write yourself. I hate unnameable types. I think Pin is confusing and weird. And the syntax for interacting with raw pointers is unnecessarily inconvenient and ugly. Yes, rust makes programs with a lot of shared mutable state awkward to write. So don’t program like that. In general, if you write code in language X as if it were a bad version of language Y, you're going to have a bad time. The right question here is if the "rust way" of thinking about your code results in a beautiful program. You can't answer that if you go in with too many preconceptions of how programs should be designed.
- tialaramex 11mo agoThe Cloudflare bug was unwrapping a Result::Err not an Option::None. Both Option and Result can be unwrapped and - to some extent not coincidentally - both can also be subject to the Try operator (?) which is arguably more correct here than unwrap because this can fail and perhaps the caller will have some plan to recover. My list of peeves would be very different from yours. I would like to prohibit move of the dodgier as casts (requiring that you write out the conversion call you actually meant explicitly and then handling any edge cases) for example. What sort of "interacting with raw pointers" are you thinking of that's too inconvenient and ugly for your liking?
- josephg 11mo ago> Both Option and Result can be unwrapped and - to some extent not coincidentally - both can also be subject to the Try operator (?) which is arguably more correct here than unwrap because this can fail and perhaps the caller will have some plan to recover. I guess its equivalent to Go code like this: value, err := stuff() if err != nil { panic(err) } Or in C: int result = stuff(); assert(result >= 0); If someone wrote code like that and the program crashed, nobody would attack Go or C. In all these cases (including rust), the programmer is expressing clear, explicit intent for the program to panic if the call failed. I've seen some people say .unwrap() should be named .unwrap_or_panic() or something to make that more clear? I dunno. It seems like a nothingburger to me. A buggy program crashed. They'll do that. > What sort of "interacting with raw pointers" are you thinking of that's too inconvenient and ugly for your liking? I have 2 complaints. First, I wish Rust had a -> operator or something like it. This sort of thing is horrible: (*(*(*ptr).foo).bar) Secondly, rust's aliasing rules make writing pointer heavy code very difficult. I like to run my unsafe code through MIRI to make sure I'm not doing anything bad, and its incredibly subtle. Here's an unsafe function which manages the internal state of a skip list: https://github.com/josephg/jumprope-rs/blob/3981256e4e741d8b19efe26ffcfcfe178332eda0/src/jumprope.rs#L965-L1034 https://github.com/josephg/jumprope-rs/blob/3981256e4e741d8b... This code is insanely fragile. There are multiple pointers to different elements floating around. The only way I got miri to calm down was to dereference the node pointer constantly. Eg: *cursor.num_bytes -= (*node).str.len_bytes(); let next = (*node).first_next().node; Basically everything else I tried caused obscure aliasing problems. I think if I rewrote this code today I'd probably use a Vec and safe rust instead. I can much more confident write correct C code than correct unsafe rust code. I wish it were the other way around. As a general principle, unsafe rust should be as simple and easy to reason about as possible so we can spot security problems. But rust's syntax makes unsafe code very complex. I don't think this complexity is in any way necessary.
- PaulDavisThe1st 11mo ago> Compile speed. Why do people care so much? Ardour is a real-world, mid-size project. About 1.3M lines of code, almost all of it C++. On the fastest typical x86_64 systems, it builds in about 1.5mins, on an M3 it builds in about 3.5mins, on a somewhat older x86_64 16 core system it builds in about 7.5mins. If you ever touch libs/ardour/ardour/session.h or libs/pbd/pbd/stateful.h, you're in for an almost complete recompile. If you touch libs/temporal/temporal/timeline.h, same thing. That's just the day to day work of being a developer of a native desktop application - nothing to do with CI or releases. That's why some of us care.
- jandrewrogers 11mo ago> Mutable shared state: make bad designs hard to write. Also makes good designs hard to write, designs that can be significantly more efficient. Passing messages is not a universal solution to shared mutable state. It is great for certain patterns but suboptimal for others.
- eddd-ddde 11mo agoWrong, it makes good designs easy to write with clear safe APIs. If you know what you are doing just create a safe wrapper over unsafe functions and do what you need. For example you can just write a lockless triple buffer for efficient memory sharing and wrap the unsafe usage of pointers with a safe API. now you only need to pay attention to those specific unsafe calls.
- int3trap 11mo ago> Wrong, it makes good designs easy to write It encourages good designs but it does not make them easy to write, but that's somewhat the point. Its not trivial to design a safe API that pushes performance limits. > just write a lockless triple buffer for efficient memory sharing and wrap the unsafe usage of pointers with a safe API This isn't practical or pragmatic. And I say this as someone who likes rust and develops in it every day.
- byko3y 11mo ago>Compile speed. Why do people care so much? Use debug for correctness and iterating your code. You're hardly going to change much between runs, and you'll get an incremental compile. What's the largest Rust-based public codebase so far? Rustc with like 1 million lines of code including all the dependencies in all the languages? Zed IDE has 800k lines. Incremental compilation seems to work fine at this scale, but things become messy above it. Most people prefer to not exceed the limit. >Mutable shared state: make bad designs hard to write. Mutable shared state is another one of these eternal bug sources. Use channels and pass messages. People think BEAM (Erlang/Elixir) does not have shared mutable state because the programming model says so, but it actually has some mutable shared state transparently under the hood i.e. implementation details and runtime. BEAM processes all run in a single OS address space, they are not even separate threads but async tasks spread out across OS threads — and still per programming model of the language those are "shared nothing". So in the end BEAM is a very good abstraction on the partially shared mutable state. And no, in BEAM remote messaging is not nearly the same as local messaging. For example, you don't have built-in supervision trees on remote, and ETS is also local-node-only. I do agree that hardware model of shared mutable state is inherently problematic, but we don't have other commodity CPU-s yet — you have to handle the shared mutable if you wanna be close to hardware. >It reads like a lot of critiques of Rust: people haven't spent enough time with it, and are not over the learning curve yet. Of course everything is cumbersome before you're used to it. Well, at least you confirm that the complexity is real. Don't get my criticism to close to the heart though — I did exaggerated the problems a bit, because someone needs to counteract the fanboys.
- deleted 11mo ago[deleted]
- Capricorn2481 11mo ago> Things having unsafe {...} does not make them unreliable. On the contrary, if you run into a memory issue in a rust program, you know where to look for it This isn't true, no matter how much people keep saying it. Unsafe does not scope bugs to the block, or even where you have to look for bugs. Just having unsafe in your codebase means changing code outside the unsafe block could cause UB. Doesn't mean I think it's worth complaining about, there's really no better way for Rust to do this without sandboxing memory.
- vacuity 11mo agoInternal use of unsafe requires securing the safe code at the module boundary. However, the design of unsafe still greatly reduces the burden of memory safety, both when it is and isn't used directly. The specific semantics of Rust aside, unsafe is more or less the ideal way for a language to express unsafe escape hatch constructs.
- Capricorn2481 11mo ago> Internal use of unsafe requires securing the safe code at the module boundary Not even that, because you can pass data structures from unsafe code at arbitrary depth.
- vacuity 11mo agoIf the goal is to make a safe abstraction, which is what I'm talking about, proper use of visibility and safe code at the module boundary encapsulates the unsafe code soundly. You seem to be talking either about improper encapsulation or unsafe that is intended to be exported and used unsafely. Or perhaps some method that is not sound according to the language.
- Dylan16807 11mo agoIf changing the safe code causes UB, the actual bug is in the unsafe code.
- 11mo ago
- vacuity 11mo agoYour point about compile times is very dismissive and wrong, but I agree aside from that. It's worth noting that the Rust team explicitly tracks, monitors and limits regressions in, and actively optimizes for compile times, and Rust community surveys always ask for better compile times. This is clearly a significant issue, and while Rust is never going to compile as fast as C or Pascal, it can and will improve so that it becomes more usable.
- a022311 11mo ago> - Compile speed. Why do people care so much? Use debug for correctness and iterating your code. You're hardly going to change much between runs, and you'll get an incremental compile. Let rust-analyzer tell you if there are errors before you even try compiling. Let your CI do release optimization in its own time, who cares if CI is slow? Even if you know you're code compiles, it's often easier and faster to validate the logic or complex interactions by running the code. In large (and even not so large actually) projects, debug builds can be painfully slow, even on good hardware. It's important to have a tight feedback loop so that you can interate quickly.