Isolated by example

via Digitalmars-d digitalmars-d at puremagic.com
Fri May 2 02:41:45 PDT 2014


I like it a lot, as it solves several problems elegantly! Some 
comments inline...

On Friday, 2 May 2014 at 06:51:49 UTC, deadalnix wrote:
> An isolated is consumed when:
>  - it is returned
>  - it is passed as argument
>  - it is assigned to another island

Assignment and passing to a scope variable can be exempt from 
this rule.

>
> When an isolated goes out of scope without being consumed, the 
> compiler can free the whole island:
>
> void foo() {
>   A a = new A(); // a is isolated if A's ctor allows.

I guess the condition is that assignment to isolated is allowed 
only from a unique expression. Thanks to Walter's recent work, 
this is now inferred in many cases. But I guess in cases where it 
cannot be inferred (.di files come to mind), it needs to be 
annotated explicitly:

     class A {
         this() isolated;
     }

>
>   // a is not consumed. The compiler can insert memory freeing.
> }
>
> As we can see, it allows the compiler to do some freeing for us 
> to reduce GC pressure. Manu why aren't you already here 
> cheering ?

To make this more useful, turn it into a requirement. It gets us 
deterministic destruction for reference types. Example:

         ...
         isolated tmp = new Tempfile();
         // use tmp
         ...
         // tmp is guaranteed to get cleaned up
     }

>
> When an isolated is consumed, the island it is in is merged 
> into the island that consumes it. All reference to the island 
> become write only until next write.
>
> void foo() {
>   A a = new A(); // a is isolated
>   immutable b = a; // a's island is merged into immutable
>
>   // a's island has been consumed. a is not readable at this 
> point.
>   // a.foo() // Error
>   a = new A(); // OK
>   a.foo(); // OK, we have written in a.
> }

This needs more elaboration. The problem is control flow:

     isolated a = new A();
     if(...) {
         immutable b = a;
         ...
     }
     a.foo(); // <-- ???

(Similar for loops and gotos.)

There are several possibilities:

1) isolateds must be consumed either in every branch or in no 
branch, and this is statically enforced by the compiler.

2) It's just "forbidden", but the compiler doesn't guarantee it 
except where it can.

3) The compiler inserts a hidden variable to track the status of 
the isolated, and asserts if it is used while it's in an invalid 
state. This can be elided if it can be proven to be unnecessary.

I would prefer 3), as it is the most flexible. I also believe a 
similar runtime check is done in other situations (to guard 
against return of locals in @safe code, IIRC).

> I hope the idea get across better with some sample code and 
> will be considered. As sample code shows, isolated do not need 
> to be specified explicitly often. User not annotating can get a 
> lot of benefit out of the concept right away.

That's true, but it is also a breaking change, because then 
suddenly some variables aren't writable anymore (or 
alternatively, the compiler would have to analyse all future uses 
of the variable first to see whether it can be inferred isolated, 
if that's even possible in the general case). I believe it's fine 
if explicit annotation is required.


More information about the Digitalmars-d mailing list