←back to thread

177 points signa11 | 2 comments | | HN request time: 0s | source
1. olvy0 ◴[] No.42162033[source]
This is exactly what I thought about rust when trying to learn it a few years ago. I'm also an experienced C++ programmer. After trying for 3-4 months and constantly fighting the borrow checker, I lost all motivation and gave up.
replies(1): >>42163193 #
2. goku12 ◴[] No.42163193[source]
Rust borrow checker rules are a bit weird and unintuitive. But if you are a systems programmer (C or C++) and think a bit about the borrow checker complaints, you'll find that they almost always correspond to memory safety bugs like use-after-free or invalidated references. All you need to think is about what might happen if the code was accepted (this is for C/C++ programmers, since GC-based language programmers don't face those often). The same mistakes can happen in C and C++ too - but without the BC to back you up. In essence, there is no escape from those exact same rules.

There are a few genuine cases which the BC won't accept, though they may be valid. The first case is of data structures containing cycles (like dequeues, ring buffers, closed graphs, etc). The other is cross-FFI calls. This is due to the fact that the BC simply doesn't have the intelligence to reason about them (at compile-time). Even then, Rust gives you 2 types of escape hatches - runtime safety checks (using Rc, Cell, etc) with a slight performance impact, and manual safety checks (unsafe) when performance is paramount. All that's expected of you (the programmer) is to recognize such cases and use the appropriate solution.

I'm not too surprised when non-C/C++ programmers struggle with BC rules. They may be unfamiliar with the low-level execution semantics. But I'm surprised when C/C++ programmers fail to make the connection. I was a C++ programmer too and this is the first thing I noticed. Memorizing the BC rules is the absolute worst way to learn it. You should be looking for memory safety problems and correlating them with BC error messages instead. I know this works because I trained non-systems (non-C/C++, primarily JS and Python) developers in Rust. They picked up the execution and memory semantics quickly and easily made sense of the borrow checker idiosyncrasies.