This isn't going to be appealing to Rust current users though, because “fighting the borrow checker” is a learning curve issue, you don't fight the borrow checker anymore once you've internalized its rules.
> or making gratuitous copies of data to satisfy the borrow checker.
You get it backward. In Rust there's less gratuitous copies, not more, because the ownership rules and the borrow checker gives you compile-time guarantees, while “defensive copies” are common in C++ for instance, “to be safe”.
I still fought the borrow checker after a year of using Rust.
And I found many situations while using Rust where I either needed to clone, or use unsafe where it's easier to make a mistake than in other languages because the syntax is extremely unergonomic and the memory semantics are much less clear.
> I still fought the borrow checker after a year of using Rust.
That's interesting. How much Rust did you use during that year? And how level of proficiency did you reach?
> And I found many situations while using Rust where I either needed to clone, or use unsafe
That sounds like an uncommon trade-off. From my experience, the trade-off was usually “clone or put lifetime parameters everywhere”, which is annoying (and I really wish Rust analyzer could help with at some point, because it's pretty mechanical), but it was quite rare, because most of the time you can just move things (that is transferring ownership), unlike in C where you have either a copy or a pointer.
> or use unsafe where it's easier to make a mistake than in other languages because the syntax is extremely unergonomic and the memory semantics are much less clear.
This is unfortunately true. Miri helps, but there's a wide margin for improvement on that front.
For the first one, something between: “I was learning Rust on my spare time” and “I was working full time in a Rust-centric team”. And the second one is more subjective, about how confident you considered yourself with the language and how familiar you felt with its concepts.
I'd say that after using Rust for a year I also fought the borrow checker, but after using Rust for 6 years I definitely don't anymore. A lot of the difference between a year and 6 was unlearning C++ habits.
For Self referential struct, the typical answer is twofold:
- try to design your code not to need them.
- if you really need one, you can either use smart pointers (Rc & RefCell) or use unsafe and use the Pin API to be sure that you won't accidentally move your struct.
That being said, it's not easier in C (or at least, it's easier to write, but also very easy to misuse), since a memcopy will silently break your self-referential struct. Do Zig has “Copy constructors” like C++ to avoid this issue?
In most situations those are horrible non-solutions.
Ref counted cells can't be used in self-referential structures because you'll introduce cycles. So, you'll go through all this trouble just to make memory leaks in the end.
"Designing your code not to need them" usually means implementing a worse version of a data structure from first principles.
The only real answer is to write "unsafe" Rust here and there. Which is fine. But, to the prevailing Rust community that is absolutely heretical.
> Ref counted cells can't be used in self-referential structures because you'll introduce cycles. So, you'll go through all this trouble just to make memory leaks in the end.
You know about Weak references right?
> "Designing your code not to need them" usually means implementing a worse version of a data structure from first principles.
> The only real answer is to write "unsafe" Rust here and there. Which is fine.
If it's a specific “data structure” (1% of the time) and not just the way you've decided to structure your current code (99% of the time), then using unsafe is fine.
> But, to the prevailing Rust community that is absolutely heretical.
No, the rust community is totally fine with reasonable unsafe code (you don't see burntsushi being harassed for using unsafe in his crates for instance), rustaceans hate (to a point which leads to excessive behaviors) unsound code, like the Actix drama, where the author used unsafe in unsound ways (not checking invariants in any way, and declaring “safe” functions that could cause segfault is used incorrectly). But unsafe code used properly is fine.
Yes, I'm aware of weak references and I'm aware that they're not a universal solution to this problem. You risk having something removed as unused while it's actually still being used if you don't have some strong reference to it somewhere.
As to your assertion that this is only '1%' of code, it really depends on what you're doing. If you're just gluing together modules that's where linear types for memory are an applicable model. But, if you are actually designing some structure yourself, it's not an applicable model.
The Actix 'drama' is reason alone to avoid the rust 'community'. I'll wait for these features to make it in a language with better ergonomics, a large commercial backer, and professionals at the helm who are less religious about how mere mortals use their language and are willing to err on being more pragmatic about it.
> Yes, I'm aware of weak references and I'm aware that they're not a universal solution to this problem. You risk having something removed as unused while it's actually still being used if you don't have some strong reference to it somewhere.
In graphs yes, but we're talking about self-referential structure here, and there you don't face this risk: the self-reference should always be a weak reference (the struct should be dropped when and only when the external references are gone, the internal ones don't count).
> As to your assertion that this is only '1%' of code, it really depends on what you're doing. If you're just gluing together modules that's where linear types for memory are an applicable model. But, if you are actually designing some structure yourself, it's not an applicable model.
Either you're implementing a data structure from a research paper (and you're in the 1% case and unsafe is fine) or you are actually using such a data structure and you don't have to perform this gymnastic by yourself. In C, people tend to reimplement data structures in their project because the dependency management story is quite dated, but it's not something anyone else does in other languages: most of the time you just import the standard library's data structure (or someone else's) and call it a day.
> The Actix 'drama' is reason alone to avoid the rust 'community'.
You'll find internet mobs in any group of people, unfortunately…
> I'll wait for these features to make it in a language with better ergonomics, a large commercial backer
If you expect larger backers than Amazon, Microsoft, Facebook and Google combined[1], I think you'll need to hold your breath much too long for your own good…
> and professionals at the helm who are less religious about how mere mortals use their language and are willing to err on being more pragmatic about it.
You're confusing redditors (the actix stuff took place on /r/rust) and the language management…
> In graphs yes, but we're talking about self-referential structure here, and there you don't face this risk: the self-reference should always be a weak reference (the struct should be dropped when and only when the external references are gone, the internal ones don't count).
Graphs are a common example of a self-referential structure.
> Either you're implementing a data structure from a research paper (and you're in the 1% case and unsafe is fine) or you are actually using such a data structure and you don't have to perform this gymnastic by yourself. In C, people tend to reimplement data structures in their project because the dependency management story is quite dated, but it's not something anyone else does in other languages: most of the time you just import the standard library's data structure (or someone else's) and call it a day.
On the several occasions I've look for crates that do what I need. They either don't exist, or I read through the code and they're poorly written and make lots of gratuitous copies of data and are very inefficient. You also have people using crates.io for their blog, literally.
> If you expect larger backers than Amazon, Microsoft, Facebook and Google combined[1], I think you'll need to hold your breath much too long for your own good…
A few people at large companies doing resume driven development isn't a real investment. It's not from the top down. At best, you could say they have some R&D investment to hedge their bets.
> You're confusing redditors (the actix stuff took place on /r/rust) and the language management…
Then why doesn't this sort of thing happen with other communities which are also highly online? It doesn't matter if you try to do gate keeping to say "oh those redditors" or "oh those guys on hackernews" aren't the REAL Rust community, the end result was a real package being really deleted from the real Rust community.
This isn't going to be appealing to Rust current users though, because “fighting the borrow checker” is a learning curve issue, you don't fight the borrow checker anymore once you've internalized its rules.
> or making gratuitous copies of data to satisfy the borrow checker.
You get it backward. In Rust there's less gratuitous copies, not more, because the ownership rules and the borrow checker gives you compile-time guarantees, while “defensive copies” are common in C++ for instance, “to be safe”.