3 ms·
I'm in the camp that is long-term bullish on Rust. Memory safety is simply too important. I also consider C++ an unsalvageable mess at this point. Just a couple
by cletus 5y ago
I'm in the camp that is long-term bullish on Rust. Memory safety is simply too important. I also consider C++ an unsalvageable mess at this point. Just a couple of thoughts reading this.
> Compile Times
This is (IMHO) the biggest problem with Rust as the article mentions. Apparently, this was due to some early unfortunate design decisions that resulted from the tight coupling with early Rust and Servo. Rust at this point is heavily tied to LLVM (I'm aware there's a gcc version in the works).
If you don't know, the general structure is LLVM is to have a frontend and a backend. The frontend translates whatever your language is into LLVM-IR (intermediate representation), a sort of abstract assembly language. This isn't tied to any particular architecture (eg IIRC there are infinite registers in LLVM-IR). The backend translates that to a particular architecture. This is good because it's easier to get a compiler off the ground but gcc's performance is still second-to-none.
Rust expands macros and the likes by producing a godawful amount of LLVM-IR and lets the backend strip out what's not needed. This works but impacts compile times.
More details here [1].
> Complexity
Yes and no. It's a bit like how dynamic programming languages originally rose to prominence because of the speed you could do things, or at least that was the argument. Static typing was seen as getting in the way or being too complex. I've come to the conclusion that this is a false economy. The best way I can put it is in Python you end up writing unit tests for spelling mistakes.
The hierarchy of programming errors is IDE errors are better than compiler errors which are better than runtime errors. In an ideal world there's no difference between IDE errors and compiler errors but almost always there is.
So Rust is actually forcing you to move runtime multithreaded issues into being compiler errors. This feels like more work (because it is) but it is infinitely preferable. Opponents will say, for example, that C++ has smart pointers to denote ownership. This is true but they have a runtime cost. Rust doesn't. And the effect of a runtime error in C++ is typically a core dump or just weirdly inconsistent behaviour (which is often worse).
People routinely underestimate just how complex multithreaded code really is, particularly when they try and write lock-free abstractions (as is popular in C++) especially given the complexity of how processors actually work (eg out-of-order execution, branch prediction). There are various tools that are written to identify some of these issues (eg valgrind, asan, tsan, etc). While I was at Google I remember reading about how a bug had been found in an in-house written lock-free abstraction with some new tool that had been >7 years in production.
But yet, even on HN, I too often hear "what's so hard about just putting a mutex on it".
[1]: https://pingcap.com/blog/rust-compilation-model-calamity https://pingcap.com/blog/rust-compilation-model-calamity
- solomatov 5y ago>So Rust is actually forcing you to move runtime multithreaded issues into being compiler errors. This feels like more work (because it is) but it is infinitely preferable. Opponents will say, for example, that C++ has smart pointers to denote ownership. This is true but they have a runtime cost. Rust doesn't. And the effect of a runtime error in C++ is typically a core dump or just weirdly inconsistent behaviour (which is often worse). Rust has full set of smart pointers: Box (unique_ptr), Rc, Arc (shared_ptr), and in addition to it RefCell to work around limitations of borrow checker. All of these are very widely used in almost any real world project.
- formerly_proven 5y ago> If you don't know, the general structure is LLVM is to have a frontend and a backend. The frontend translates whatever your language is into LLVM-IR (intermediate representation), a sort of abstract assembly language. This isn't tied to any particular architecture (eg IIRC there are infinite registers in LLVM-IR). The backend translates that to a particular architecture. This is good because it's easier to get a compiler off the ground but gcc's performance is still second-to-none. Virtually every modern compiler is implemented using this approach - including GCC. GCC also used to be quite a lot slower than clang, but just like with error messsages, the GCC people have put a lot of work into it.