5 ms·
Rust safety is ultimately a productivity boost. For example, if I have a big string, I may create a hashmap where both keys and values are references to some p
by nercury 10y ago
Rust safety is ultimately a productivity boost.
For example, if I have a big string, I may create a hashmap where both keys and values are references to some portions to that original string.
Then, I may pass this hashmap to another function that will transform this hashmap into structs that contain reused portions of those string references.
Rust compiler will make sure that the original string is not destroyed or moved in any way in memory while this is happening.
While it is certainly possible to do this in C and C++, the development cost there is way higher. In C++, one would be sensible to stick to a slower version that copies and allocates data, unless he/she is really sure that the need for performance justifies the code complication.
Meanwhile, juggling the references this way in Rust is common and almost sloppy: the hashmap contains references to strings because it was probably created from iterator that iterated over references. The developer might not even need to notice it unless the string reference in result might be kept around longer than original. The compiler will tell about the type mismatch, and the developer will then create a new string from the reference, and then he/she will move on.
There is a similar story when such code needs to be refactored. The word "sloppy" still works here, but in a good way: offloading "being very, very careful" stuff to compiler is deliciously fun.
- Manishearth 10y agoI wrote about this concept a bit in http://manishearth.github.io/blog/2015/05/03/where-rust-really-shines/ http://manishearth.github.io/blog/2015/05/03/where-rust-real..., with an example of a situation where in Rust I was able to make things work but in C++ I'd be totally terrified and use a shared_ptr or something. I like to say that Rust lets you toe the line perfectly, and dance near it as much as you want. C++ does not, since you're afraid you may accidentally cross it.
- newsat13 10y agoIs that a joke? Just doing a cursory reading of your blog post was terrifying to me and I could hardly understand why things are so complicated. It almost make it seem like programming is some 'puzzle' (I feel same way about boost library).
- nercury 10y agoFew recent posts that I can see are about the compiler internals, design of a tracing GC and a crypto problem. These things might just be complicated anyway :)
- Manishearth 10y agoWhat did you find complicated or terrifying there? The fact that the code was complicated was sort of the point; the generic deriving code in the Rust compiler is in general a very tricky and confusing area and pretty complicated to deal with. In C++ I would have been very careful around code like this and not introduced new pointers. In Rust, I could do this without being afraid of memory issues. You're not supposed to understand the actual code in the blog post; there's heaps of context and explanations of compiler internals I didn't want to do. I tried to make it clear what task I wanted to do, and how the compiler helped me carry it out; the code is just there to give a better idea of what was going on. If you read closely I do mention that a lot of things should be ignored, there. The post also walks through the explanations of why the lifetimes work out that way, but that's more for the readers' edification -- I didn't need to actually figure anything out whilst working on it; the explanations are something I thought about later.
- sidlls 10y agoI'd argue that in order to properly evaluate your statements regarding C++ (and Rust, for that matter) it actually is important to understand the code and what you're trying to do. Given that there generally is more than one way to solve a problem it isn't unreasonable to think you found a solution that doesn't map (well) to C++ and from there generalize (perhaps incorrectly) that therefore it's impossible in C++ (with similar performance).
- Manishearth 10y agoWell, in this case there aren't multiple solutions -- my solution was literally the problem statement. I wanted to make a particular array accessible later in the pipeline in a specific API. That was the problem statement (the reason behind this problem was that the plugin API needed to be able to expose this array). This itself was pretty simple. The array arose from a particularly entangled bit of code. Possible ways to persist it are with a regular or smart pointer/slice to the vector, in both Rust and C++. This isn't an instance of the XY problem.
- yawaramin 10y agoC++ users would say that shared_ptr is the idiomatic way to handle this scenario, and it's no more unsafe than Rust is in general use.
- Manishearth 10y agoRight, but there's a runtime cost associated with it, unlike the borrowed pointer in the rust version. Using shared_ptr is not "toeing the line", it's stepping back from the line in fear you will cross it.