6 ms·
Currently fighting the borrow checker. My project has not moved much this last week due to an issue I just can't understand. Have rewritten the offending code
by kramerger 3y ago
Currently fighting the borrow checker.
My project has not moved much this last week due to an issue I just can't understand. Have rewritten the offending code 4 times but it always fail to compile somehow.
At this point, I am only staying with Rust because of the ergonomics of enum and iterators. The memory safety stuff is 90% writing safe code then fighting the compiler to agree with you.
:(
- deleted 3y ago[deleted]
- chrismorgan 3y ago> The memory safety stuff is 90% writing safe code then fighting the compiler to agree with you. This isn’t my experience, from a decade of occasionally watching and helping others learn Rust, personally and professionally. Rather, it’s normally writing code that you believe is safe, wrestling with the compiler and finally realising that it was right all along, or giving up before reaching this stage but it was still. There are certainly some cases where this isn’t the case, and this article talks about the most common and most notorious one, but seriously, the compiler is normally right. Somewhere along the way, things click and your intuitions subsequently almost always match the compiler’s, and you have a much happier time of it, seldom needing to wrestle. And your coding in other languages tends to improve, or at least focus on ownership more in ways that tend to make later maintenance easier.
- kstrauser 3y agoMe, writing a thing in Python: La, la-la, la-la. Me, writing it in C: Grumble, grumble, la-la-la. Me, writing it in Rust: I HATE THIS THING WHY DO YOU oh hey I'd been thinking about this all wrong. I go through that cycle all the freaking time. At first, I'm irked that Rust is being such a pain in the neck. Then I give in and do things the way it wants me to, and realize that it's genuinely much better that way, even if I then take that approach back to Python. At the least, now I'm more aware of when I'm counting on the garbage collector to atone for my sins.
- 4death4 3y agoYour “experience” (bias?) is easily falsified. Obviously memory issues happen all the time in unsafe languages, but even then, not nearly at the frequency that a novice Rust user will conflict with the borrow checker. The article we’re commenting on is literally about safe code that the borrow checker fails on.
- oconnor663 3y agoIf you could put your project up on GitHub or similar, I'd be happy to take a look at the errors. Otherwise without knowing anything about your specific situation, any chance this helps? https://jacko.io/object_soup.html https://jacko.io/object_soup.html
- yodsanklai 3y agoUse OCaml if you can live with a GC.
- armchairhacker 3y agoDepending on the issue you could get away with either using unsafe code or just using a RefCell (if you can’t convince the compiler a mutable reference isn’t being shared, wrap it into a RefCell and then you have a shared reference that you can do mutable operations on.)
- dehrmann 3y ago> I am only staying with Rust because of the ergonomics of enum and iterators Don't other languages have things that are close enough?
- logicchains 3y agoHave you tried asking GPT4 for help? It understands Rust fairly well, and can also explain what's going wrong quite clearly.
- pgwhalen 3y agoI haven't used GPT4 to help with any borrow checker issues, but just yesterday I figured out how to make my FFI use case work in about 3 minutes after asking. I'd been struggling with it for hours.
- dimgl 3y agoIs your problem domain relevant to low-level programming? Because if not, I would drop Rust immediately and just go with an easier language.
- tkz1312 3y agothere are many excellent languages that have adts (and much more) without having to deal with the borrow checker. Maybe give ocaml or haskell a try :)
- estebank 3y agoFWIW, you can also write Rust without having to "deal" with the borrow checker either. A common problem I see from experienced programmers picking up Rust is trying to write code with minimal allocations, before learning enough of the language to properly represent them (or whether the pattern can be represented) in safe Rust. I recall an argument I got into with a colleague who was adamant that boxing closures was the wrong call and spent an inordinate amount of time trying to represent a pattern that wouldn't work without doing so. Or the time I myself spent a lot of time trying to return borrowed values when in hindsight I should have called .to_owned() once and spared the time I spent looking for an allocation-free alternative. (Cow would have worked in that case, but I didn't have the experience to know that for sure, and today I wouldn't have chosen it because it would have made using the API more cumbersome than needed.) A lot of the borrow checker problems go away if you're ok with allocations, storing trait objects on the heap, making your ADTs not have references, etc. But getting familiar with the language enough to know "this requires unsafe or for<'a>" takes a while.
- baq 3y agoThis is not fighting the compiler, this is writing code in a way which can be proved to be safe. Some code can be safe but is hard to reason about. The compiler tells you that. The solution is, unsurprisingly but perhaps disappointingly, to stop writing code like that.
- Animats 3y ago> Some code can be safe but is hard to reason about. This is a point I made back when I was doing verification. Yes, you can write code for which termination cannot be proven. If termination for your code is theoretically undecidable, it probably won't work right anyway. So don't go there. Microsoft took a hard line on this with their Static Driver Verifier, a proof of memory correctness system for Windows kernel drivers. If your driver code is so hard to analyze that automatic path analysis can't verify memory correctness, it doesn't get signed to run in kernel space. Driver-caused Windows kernel crashes, formerly a huge problem, mostly went away.
- kramerger 3y agoWhat you basically wrote is that my problems would go away if only I wrote code that the compiler approves.. But that is not easy, and much of that is due to the complexity of Rust and the way it handles memory safety. Which is where fighting the compiler comes in.
- baq 3y agoYeah I get it, I was there. It is super hard if you actually know C/C++ or mastered a GC language. Rust won’t like some patterns at all and will fight you. The point is, there are replacements for those patterns that are safer, about as performant and simultaneously easier to reason about by both you and the compiler. To stop fighting, you must switch to them. Old ways will not work. This is by design and a key point of Rust. A single, concrete example: do not use references in object graphs. Use an array and indexes into it. If you have a dynamic structure with many additions and deletions, use generational indexing.
- mcronce 3y agoIf it's not a project under NDA, like another user, I'd be happy to put eyeballs on it and help you work out the errors
- bsder 3y agoAdd more braces. Not joking. I find that a lot of Rust borrow checker problems can be solved by inserting more blocks. At the very least, it helps you isolate precisely where the issue is. I don't see this recommendation often for how much it seems to help beginners. To be fair, it's a lot less of an issue than it used to be as the borrow checker has gotten quite a bit better.
- Georgelemental 3y agoRead https://quinedot.github.io/rust-learning/lifetime-intuition.html https://quinedot.github.io/rust-learning/lifetime-intuition...., the solution to your issue is probably in there
- kramerger 3y agoI read that and honestly I can't see how that article could improve anything. The author goes into a bunch of other issues or uses his own terminology, which makes things even more confusing.
- Georgelemental 3y agoIf you have gone through the entire guide and are still stumped, I would suggest asking for help on https://users.rust-lang.org/ https://users.rust-lang.org/ (Not sure what you are referring to wrt the terminology)
- dontlaugh 3y agoIt’s ok to box or use Arc.
- Cloudef 3y agoI rewrote my rust project in zig. Final nail to coffin was finding out static building is basically unsupported and cross-compiling is even more annoying. Ended up with way smaller codebase, the code is more readable and im more confident about it because im aware wherever memory is allocated and where it isnt. Async in rust is also complete mess and mixing async / non async is not fun. I dont even want to start on the meta-programming and traits which needs a degree on rust to get started.