Am 13.11.2012 12:00, schrieb Walter Bright:
> 
> By operating on the expression, a lot more cases can be handled.

Yes, but _only_ doing that, the unique property is lost as soon as the 
expression crosses the
statement border - then the type system somehow needs to take over. But 
extending its capabilities
using this is certainly a win.

> 
>> That is, except for shared data. Allowing shared data
>> greatly improves its flexibility for passing data between threads.
>>
>> But because it guarantees that the type cannot contain non-unique data, it 
>> can allow multiple
>> dereferences and still guarantee that no references are shared. Only 
>> immutable (or shared)
>> references can be extracted. Everything else can only be copied or moved, 
>> keeping everything
>> isolated.
> 
> Allowing shared access into the middle of something means that unique 
> pointers cannot be implicitly
> cast to immutable.

Not to immutable, but it may still be moved to another thread without 
copying/locking etc. Since
this can be easily checked at compile time, in my current implementation, the 
freeze() method of
Isolated!T is only available if T is strongly isolated (i.e. does not contain 
shared references).

> 
> The other trouble is doing assignments into the isolated data. What if you're 
> assigning to a
> pointer, and the pointer value is pointing outside of the isolated graph?
> 

The trick is that an Isolated!T value only has references to immutable or other 
Isolated!U data. So
assigning to any field will never violate the isolation. Assigning to an 
Isolated!U field requires a
move().

> 
>> The result is, I think, more usable because a) shared data is allowed and b) 
>> step-by-step
>> construction of unique data is possible naturally without constantly moving 
>> a unique pointer around.
>> What makes the C# system usable are mostly the automatic uniqueness-recovery 
>> rules, and I think
>> those can only be implemented by the compiler (setting apart AST macros ;) ).
> 
> I think we can do this with __unique(Expression), which is not a pervasive 
> change to the compiler,
> it's fairly isoloated (!). That construct would perform the "recovery". I 
> implemented a little bit
> of this in NewExp::implicitConvTo().
> 

But how can it do recovery across a statement boundary?

Anyways, it was partly a moot point on my part, as the Isolated struct can 
simply make sure to
expose only fields that are safe (i.e. POD, immutable or Isolated fields). 
Those can be freely
changed without violating isolation and thus no explicit recovery is even 
necessary. But other
fields with references to mutable or shared data are still difficult to handle.

Reply via email to