30 ms·
I have a lot of criticisms of Rust's usability, but I think you're being pretty much just unreasonable here. One of the first things a Rust novice will see when
by pcstl 4y ago
I have a lot of criticisms of Rust's usability, but I think you're being pretty much just unreasonable here. One of the first things a Rust novice will see when picking up the language is:
let a = 1; // a is immutable
let mut a = 1; // a is mutable
Then a bit further in they will learn about references, and that there are two kinds of references:
a: &i8 // a is a immutable reference
a: &mut i8 // a is a mutable reference
I believe it is pretty clear that "mut" is what signals mutability, while "&" signals that something is a reference. There is next to no reason to associate "&" intrinsically with mutability, since you will have seen "mut" in a non-reference context and you will have seen "&" in a non-mutable context.
- iandanforth 4y agoThe OP is entirely about how `&` is misunderstood and misused, and how just adding `&` to appease the compiler is a common learner behavior. The author then explains `&var` and `&mut var` not in terms of their nature as references but in their aspects of mutability. Your view is the way understanding of the language should proceed, but I argue that it is not the reality in fact.
- pcstl 4y agoFair enough. I understood your phrasing more as a criticism of the language's design, and that is where I disagree, but I agree that the article could be structured better.
- ordu 4y ago> how just adding `&` to appease the compiler is a common learner behavior. If learner is unfamiliar with the very idea of references, then his/her problem is not an ampersand, but how to grasp the distinction between reference and value. Rust makes it hard, because it takes its own view on how variable relates with its value: Rust variable holding a value behaves much more like a reference to the value than a variable in C does. It is hard to notice with Copy+Clone types, like integers, but it bites in the ass with others. Variable in C is associated with its memory. When you write `int a;` you create a variable which has `sizeof(int)` bytes of memory. It doesn't work with Rust, a place in memory is an attribute of value not of variable. `let a: i32` doesn't allocate memory, memory will come with a value, when you assign the value to `a`. I mean it is hard to grasp at first. I came to Rust from a C world, and struggled to get this simple fact for a few months. It seems stupid in retrospect, it was written all over the place in Rust Book, but my mind took the relationship between a variable, memory and a value as a kind of an implicit dogma, and failed to notice how it breaks in Rust. But I digress. So variable in Rust has some properties of a reference. And then there are "real" references like &, &mut, RefCell, Rc/Arc. These didn't made my life harder, they work like my C-mind expected them to work, but I assume that people who come from a higher level languages can struggle to grasp all the differences.
- Dylan16807 4y agoUnless something gets optimized away, I'm pretty sure "let a: i32" will allocate memory on the stack exactly like C. Do you have some sources?
- ordu 4y agoBy default new types in Rust are not Copy, so when you pass values of these types around they are moved, not copied. It leads for example to freedom to do something like: fn move_things(a: SomePrettyBigType) -> EvenBiggerType When I was taught programming, I learnt that it is a bad thing, because passing big values to functions needs a lot of copying and is very slow. Not so with Rust. I personally did all the checks with emit=asm, and noticed how rustc passes an argument's address to a function (instead of copying an argument value) and one more address of a place, where function can build a value of EvenBiggerType. I never checked whether rustc preallocate memory for uninitialized variable or not. I bet it doesn't even in debug builds, because it knows in advance when variable is used. C compiler can work without this knowledge, but rustc cannot: it needs to check lifetimes and borrowing. Yes, it is normally seen as an optimization in C, but in rust many of C optimizations become a part of a language. > Do you have some sources? No, sorry, I have no source, my mental representation of rust code is a creation of my mind (being modest I'd add, that it is a second-hand creation probably, I'm not invented Rust, so someone thought of it before me, and I've read a lot what others think, probably I picked it up somewhere). But I can give you a link[1] to an article comparing C++ and Rust move semantics. There you can see the difference between "variable has no value" and "variable have a value that means 'moved out'". I see this difference as static vs dynamic tracking of "moved out" status (probably the article talks about it, I didn't reread it now and do not remember clearly). And I interpret it as a difference in a variable semantic: rust's variable has no memory, rust's values have. C++ variable on the contrary has a memory which is used to store value of the variable. I see it as a semantic differences of variables in Rust, because this semantics works. I can predict machine code generated, I can predict when borrow checker will become unhappy, I can track lifetimes in my mind. I mean a scope of a variable and a lifetime of a value are different things. I cannot imagine how anyone can think of a lifetime of a value without believing that memory occupied by a value is an attribute of a value. And at my first months of dealing with Rust I really tried to find a way. [1] https://www.thecodedmessage.com/posts/cpp-move/ https://www.thecodedmessage.com/posts/cpp-move/
- avgcorrection 4y agoYou write: > Take the first two sections as a perfect example. You decide you want to introduce a single-character control symbol `&` (which is questionable by itself), how do you apply it? In one case you decide that this control symbol indicates that a value is immutable and in another it's part of the declaration of a value as explicitly mutable. You've now introduced a semantic contradiction that a learner has to overcome. Here you write: > The author then explains `&var` and `&mut var` not in terms of their nature as references but in their aspects of mutability. - The angry, tired dog was running - The angry dog was running Does the “angry” cause confusion when trying to understand what “tired” means? `&` never has anything to do with mutability. Only `mut`. There is no “semantic” contradiction. “Weltschmerz” is a word, and “Welt” and “smerz” are two other words; the fact that they can occur in a compound noun doesn’t mean that “Welt” and “schmerz” by themselves get contaminated by each other. The fact that they chose to use `&mut` is… syntactic. The semantics would be the same if they used `& mut` or `reference mutable` or `reference which is mutable`. I’ve sprinkled some ampersands around Rust code in my little time but never because I was confused about how it interacted with mutability.
- emschwartz 4y agoFair point. I could have placed a greater emphasis on ownership and mutability being two separate axes. That said, I think you downplay the ways that references and mutability do interact in Rust. If there is a single outstanding reference to a value, Rust won't let anyone mutate the underlying value. I think this is quite an important part of Rust to understand that's not obvious to someone who's new and especially coming from a language that enforces no such guarantees about mutability.
- WalterBright 4y agoD's borrow checker simply keys off of the existing syntax: const a = 1; // a is immutable auto b = 1; // b is mutable const(int)* p; // pointer to const int* q; // pointer to mutable There's no new syntax, the borrow checker just adds a layer of checks.
- maccam94 4y agoRust references are basically pointers with extra rules, so using a different symbol is reasonable, and rust is immutable by default rather than opt-in (which is an important design decision) so you have to have syntax to mark things as mutable. auto is horribly uninformative for new coders, and var is too overloaded to expect newbies to only use it for mutable variables.
- WalterBright 4y agoD doesn't use `var`.