←back to thread

451 points birdculture | 3 comments | | HN request time: 0s | source
Show context
Animats ◴[] No.43979394[source]
It's like reading "A Discipline of Programming", by Dijkstra. That morality play approach was needed back then, because nobody knew how to think about this stuff.

Most explanations of ownership in Rust are far too wordy. See [1]. The core concepts are mostly there, but hidden under all the examples.

    - Each data object in Rust has exactly one owner.
      - Ownership can be transferred in ways that preserve the one-owner rule.
      - If you need multiple ownership, the real owner has to be a reference-counted cell. 
        Those cells can be cloned (duplicated.)
      - If the owner goes away, so do the things it owns.

    - You can borrow access to a data object using a reference. 
      - There's a big distinction between owning and referencing.
      - References can be passed around and stored, but cannot outlive the object.
        (That would be a "dangling pointer" error).
      - This is strictly enforced at compile time by the borrow checker.
That explains the model. Once that's understood, all the details can be tied back to those rules.

[1] https://doc.rust-lang.org/book/ch04-01-what-is-ownership.htm...

replies(17): >>43979460 #>>43979907 #>>43980199 #>>43981064 #>>43981313 #>>43981587 #>>43981720 #>>43982074 #>>43982249 #>>43982619 #>>43982747 #>>43983156 #>>43984730 #>>43988460 #>>43990363 #>>43996196 #>>44008391 #
xiphias2 ◴[] No.43981313[source]
I think the most important lesson is this:

Ownership is easy, borrowing is easy, what makes the language super hard to learn is that functions must have signatures and uses that together prove that references don't outlive the object.

Also: it's better not store referenced object in a type unless it's really really needed as it makes the proof much much more complex.

replies(1): >>43983830 #
echelon ◴[] No.43983830[source]
> Ownership is easy, borrowing is easy

100%. It's the programmer that needs to adapt to this style. It's not hard by any means at all, it just takes some adjustment.

replies(1): >>43984725 #
geodel ◴[] No.43984725{3}[source]
Indeed. Programmers are holding Rust wrong.
replies(1): >>43985189 #
echelon ◴[] No.43985189{4}[source]
Programmers new to Rust, you mean.

It's kind of like career Java programmers using JavaScript or Python for the first time and bringing their way of doing things.

replies(1): >>43986357 #
1. cmrdporcupine ◴[] No.43986357{5}[source]
It's more than that. Rust's value & reference passing semantics are completely different from the way most programmer's have trained their entire lives to think about it.

When you pass an argument to a function in Rust, or assign a value into a struct or variable, etc. you are moving it (unless it's Copy). That's extremely different from any other programming language people are used to, where things are broadly pass by value pass by reference and you can just do that as much as you want and the compiler doesn't care. It's as if in C++ you were doing std::move for every single argument or assignment.

And so as a programmer you have to shift to a mindset where you're thinking about that happening. This is profoundly unintuitive at first but becomes habit over time.

Then having that habit, it's actually a nice reasoning skill when you go back to working in other languages.

replies(1): >>44003199 #
2. int_19h ◴[] No.44003199[source]
I think sometimes that there's a niche for an alternative syntax for Rust that is generally more verbose (keywords instead of punctuation etc), and which specifically makes this behavior explicit. In other words, for every argument of every call you'd have to write "move" or "copy" and similarly with assignments etc.
replies(1): >>44008379 #
3. cmrdporcupine ◴[] No.44008379[source]
RustRover recently added visual indication of the borrowing process within a block of code, which is kind of nice. I think for now it only shows for some cases and only when there's an error? but still you get a highlight of where the borrow happened so you can walk back to it and figure out how to fix it without having the parse through the compile error.

I suspect they'll eventually get a fast and live indicator to the user of where all the references are "going" as they type.