How mutable is immutable?

Timon Gehr timon.gehr at gmx.ch
Wed Oct 17 09:02:08 PDT 2012


On 10/17/2012 01:49 PM, Don Clugston wrote:
> On 01/01/12 13:50, Timon Gehr wrote:
>> On 01/01/2012 10:40 AM, Denis Shelomovskij wrote:
>>> So, I'm a function `f`, I have an `immutable(type)[]` argument and I
>>> want to store it for my friend `g` in an TLS variable `v`:
>>> ---
>>> string v;
>>> debug string sure;
>>>
>>> void f(string s) { v = s; debug sure = s.idup; }
>>> void g() { assert(v == sure); }
>>> ---
>>> I also store a copy of `s` into `sure` for my friend to ensure immutable
>>> date hasn't been mutated.
>>> Can my friend's assertion ever fail without breaking a type-system?
>>> Sure. Just consider this:
>>> ---
>>> void main() {
>>> auto s = "abba".idup;
>>>     f(s);
>>>     delete s;
>>>     g();
>>> }
>>> ---
>>> Is it by-design? Looks like deleting immutable (and const because of
>>> implicit conversion) data should be prohibited.
>>> OK. Let `delete` be fixed. Can we still fail?
>>> ---
>>> void h() {
>>>     immutable(char)[4] s = "abba";
>>>     f(s);
>>> }
>>> void main() {
>>>     h();
>>>     g();
>>> }
>>> ---
>>> Damn! So, what can we do with it? Not sure, but I have a proposal.
>>>
>>> Fix it in language:
>>> * disallow `delete` of const/immutable data
>>> * disallow immutable data on the stack
>>>
>>> This makes data really immutable if I don't miss something. Anyway, I
>>> want `immutable` qualified data to be immutable without breaking a
>>> type-system (if one do it, its his own responsibility), so some changes
>>> should be made (IMHO).
>>
>> You are using unsafe language features to break the type system. That is
>> not the fault of the type system.
>>
>> '@safe:' at the top of the program should stop both examples from
>> working, it is a bug that it does not.
>
> That's the point -- *which* checks are missing from @safe?

Escaping stack data and arbitrarily freeing memory are not operations
found in memory safe languages.

> But I'm not sure that you're right, this looks broken to me, even
> without @safe.
>
> What does it mean to create immutable data on the stack? The stack is
> intrinsically mutable!

So is the heap.

What does it mean to garbage collect immutable data?

What does it mean to allocate an 'int' on the stack?

> What does it mean to delete immutable data?

Deallocate the storage for it and make it available for reuse.
Accessing it afterwards leads to arbitrary behaviour. This is the same
with mutable data. As the program may behave arbitrarily in this case,
it is valid behaviour to act as if immutable data changed.

> I think it's reasonable for both of them to require a cast, even in
> @system code.
>

The implementation of the 'scope' storage class should be fixed. We 
could then require an unsafe cast(scope) to disable prevention of stack 
address escaping. Rust's borrowed pointers may give some hints on how
to extend 'scope' to fields of structs.

As to delete, delete is as unsafe when the involved data is immutable
as when it is mutable. Why require an additional cast in one case?



More information about the Digitalmars-d mailing list