3 ms·
> One literal interpretation of Pike's quote is that message passing is different than sharing memory for pedantic reasons. Copying values between sender/receiv
by tapirl 2y ago
> One literal interpretation of Pike's quote is that message passing is different than sharing memory for pedantic reasons. Copying values between sender/receiver stacks is safer than sharing memory. But it is also possible to send values with pointers into channels, so that doesn't really prevent developers from abusing the model. I don't think avoiding shared memory is a top of mind consideration for developers deciding whether to use channels.
I think the point of Pike's quote is that, when a goroutine gets a pointer received from a channel, it gets the ownership of the values referenced by the pointer and other goroutines give up the ownership. This is a discipline Go programmers should hold but not a rule enforced by the language.
- jerf 2y agoAs I like to say, Rust may be one of the only languages that has built ownership right into its type system, but the problems that "creates" with programming in Rust are actually problems revealed by programming in Rust, not created. The ownership problems are 100% there in other languages too, it just isn't a compiler error. It can help everyone, in any threaded language, to be thinking like Rust, even if the compiler and type system do not directly help you. A simple and useful degenerate case of this is that whenever any message is sent, complete ownership of the entire transitively-reachable set of values contained in that message is by default transferred to the receiver. This is worthwhile even if you must explicitly construct some safe value to pass in order to maintain this promise. This keeps things generally easy to reason about without the full complication and power that Rust offers. At the very least, whenever I violate this, I have lots of comments about what and why on both sides of that transaction in my code base. (I do sort of wish there was a variant of a "go" statement that I could use that made me statically promise that all communication in and out of a given goroutine must be solely in the form of copied values, so I could guarantee that goroutine was an "actor". This is, admittedly, just me wishing very pie-in-the-sky. I doubt it could be turned into a practical proposal.)
- tick_tock_tick 2y agoTo be technical Rust "creates" a lot of errors that aren't their because it doesn't, and can't, have full understanding of the control flow. Well it's less create and more complains about non issues. It why overtime code that used to be invalid Rust has become allowed as they've improved the borrow checker.
- withoutboats3 2y agoThis remark isn't relevant to the subject under discussion. You're talking about the fact that Rust's lifetime analysis was initially a simple lexical check, and has evolved toward properly understanding control flow beyond just lexical scope (e.g. it is aware that both branches of an if/else cannot be taken). This has nothing to do with ownership, a completely separate part of the type system from lifetime analysis, and how it prevents data races by controlling the sharing of data between concurrent processes, which is what this discussion is about.
- samatman 2y ago> the problems that "creates" with programming in Rust are actually problems revealed by programming in Rust, not created. I would dearly like to see Rust advocates be more careful when they talk about this aspect of their beloved language. The ownership semantics of safe Rust programs prevent programs from being written, and in the process, eliminate entire classes of bug. But they also prevent a literally infinite number of correct programs from being written, without resorting to the unsafe escape hatch. Sometimes that's a good tradeoff. Often you can design your program around those restrictions and enjoy the benefits they bring. But what you said is much too strong a claim! Ownership semantics prevent or inhibit a great deal of simple patterns which are in fact possible to implement correctly. The doctrine that every difficulty a programmer runs into trying to color inside the lines of safe Rust is a case of Rust preventing them from doing something wrong, is simply incorrect. Rust's memory model is highly opinionated, and in fact, restrictive. The pitch, and it's a strong one, is that the benefits of working within that model are worth learning how to work within those restrictions. But it's also very clear that ownership semantics create problems as well as prevent them. Telling people that the tradeoffs are worth it is good advocacy. Pretending there are no tradeoffs is not.
- jerf 2y agoYeah, I feel like it's generally extraneous to my main point to observe that Rust isn't perfect at it, and it can be wrong, in consequential ways. My main point is, the general concept of ownership and having to care about it is present everywhere, though. If you prefer to say that it reveals it but imperfectly, I'm down with that. But I think it's important to understand it isn't entirely 100% responsible for creating it. Every shared-state threaded language has the issues, it just doesn't have a type system and compiler (imperfectly) helping you with them. It's not a license to write Go or any other language while oblivious to ownership issues just because the compiler won't complain.
- samatman 2y agoMy point wasn't actually that Rust's ownership model could be improved. While that's also true, features like being able to take disjoint mutable borrows of two fields of a struct are generally agreed to be good things to have, and I expect the language team to solve them eventually. It's simpler than that: Rust prevents you from doing a lot of correct things in the safe subset of the language. It does it for a good reason, because that lets the compiler prove a bunch of nice properties, but it's a fundamental tradeoff: in exchange for not having to deal with bugs in shared mutable access to data, it doesn't let you write programs that way. I actually think that Rust is a great choice for multithreaded programs which want to follow a one-writer-many-readers pattern, because that's very difficult to do correctly without the borrow checker. But when you say this: > The ownership problems are 100% there in other languages too, it just isn't a compiler error. A straightforward read of that is that anything you can't do in safe Rust is a bug. That's very far from true, it's in fact backward: what you can do in safe Rust isn't an ownership bug, by construction. But I see this implication reversed in a lot of Rust advocacy, and it directly contributes to the Rust fatigue which you'll see on this very website, and many other places. It's the difference between prohibiting potentially unsound ownership policies (what Rust does) and prohibiting only unsound ownership policies (which safe Rust does not). > My main point is, the general concept of ownership and having to care about it is present everywhere I completely agree with this, fwiw.