3 ms·
Like with functional programming, I'm not sure it's hard, exactly. Maybe it's not so hard if you learn it from the start. It is very different, though. Most
by retrac 6y ago
Like with functional programming, I'm not sure it's hard, exactly. Maybe it's not so hard if you learn it from the start. It is very different, though. Most programmers are not used to the idea of carefully tracking where, and how, their data ends up in a program. Many high-level languages do heavy lifting to abstract that away as much as possible. Is it on the stack or in the heap? Is it a copy or a reference? How many references to it are floating around? You don't need to worry about that. The implementation will juggle that for you.
Rust is targeted pretty much as a C replacement. And the thing is, you have to do the borrow checker's work when you program in C too.
You must know whether it's copy-by-value or a reference. If it's a reference and it needs to be a copy, you must do that manually. You must know how many threads are accessing something by a reference, and you must guarantee that more than one thread is not writing a non-mutex variable at the same time. You must know when your objects are created, where they go (heap? stack?) and you must track those objects over their lifetime, and then you must free them at the end. (Or tell a garbage collector about them, and remember to run the garbage collector periodically.)
Except a C program still compiles when you don't get that right. And then it segfaults. Rust's borrowing model ends up enforcing much of that as language policy, rather than just good programming style. It's a bit like how you have to cast types explicitly in many languages (including Rust, of course). Any implementation can wrap an integer used as a pointer to guarantee you're not pointing into dead memory. But when the compiler knows the type explicitly, it can often generate fast unwrapped code that is safe and will not crash. All of this comes with explicitness which is burdensome to the programmer, unfortunately.
Sometimes you need to state, explicitly, what should be obvious to allow the compiler to show something is correct and fast. In this regard, Rust is, at least, nicer than C, even when you have to fight the borrow checker. (In my opinion.) Which is probably why it's growing so fast. I don't expect it to displace more than the C niche of systems programming, though.
- terminalserver 6y agoOne forgets how hard it was to climb the mountain once one has climbed the mountain.
- retrac 6y agoYou're right, in fairness. It's gruelling sometimes. Five years of on-off hobby programming with Rust and I still fight the borrow checker with every other function. How to implement things in a way that makes Rust happy is often not at all obvious. But the idea does seem useful enough to keep persisting at it.
- Measter 6y agoI'm really curious why some people have such a hard time picking it up. My experience has been the complete opposite, everything just clicked and it all made sense (at least, until you get to the gnarly stuff). What was the difference in our mental models that caused this?
- retrac 6y agoThe basic idea clicked pretty quickly with me. A restricted memory model that sort-of guarantees a number of awful things can't happen. Makes sense. But how do I express working things in it? The obvious approaches conflict with the rules. A simple emulator in a C-style might consist of a UI thread and a compute thread. The UI thread sends messages to the compute thread. You can have some timing though not usually safety/crash issues if you do this without locks. So maybe you do or don't lock that. But the UI thread can pretty wantonly read the compute thread's memory array to render it for graphics and may just get tearing like real hardware. Simple, fast, almost-safe. How do I express that sort of arrangement in Rust's type system and make it actually safe and fast? It's hard to get that right.
- zozbot234 6y ago> But the UI thread can pretty wantonly read the compute thread's memory array to render it for graphics and may just get tearing like real hardware. ... How do I express that sort of arrangement in Rust's type system and make it actually safe and fast? You can use atomic types with custom memory ordering, just like you would in C.
- pjmlp 6y ago> It's like with how people coming from much higher level languages tend to detest C at first, because you have pointers. It seems like needless complexity. You even have to hold C's hand to step through a simple linked list. Why?! WHYYYY?! Specially when that high level language was Ada, Modula-2, a Pascal dialect like Turbo/Quick Pascal, or a compiled BASIC, yes really "Why?! WHYYYY?!"