Besides, if I don't want automatic memory management, I could also use Ada or Freepascal, who are both reasonably safe, though not generally as safe as Rust, and are mature and have a well-established toolchain.
Besides, if I don't want automatic memory management, I could also use Ada or Freepascal, who are both reasonably safe, though not generally as safe as Rust, and are mature and have a well-established toolchain.
In Rust, on the other hand, once you gain some experience at least, you don't think about memory management that much, until the compiler tells you how your strategy is wrong, and then you adapt your strategy to cope with it. This is very different from C/C++, where typically your program just crash at random when you get it wrong, and then you have to figure out where or how it's wrong.
And yes, mature and well-established are nice features. On the other hand, I can tell you that modern tooling like cargo, even if not quite as mature and well-established, can also bring large productivity benefits with it. Dependency tracking and build systems are largely a solved problem in Rust.
I would argue that memory management in Rust is a much smaller burden then you might expect, bit it's still there.
Some responses:
- ownership / clone vs move = Valid concern in any imperative language.
- stack vs heap / when things are freed = Nope. Things are freed when you no longer use them. Are you upcasting to a parent "class"? Use `Box::new(value)`. Otherwise there's no cognitive overhead.
I come from C++ and I've written quite a lot of Python. Rust feels a lot more like a typed Python than C++, memory-wise.
C != C++, because in the latter you can use smart pointers - just like in Rust.
> Dependency tracking and build systems are largely a solved problem in Rust.
I wouldn't say so, especially since incremental compilation is still an experimental feature only available in nighty. And tracking objects dependencies across crates isn't even possible ATM.
I meant dependency tracking in terms of which libraries you need what versions of. Incremental compilation as a project in nightly is about improving compile times only, not about any functional change in build system/project management tooling. In this context, I'm not sure what you mean by tracking objects across dependencies.
Keeping compile times to a minimum is an essential task of a build system for me. That's why I wouldn't say that "build systems are a solved problem" in Rust.
> In this context, I'm not sure what you mean by tracking objects across dependencies.
When I make a change in one file in a crate, this triggers a complete rebuild of all the dependent crates.
That's the same thing as incremental compilation.
While that is what good C++ programmers do, you cannot (sadly) prevent others to program just like in C.
// We don't need unsafe here
or
print!("This is NOT unsafe");
So you'd want a static analyzer anyway.
With Rust, or any other systems safe language for that matter, I can be assured that any code that violates the type system is contained in such blocks.
In C or C++ written in C style, any string, vector, function call with out parameters, data structure manipulation can be hiding unsafe code.
It is quite different just having to review some well defined sections than the whole program.
However I do concede all of this fails flat when using third party binary libraries.
I do enjoy using C++ since C++ARM days, already back then many of the modern C++ practices were possible after templates got added into the language, yet enterprise "C compiled with C++ compiler" code is the norm in many companies.
Specially since many don't even bother to write type safe C++ wrappers and call C APIs directly.
Even though it's controversial, I think this is why it's a good thing Rust can't #include a C header directly (requiring bindgen to make a crate). The community has put work into making safe abstractions over the raw C.
grep /^unsafe(\s\{)|(\sfn)|(\strait)|(\simpl)/
Some variation of that, or four individual greps. I forgot how to use OR properly in Regex but each of those works individually. Tested on regex101 [0] against the following code: unsafe {
// Scary stuff...
}
unsafe trait Scary { }
unsafe impl Scary for i32 {}
unsafe fn danger_will_robinson() {
// Scary stuff...
}
That should catch all four instances that unsafe can be called in without any false positives. Since `fn`, `trait` and `impl` are keywords they won't change. Of course, any comments should be removed beforehand in case of a commented out unsafe block.I did this as a learning experience because I either regex101 doesn't properly implement /g or I don't understand capture groups. :D
That's an overstatement. You can use smart pointers in C++, but they're not at all equivalent to the usability of Rust's pointer abstractions.
For example, Rust is able to have the Rc/Arc split, allowing for increased performance in single-threaded code. You can't do that with shared_ptr, or at least, not in a way that's checked like in Rust.
1 - http://blog.skylight.io/rust-means-never-having-to-close-a-s...
In C++ the rules are enforced by optional tooling that most developers don't use.
At CppCon 2015, only 1% of the audience acknowledged using such tools at Herb's talk about the core guidelines.
The only difference is that you need to deal with whether or not things go on the heap, are refcounted, etc (but this decision is in the types, so you make it once and are done). Whether or not that's "manual" depends on your point of view. I consider it to be more along the lines of choosing guarantees.
(I know this isn't quite the same thing as liballoc on nightly)
The process is mostly automatic because you don't have to manually free the memory you use like you do in C. The difference is that the moment when the memory must be freed is determined at compile time by Rust, while a dynamic GC has to determine this at runtime, which uses more resources but also ends up being easier to use.
I've never worked with Rust, so I may be horribly wrong. Based on what I understood, it's a more than what you say: resources are freed at a time determined by the source code, no random involved, thus you get GC and RAII at once.
Not necessarily. D has a garbage collector and is used in games already such as Quantum Break. I do audio processing and had to limit GC usage in audio callbacks of course, but it was far from a showstopper.