> > The most ironic part is that so many restrictions and problems are likely to provoke people to rely on whatever option happens to work, which might not be the best/safest one
> Programs written in Rust are empirically safer than programs written in C or C++.
But Rust defines safety as being safe from the kinds of errors that the Rust compiler is capable of making one safe from (buffer overflows, race conditions, undefined behaviour, etc).
If one if distracted by trying to satisfy the borrow checker, they might overlook a logical error. People have limited concentration, patience and perseverance and usually have to work to deadlines.
Rust is great for writing high-performance code, or code that needs to be parallelised within a single process. However if performance is not a concern then a statically typed language with a GC is usually a better choice.
> If one if distracted by trying to satisfy the borrow checker
That distraction goes away with experience. Once you "get" how to structure ownership in the program in a borrow-checker friendly way, it stops being a problem.
Similarly, if you are used to dynamically typed languages, you may find static typing a distraction that tests your patience. But OTOH if you think in types and use design patterns for them, they become a tool to improve code reliability, not an obstacle.
In this case, safer == memory safety (which is not a Rust-specific thing), not general forms of correctness, and the comparison in the original comment is to C and C++, not statically typed languages with a GC.
Unless it has been edited, the original comment doesn't say memory safety, it says "so many restrictions and problems are likely to provoke people to rely on whatever option happens to work, which might not be the best/safest one". The reply to that comment then interprets safety as memory safety and compares to C and C++. This is kind of my point.
Rust defines safety as memory safety, but unfortunately memory safety is only the tip of the iceberg when it comes to safety. Logic errors are just as pernicious.
Programmers have a natural bias towards solving problems with technical solutions, but for me, Rust's memory safety is achieved at the cost of a high productivity penalty and a moderate readability penalty. Both of these reduce my ability to understand and manually verify the code.
Whereas languages that achieve memory safety via a GC, allow me to focus my mental energy on writing correct code, not on memory management.
> Whereas languages that achieve memory safety via a GC, allow me to focus my mental energy on writing correct code, not on memory management.
Ownership type systems are supposed to rule out synchronization errors (say, data races), which is something you may want regardless of how memory is managed. Say, the research on ownership types that came out of MIT in early '00s worked with a subset of Java (see OOPSLA'02 "Ownership Types for Safe Programming: Preventing Data Races and Deadlocks").
> If one if distracted by trying to satisfy the borrow checker, they might overlook a logical error.
I see it the other way around. I let the compiler deal with the borrow and type checkers and to tell me what I missed, while I focus on the logic of the code.
> Rust is great for writing high-performance code
Some high-performance code is CPU bound. To approach advertised FLOPS figure on any modern CPU, you must manually write SIMD code (typically SSE, AVX, and/or NEON). It’s only in Rust nightly, and is very limited. Without SIMD, you’ll only use a small fraction of CPU’s computational power.
The only programming languages great for high-performance code are C and Fortran. C++ is also OK because C compatibility.
One response I received to that argument was “not many projects need to multiply a lot of single-precision floating point matrices”.
Later additions, SSE2, SSE 4.1, SSSE3, add double-precision floating point, and 8-16-32-64 bit integers support. Some of them come with unsigned and saturated versions (the latter clips to min/max when overflown).
In C++, I use these for performance-critical functions doing integer computations, bit manipulation, image processing (saturated integer math is especially useful for the latter). While it adds some complexity to the code esp. when it benefits from SSE 4.1 or SSSE3 instructions (I must implement SSE2-only workarounds for older CPUs), the performance improvement IMO justifies that.
> and is very limited
You might be thinking of the `simd` crate, in which case, you're right. But we are getting closer and closer to exposing a large set of vendor intrinsics: https://github.com/rust-lang-nursery/stdsimd --- You can use it today on Rust nightly. This includes runtime CPU feature detection!
ripgrep is an example of a program that is written in Rust, is CPU bound and uses explicit SIMD in various places to speed up text search. (It hasn't moved to stdsimd yet and is still using the `simd` crate and the old platform intrinsics system exposed by rustc. But ripgrep will move to stdsimd soonish.)
Very good.
Finally, someone in Rust community realized we don’t want higher-level abstractions, we just want whatever the hell our hardware can do. If that thing will go stable, I will consider Rust for a next project (BTW, doing CAD/CAM stuff for Windows).
Feature detection is no big deal, it’s just a couple of lines in C.
But I’m curious how well that thing gonna work in practice? In C++ we have low-level control over memory layout allowing to place these SIMD vector values in STL containers with correct alignment. We have function pointers with vectorcall calling convention that enable implementing CPU-dependent routines very efficiently. The compiler inlines a lot of that SIMD code. Maybe you know how much of that applies to rust + stdsimd?
> Finally, someone in Rust community realized we don’t want higher-level abstractions, we just want whatever the hell our hardware can do. If that thing will go stable, I will consider Rust for a next project (BTW, doing CAD/CAM stuff for Windows).
That's great, but please consider that this is an unfair characterization. stdsimd has been in the works since 2016, and many people have been involved. It's not like nobody "realized" we needed to expose vendor intrinsics before then, but it just hadn't been worked on. It's a ton of work.
> Feature detection is no big deal, it’s just a couple of lines in C.
It's only a few lines in Rust as well. But this is spoken like someone who uses it instead of someone who was involved in making it available. :-) It's not just about querying the CPU, but enabling functions to compile with specific target and also reasoning through Rust's safety story there, which is non-trivial.
> But I’m curious how well that thing gonna work in practice? In C++ we have low-level control over memory layout allowing to place these SIMD vector values in STL containers with correct alignment. We have function pointers with vectorcall calling convention that enable implementing CPU-dependent routines very efficiently. The compiler inlines a lot of that SIMD code. Maybe you know how much of that applies to rust + stdsimd?
I don't see any reason why any of that would be a problem with Rust. Inlining is just as important to Rust as it is to C++, and so is control over memory layout. You should try it out and give feedback. :-) Now would be the time!
> It's not like nobody "realized" we needed to expose vendor intrinsics before then, but it just hadn't been worked on.
It had been... in 2015. :)
Errm, d'oh, sorry! :-( I had vendor intrinsics stuck in my head, but now that I say that, I of course now remember the platform intrinsic stuff.
> Rust is great for writing high-performance code, or code that needs to be parallelised within a single process. However if performance is not a concern then a statically typed language with a GC is usually a better choice.
Are there Rust programmers who disagree with that?
It depends on context.
I don't think many would disagree that it would be easier, but better is very broad. Better in what way? For what purpose?
For example, if you already know Rust, then "easier" may (or may not, depending on what sense of easy you mean!) not be a compelling argument.
Rust is certainly not the best tool for every single task, but it also has broader applicability than "I can't possibly accept a GC."
I use Rust for all sorts of things that don't need to be high performance, because I know Rust very well. But I don't think it's the ideal choice for most of those tasks--although I will say that I wish more languages had (for example) the same approach to namespacing that Rust takes, or as nice of a package manager, those are things that could coexist with a very different language. I imagine most Rust programmers would agree...