Immutability vs reference types

Francois Chabot francois at chabs.ca
Mon May 27 18:20:10 PDT 2013


On Tuesday, 28 May 2013 at 00:35:32 UTC, Diggory wrote:
> On Tuesday, 28 May 2013 at 00:24:32 UTC, Francois Chabot wrote:
>> Hello, I'm trying to get back into D again. This time around, 
>> I'm
>> playing mostly with concurency and parallism, all the while
>> trying to get my code writen in "the D way" as much as 
>> possible.
>>
>> I've run into a rather major road block that seems rather
>> nonsensical at face value, so I'm not sure if i'm 
>> misinterpreting
>> the nature of immutability...
>>
>> Here's kinda what I WANT to do:
>>
>> class DataChunk {  }
>>
>> struct DepPassResult {
>>     immutable( DataChunk ) target_chunk ;
>>     immutable( string ) [] foundDeps ;
>> }
>>
>> immutable( DataChunk )[ string ] chunk_db ;
>>
>> void doWork( const string[] chunks , int workers_count ) {
>>     auto workers = new TaskPool( workers_count ) ;
>>
>>     foreach( chunk ; chunks ) {
>>       _workers.put( task!doDepPass( chunk_db[ chunk ] , 
>> thisTid )
>> )
>> ;
>>     }
>>
>>     bool all_done = false ;
>>     while( !all_done )
>>     {
>>       receive(
>>          ( DepPassResult r ) { ... } ,
>>          ...
>>       ) ;
>>     }
>>
>>     workers.stop() ;
>> }
>>
>> void doDepPass( immutable( DataChunk ) data , Tid main_thread 
>> ) {
>>     ...
>>      main_thread.send( DepPassResult( data , [ "whatever" ] ) 
>> ) ;
>> }
>>
>> Obviously, there's a lot more to it, but that's enough to
>> illustrate my problem.
>> DepPassResult is being rejected as a valid Variant type (only 
>> at
>> run time might I add) because it's not re-assignable. Fair 
>> enough.
>>
>> I have a few easy options at my disposal, but all of them seem
>> pretty bad to me:
>> 1. DepPassResult.target_chunk could be made a string, but that
>> would require DataChunk to be aware of the index value it has 
>> in
>> chunks_db.
>> 2. DepPassResult.target_chunk could be made a pointer, which 
>> just
>> screams workaround.
>> 3. DepPassResult.target_chunk could be made a slice that by
>> convention will only ever point to an array of 1 DataChunk
>>
>> It's the fact that #3 works that kills me.
>> If with immutable(Type)[], I can have a re-assignable reference
>> to arrays of immutable data, I really should be able to have 
>> some
>> form of syntactical equivalent for single instances. But there
>> just doesn't seem to be one. Immutability for reference types
>> seem to always apply both to the referenced data as well as the
>> reference itself no matter what.
>>
>> Considering how critical immutability is to concurency and
>> paralellism in D, that seems like a pretty big missing piece of
>> the puzzle. I've got to be overseeing something here. Please 
>> help.
>>
>> It looks like Michel Fortin did some work on this years ago
>> (though for completely unrelated reasons):
>> http://forum.dlang.org/thread/bug-5325-3@http.d.puremagic.com/issues/
>>
>> Did this ever pan out? or has some form of equivalent or 
>> standard
>> work-around been established?
>
> This is still a known problem with no nice solution. One other 
> possibility is making DataChunk a struct and then make two 
> classes, MutableDataChunk and ImmutableDataChunk which contain 
> mutable and immutable versions of that struct respectively. You 
> can use "alias this" on each class to automatically forward 
> calls to the inner struct.
>
> I haven't tried this out myself so there may be other problems 
> doing it this way but it's something to consider at least.

I'm afraid that I'm not sure how this would help my case. 
DepPassResult would still need an mutable reference to an 
ImmutableDataChunk. And that's just not allowed since structs can 
only be used in send/receive if all their members are immutable. 
So we'd need a immutable( ImmutableDataChunk ) and we'd just be 
back at square one, just with an additional layer of indirection.

Another thing I could do would be rework std.concurency's usage 
of Variant so that it only ever constructs Variants without ever 
re-assigning them. But that would be a lot of work just to work 
around something that should be functional in the first place.


More information about the Digitalmars-d-learn mailing list