←back to thread

452 points birdculture | 1 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 #
ajross ◴[] No.43980199[source]
The second bullet in the second section is overpromising badly. In fact there are many, many, many ways to write verifiably correct code that leaves no dangling pointers yet won't compile with rustc.

Frankly most of the complexity you're complaining about stems from attempts to specify exactly what magic the borrow checker can prove correct and which incantations it can't.

replies(2): >>43983423 #>>43996681 #
zigzag312 ◴[] No.43983423[source]
A great teaching technique I learned from a very good match teacher is that when explaining core concepts, the simplified definitions don't need to be completely right. They are much simpler to grasp and adding exceptions to these is also quite easy compared to trying to understand correct, but complex, definitions at the beginning.
replies(1): >>43983565 #
ajross ◴[] No.43983565[source]
Yeah, but the whole purpose here is "flattening the learning curve", and telling people code will work when it won't is doing the opposite.

That bullet, at its most charitable, defines the "idealized goal" of the borrow collector. The actual device is much less capable (as it must be, as the goal is formally undecidable!), and "learning rust" requires understanding how.

replies(3): >>43983582 #>>43984026 #>>43987333 #
zahlman ◴[] No.43987333[source]
> Yeah, but the whole purpose here is "flattening the learning curve", and telling people code will work when it won't is doing the opposite.

"Flattening the learning curve" is perhaps a wrong metaphor - you can't actually change what needs to be learned; you can only make it easier to learn.

Saying something that is usually right and can be corrected later is a standard pedagogical approach - see https://en.wikipedia.org/wiki/Wittgenstein%27s_ladder . To extend the metaphor, the ladder is there to help you climb the learning curve.

replies(1): >>43987432 #
ajross ◴[] No.43987432[source]
It's not "usually right" though. Rust can't compile a doubly-linked list[1] without unsafe!

And people trip over this immediately when they start writing Rust, because that kind of code is pervasive in other environments. Thus statements like "Rust just doesn't like dangling pointers" are unhelpful, because while it's true it's not sufficient to write anything but the most trivial code.

[1] Or basically any graph-like data structure that can't be trivially proven to be acyclic; even lots of DAG-like graphs that "should" be checkable aren't.

replies(1): >>43987945 #
zahlman ◴[] No.43987945[source]
People write non-trivial code all the time without worrying about that sort of thing. Quite a lot can be done with plain tree structures. In the real world, your data is flat and even your conventions for interpreting it as non-flat (such as, say, JSON) only create trees that perhaps simulate back-links with another informal protocol.
replies(1): >>43988863 #
ajross ◴[] No.43988863[source]
Sigh. The whole premise of the linked article is, in fact, that people hit validation problems with the borrow checker early on when learning rust and that attention is needed to "flatten the learning curve" to assist their understanding of what we all agree is a unique and somewhat confusing set of semantics relative to competing languages.

Rust flaming is just so terribly exhausting. No matter how reasonable and obvious a point is there's always someone willing to go to the mattresses in a fourty-comment digression about how Rust is infallible.

replies(1): >>43990278 #
zahlman ◴[] No.43990278{3}[source]
... Would it help you to know that I don't even use Rust (although I'm interested in picking it up), and in fact have complained on HN before about program performance and other features being invalidly attributed to "it's written in Rust"? Especially in the Python ecosystem, that being my primary programming language?

I'm not making anything like the argument you seem to think I am. I'm only making a pragmatic observation about what real-world coding is like, based on my own experience.

replies(1): >>44003262 #
1. int_19h ◴[] No.44003262{4}[source]
You should try picking up Rust, and then, based on your Python experience, see how quickly you run into one of those cases that GP is talking about. It's unlikely to take long.