www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - AA with immutable values

reply "Roman D. Boiko" <rb d-coding.com> writes:
immutable(SomeClass)[S] _map;
_map[S.init] = null; // doesn't compile since _map[S.init] is 
immutable

My current workaround is:
immutable(SomeClass)*[S] _map;
_map[S.init] = [null].ptr;

But this introduces an additional level of indirection in a 
performance-critical part of my code.

Probably I could cast away immutable before storing, and cast 
back to immutable after retrieving. But I would be more happy 
without these two casts. (By the way, is it correct that this way 
would be more efficient?)

Is there any other way to put immutable values into a dictionary?
Jun 24 2012
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, June 24, 2012 13:57:44 Roman D. Boiko wrote:
 immutable(SomeClass)[S] _map;
 _map[S.init] = null; // doesn't compile since _map[S.init] is
 immutable
 
 My current workaround is:
 immutable(SomeClass)*[S] _map;
 _map[S.init] = [null].ptr;
 
 But this introduces an additional level of indirection in a
 performance-critical part of my code.
 
 Probably I could cast away immutable before storing, and cast
 back to immutable after retrieving. But I would be more happy
 without these two casts. (By the way, is it correct that this way
 would be more efficient?)
 
 Is there any other way to put immutable values into a dictionary?
Use std.typecons.Rebindable. - Jonathan M Davis
Jun 24 2012
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/24/2012 04:57 AM, Roman D. Boiko wrote:
 immutable(SomeClass)[S] _map;
 _map[S.init] = null; // doesn't compile since _map[S.init] is immutable

 My current workaround is:
 immutable(SomeClass)*[S] _map;
 _map[S.init] = [null].ptr;

 But this introduces an additional level of indirection in a
 performance-critical part of my code.

 Probably I could cast away immutable before storing, and cast back to
 immutable after retrieving. But I would be more happy without these two
 casts. (By the way, is it correct that this way would be more efficient?)

 Is there any other way to put immutable values into a dictionary?
Although it sounds like a limitation, it may be due to the fact that AA may need to rehash, which may not be suitable with immutable values. The following are two ways of generating immutable AA values that I can think of: import std.exception; class SomeClass {} class S {} void main() { /* By initialization */ immutable(SomeClass)[S] _map = [ S.init : null ]; /* By a function */ immutable(SomeClass[S]) makeMap() { SomeClass[S] result; result[S.init] = null; return assumeUnique(result); } /* Note that the entire AA is immutable: */ auto myImmMap = makeMap(); } Ali
Jun 24 2012
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, June 24, 2012 05:15:03 Ali =C3=87ehreli wrote:
 Although it sounds like a limitation, it may be due to the fact that =
AA
 may need to rehash, which may not be suitable with immutable values.
const and immutable types as elements of a container are problematic in= =20 general. The container generally needs to have been designed with them = in mind=20 for them to work properly - especially in D, where const and immutable = are=20 very strict, and you're not supposed to be mutating them even through c= asts. - Jonathan M Davis
Jun 24 2012
parent reply "Roman D. Boiko" <rb d-coding.com> writes:
On Sunday, 24 June 2012 at 12:21:50 UTC, Jonathan M Davis wrote:
 On Sunday, June 24, 2012 05:15:03 Ali Çehreli wrote:
 Although it sounds like a limitation, it may be due to the 
 fact that AA
 may need to rehash, which may not be suitable with immutable 
 values.
const and immutable types as elements of a container are problematic in general. The container generally needs to have been designed with them in mind for them to work properly - especially in D, where const and immutable are very strict, and you're not supposed to be mutating them even through casts. - Jonathan M Davis
Yeah, but I wonder that such a core feature as AA doesn't support this use case better (I mean more efficiently).
Jun 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, June 24, 2012 14:24:48 Roman D. Boiko wrote:
 Yeah, but I wonder that such a core feature as AA doesn't support
 this use case better (I mean more efficiently).
The current AA implementation is quite buggy. It works, but there are all kinds of corner cases which it doesn't handle properly. Part of the problem was that its implementation was shifted from the compiler to druntime, and it was done fairly poorly. A redesign is underway (none of which should affect its usage other than fixing bugs, since it should be entirely an implementation matter, not API), but it hasn't been completed yet. - Jonathan M Davis
Jun 24 2012
parent "Roman D. Boiko" <rb d-coding.com> writes:
On Sunday, 24 June 2012 at 12:34:28 UTC, Jonathan M Davis wrote:
 On Sunday, June 24, 2012 14:24:48 Roman D. Boiko wrote:
 Yeah, but I wonder that such a core feature as AA doesn't 
 support
 this use case better (I mean more efficiently).
The current AA implementation is quite buggy. It works, but there are all kinds of corner cases which it doesn't handle properly. Part of the problem was that its implementation was shifted from the compiler to druntime, and it was done fairly poorly. A redesign is underway (none of which should affect its usage other than fixing bugs, since it should be entirely an implementation matter, not API), but it hasn't been completed yet. - Jonathan M Davis
It would be nice to find a design which would not force the user to introduce an additional indirection (like I did in a workaround). This should not be a breaking change.
Jun 24 2012
prev sibling parent "Roman D. Boiko" <rb d-coding.com> writes:
On Sunday, 24 June 2012 at 12:15:10 UTC, Ali Çehreli wrote:
 Although it sounds like a limitation, it may be due to the fact 
 that AA may need to rehash, which may not be suitable with 
 immutable values.
Thanks, now I can see the motivation.
 The following are two ways of generating immutable AA values 
 that I can think of:

 import std.exception;

 class SomeClass
 {}

 class S
 {}

 void main()
 {
     /* By initialization */
     immutable(SomeClass)[S] _map = [ S.init : null ];

     /* By a function */
     immutable(SomeClass[S]) makeMap()
     {
         SomeClass[S] result;
         result[S.init] = null;

         return assumeUnique(result);
     }

     /* Note that the entire AA is immutable: */
     auto myImmMap = makeMap();
 }

 Ali
Unfortunately, this doesn't fit my use case. I needed this to memoize creation of immutable objects. I plan to not use AA in the future (it is possible to optimize, since the key is some string), so this is not a critical problem in my case. I was just wondering.
Jun 24 2012