I'm on the train so I will be brief. I wanted to clarify a few things 1. the type hole appears in the language as it is today, not some hypothetical future without alias analysis or with regions. It occurred to me that this might not be obvious.
2. Making fields invariant but still allowing assignments that overwrite immutable fields would indeed give weaker guarantees but not quite as weak as I implied. For example a type @T would be immutable as declared. It is only references where the declared mutability of fields would have a murky meaning (I think, anyway) 3. Regarding structural types, I shouldn't have dragged them into this. :) There are many ways to address the verbosity of mutable fields, of which nominal record types are but one. Hope that makes sense. I can clarify more when I am not typing on my phone. :) Niko -------- Original message -------- Subject: Re: [rust-dev] RFC: Addressing Dan's bug through immutable memory From: Niko Matsakis <[email protected]> To: Marijn Haverbeke <[email protected]> CC: "[email protected]" <[email protected]> On 2/8/12 6:54 AM, Marijn Haverbeke wrote: > That seems a rather heavy-handed restriction. Perhaps? All I am saying is that assigning to value types that contain immutable fields is illegal, because it overwrites those immutable fields. You can declare the record like: let x = {mutable a: 10}; x = {mutable a: 20}; if you wish to allow mutability. The fact that this notation is painful is more a by-product of using structural record types than anything else. An alternative is that declaring a field as immutable does not in fact mean that it will not be overwritten. We could make that sound (no covariance, for example), but it means we (and the language's users) have to ultimately treat all fields as potentially mutable. So I'm not sure what the point is. Maybe there are other alternatives? > How about this: > let x = @{mutable y: 10}; > let f = fn@(u: int) { x.y = 20; log(error, u); } > f(x.y); // Where f's arg is passed by reference, whichever > notation you'd use for that Yes, this is precisely the kind of problem I was looking for! Well, this example itself I think is ok: it prints "20" (the wonders of aliasing). But an example like this: let x = @{mutable f: some(10)}; let f = fn@(o: option<int>) { alt o { some(f) { x.f = none; log(f); } } f(x.f); is certainly bad. We basically have to treat && mode as potentially mutable for the purposes of matching in alt statements. So the mutability algorithm from mut.rs needs to be somewhat adjusted to yield a 3-way answer: immutable, const, or mutable (actually I can't recall if it does this already or not). One annoyance is that we don't have a way to express a reference to some arbitrary immutable field. Moving to something like regions would allow a type modifier `&` that supported `const` and `mut` just like `@`, which would make it possible to express that (above, `o` would have type `&const option<int>`: `&option<int>` would be a type error, as that would mean a ptr to immutable memory, and `x.f` is not immutable). Niko
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
