(If I'm going to learn a new system programming language, which one should I pick?)
(If I'm going to learn a new system programming language, which one should I pick?)
In short, I thought Rust was "we solved the pain of this difficult thing." However, it is not really a novel solution to the difficult thing, but simply a decision to undertake it.
I've now moved to evaluating Nim and D, and while I've barely dabbled in them (mostly going through the docs and writing some simple example-like code), I can at least say that Rust is likely to be much more controversial and polarizing than these languages. I recommend giving it a try - go through the official "book" which serves as the main documentation. If you survive lifetime annotations without finding them too obnoxious, then you'll probably like Rust.
Personally, I find Rust's extreme rigorousness (and the laboriousness that follows from that) makes it very niche, and I find myself rather unexcited about using it for anything.
The annotations have, for the most part, faded into the background for me. I don't find them to be particularly pervasive in the code I write, and when I do need them, it's usually to fix a reasonably straight-forward case where the compiler failed to elide them. With that said, in the years I've been using Rust, I have committed one or two lifetime-related bugs. (No memory unsafety resulted, of course, but it did result in data being annotated with a shorter-than-actual lifetime.)
> In short, I thought Rust was "we solved the pain of this difficult thing."
Part of the pain that Rust purports to solve is the significant reduction (and debugging thereof) of memory unsafety errors. In return, you must deal with the pain of an ownership and borrowing system, which might present challenges to patterns you may have used in another language. The benefit is that you have a compiler to tell you when you've mis-stepped instead of an end user filing a bug report (or worse).
Other than lifetime annotations, I have a couple other niggling issues with it but I suspect it's because I haven't fully grasped certain things yet, and so I'll refrain from commenting on them for the moment.
Rust is newer (though being used in some big projects like Firefox/Servo, Visual Studio Code's search functionality now uses it by default, etc), has (afaiu) a more powerful type system, and is entirely memory-safe by default. However, this makes it somewhat harder to learn at first, and it also has a relatively slow compiler. It follows ML-style languages a bit more, with things like pattern matching and sum types built into the language.
Personally, I prefer Rust, because it feels like a stronger foundation with the ML-like type system and no GC. YMMV though, depending on what is important to you.
I guess your original comment was maybe meaning how D enforces (the "normal" definition of) memory safety differs to Rust? In any case, I read over both of those, and, to me, they both seem to essentially be a slightly less general version of Rust's scheme (possibly independently invented), rather than something very different. I'm interested to hear how you think they specifically differ to Rust.
There's no notion of "borrowing" in D nor any notion of "only one mutable access at a time".
Well… it's relatively slow in release mode, but C++ compilers can often be slower. GHC is always slower :D
In other words, if you're looking to replace/supplement your C use: go Rust. If you're looking to replace/supplement your C++ use: probably go D, with some caveats towards actual use.
Note: I like both languages, but do prefer Rust for my personal use cases.
Some details here... every language other than assembly languages has some amount of runtime. This is Rust's: https://github.com/rust-lang/rust/blob/master/src/libstd/rt.... (as you allude to, many people refer to this amount of runtime as "no runtime" since it's very, very small.)
You could also consider some other things as part of a runtime; for example, by default on most platforms, Rust includes jemalloc. That can be removed, though not in stable Rust. Same with the standard library code, which can be removed for libraries, but not binaries just yet (due to a small technicality regarding the stability of some attributes.) Things that do this are likely to use some of Rust's other unstable features at the moment, so it's not generally a burden to do so, and those interfaces rarely change right now.
How are you defining "runtime" such that this statement is correct?
I see a distinction between a runtime library and a language runtime. The former is just a set of convenient routines for interacting with a specific platform. The latter is something that runs alongside your program to facilitate its execution, like a JIT or an interpreter.
The key is, you are doing the injecting in asm.
Anyway, your distinction is pretty solid. Most people just use "runtime" to mean either one, and then rely on the context to disambiguate.
I REALLY ENJOYED D1, REALLY! (CAPS 11). D1 was like C, but better. It was heavenly. D2 is like C++, but better. Not my cup of tea though. Give it a spin for a day or two. I'm sure you'll like it if you like C++. Trouble arises, as with all niche languages, when you try to move to production and you have to source libraries and/or support.
I would say that I have found it to be more of a problem on Windows. That'd because the general C/C++ package management solution on Windows is quite... Old fashioned, and that's not always a D specific problem.