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

Reply via email to