| ▲ | pron an hour ago | |
> I'd argue that the value of Rust is that it makes low-level viable for a lot of stuff that would otherwise require a lack of memory safety; a lot of it is stuff that might be written in a higher level language, but that's just because relatively few programs are impossible to write in higher level languages. Maybe, but I don't see making a low language viable for something it's not needed as offering much value. Low-level languages are primarily designed to give you direct, low-level control over interaction with the hardware, they sacrifice other things for that goal (including performance [1]), and so if I don't need that control I don't use a low-level language. When I do need that control, I find that Rust requires reaching for unsafe too frequently while still paying the full price for the safety of things I don't use (even Rust's memory management of strings doesn't give me the control I want; I have to work pretty hard for it). > The cost for memory safety in Java is performance overhead though, It's not performance (you often gain performance, especially in large programs). It's warmup and footprint. > But that doesn't change the fact that some languages objectively require you to opt into which parts are memory unsafe, and others don't. Like I said, C also fits in the category, so it's not a meaningful distinction. The difference is in what you can do in the safe subset. Zig lets you do more things in a safe way than C (where the safe subset is effectively empty), Rust lets you do more safe things than Zig, and Java lets you do more safe things than Rust. > You mentioned finding the fact that they actually produce real world software that in practice do not suffer from the class of bugs that C/C++ suffers from uninteresting I didn't say that that's uninteresting; in fact Zig also eliminates spatial unsafety as well as Rust, and I think that's good. I said that merely looking at broad statistics is uninteresting if you don't consider the kinds of programs being written. I.e. Rust gives me safety mostly when I write code with the same level of low-level control as I have in Java, then that's the part I find interesting. > You seem to be arguing that unless you can eliminate literally the most bugs of any language in existence, then eliminating any bugs by picking a language that eliminates some of them is a useless endeavor. That's the very thing I'm arguing against. I'm saying that different languages eliminate different bugs at a cost (again, Zig eliminates many memory safety bugs you'd find in C or even C++, arguably the most dangerous ones). What I'm saying is that what you get and whether the price is worth it depends both on the program you're writing and on your personal preferences. Just to be clear, "preferences" doesn't mean I care more or less about correctness, but which approaches to correctness I find more or less effective, something on which there is no consensus. > To me, the reasonable thing would be to choose a place to draw the line and say "anything beyond this is too risky, but I'll tolerate anything that's at least this safe", and memory safety is in practice the place I think it makes sense to do. I think it also depends on the kinds of programs you write, because for many programs I write (and for which I pick Java) Rust's level of memory safety is too low, and for the programs I pick a low-level language I wish I could have some cheap memory safety, but it's not offered to me. So in those cases I would prefer Zig's spatial memory safety, as it's no worse than Rust, and not pay the high price for Rust's while getting little in return. Anyway, I'm saying that it's both a matter of which approach you believe leads to better correctness and the kinds of programs you write in the language. [1]: For example, the fact that in Java, references are not required to be stable machine pointers opens the door to some powerful optimisations that are not available to languages where pointers are required to be machine pointers (or something close enough to them). Or the fact that low-level languages require that the machine instructions executed are those present in the compiled image (or close enough), or, if you want, caring about worst-case performance at the expense of average case performance (although both C++ and Rust specifically don't always make that easy) precludes some other very powerful optimisations. People like me who've spent years on huge C++ programs know that the low-level control offered by low-level languages (regardless of the question of safety) sometimes helps performance and sometimes harms it. | ||
| ▲ | saghm 18 minutes ago | parent | next [-] | |
> It's not performance (you often gain performance, especially in large programs). It's warmup and footprint. To me, those are also performance characteristics. Maybe my view on what constitutes "performance" is broader than average here. > When I do need that control, I find that Rust requires reaching for unsafe too frequently while still paying the full price for the safety of things I don't use (even Rust's memory management of strings doesn't give me the control I want; I have to work pretty hard for it). Fair enough, I can't tell you that you don't have that experience when writing Rust. It's pretty different from mine though, and the experience of the large number of former C/C++ devs I've worked with after they learned Rust; the only people I've talked to with that experience didn't really try to learn Rust and went in hoping that it wouldn't work for them, which informs my perception here, but I recognize that individual experiences won't always fit into larger trends. > Like I said, C also fits in the category, so it's not a meaningful distinction. The difference is in what you can do in the safe subset. Zig lets you do more things in a safe way than C (where the safe subset is effectively empty), Rust lets you do more safe things than Zig, and Java lets you do more safe things than Rust. I don't think I understand what you're saying here. I don't know of a way to turn off undefined behavior by default in C and only opt into it in discrete segements of the code, but maybe I'm missing something. > That's the very thing I'm arguing against. I'm saying that different languages eliminate different bugs at a cost (again, Zig eliminates many memory safety bugs you'd find in C or even C++, arguably the most dangerous ones). What I'm saying is that what you get and whether the price is worth it depends both on the program you're writing and on your personal preferences. Just to be clear, "preferences" doesn't mean I care more or less about correctness, but which approaches to correctness I find more or less effective, something on which there is no consensus. It seems like you're arguing against the idea of memory safety as a category at all then. To me, "I can't write code that's memory unsafe without explicitly opting into it" seems like an objective statement, and it's objectively different than "I can't write certain types of memory safety bugs in a given language". I don't really understand what's useful about being able to write memory unsafe code without having to opt in when in practice the number of bugs from mistaken memory safety are overwhelmingly more common than the cases when you're forced to opt into unsafe because Rust forced you to work around the constraints, and even in low-level programs, the actual number of truly unsafe operations you need to do tend to be fairly low in my experience. I guess I can't say for certain that you don't truly need to do things that you're forced to write unsafe for too often, but to me, it seems like you're refusing to pay a pretty small price for mostly ideological purity rather than pragmatism. > I think it also depends on the kinds of programs you write, because for many programs I write (and for which I pick Java) Rust's level of memory safety is too low > [1]: For example, the fact that in Java, references are not required to be stable machine pointers opens the door to some powerful optimisations that are not available to languages where pointers are required to be machine pointers (or something close enough to them). Or the fact that low-level languages require that the machine instructions executed are those present in the compiled image (or close enough), or, if you want, caring about worst-case performance at the expense of average case performance (although both C++ and Rust specifically don't always make that easy) precludes some other very powerful optimisations. I'm struggling to imagine what the circumstances are where these are genuine concerns rather than theoretical or premature optimizations. What are some examples of programs where you'd get better characteristics running them if they were written in Java rather than Rust due to the lack of enough "memory safety" in Rust? | ||
| ▲ | slopinthebag 34 minutes ago | parent | prev [-] | |
I just wanna give my perspective since I came from high level languages and pretty much exclusively use Rust now, so perhaps I can articulate why I find value in the language. And my apologies if my input is not wanted, no need to respond if so. First of all I respect your point of view - I'm not a Rust absolutist, I think that garbage collected languages are a massive advantage for a lot of things and would never criticise someone choosing a higher level language. Likewise I wouldn't criticise someone choosing Zig or Oden or Jai or even C for tasks where you really need that low level control. For me, I like to have a single language that I can use for pretty much everything. Afaik there is no other language that is a) popular b) has a modern toolchain with integrated build, formatting & linting etc, and c) can be used both in the kernel and for developing websites. Rust might not be the best choice for most of the spectrum of software, but it's good enough for everything. I can write a low level service + a web server and UI in the same language, where with other choices I would need to use two separate languages. This matters to me because I don't have the time to maintain mastery of multiple languages, I find a lot of value in focusing deeply on one language and learning it completely. Now I also don't write a lot of low level rust, I've never written a block of unsafe before and I probably write "unidiomatic" rust with too much copying, too many Arc<Mutex>>'s etc. But I like knowing that I can if I need to. Rust has a lot of other things going for it. A good type system with plenty of nice language constructs that are missing in a lot of higher level languages. It has Cargo and a healthy ecosystem (although I do worry about the number of dependencies used sometimes). And a large community of very smart people. I'm not saying this is exclusive to Rust, but as a whole Rust is a unique language with no alternatives if you value the things I do. So I would say that it's approach to memory safety threads the needle where it can be used (although not the very best choice) for when you'd use a higher level language, but also gives enough control that you can do plenty of low level stuff in it safely, and with clearly delineated unsafe sections where you really can do anything. | ||