View mode: basic / threaded / horizontal-split · Log in · Help
June 24, 2012
AA with immutable values
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?
June 24, 2012
Re: AA with immutable values
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
June 24, 2012
Re: AA with immutable values
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
June 24, 2012
Re: AA with immutable values
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
June 24, 2012
Re: AA with immutable values
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.
June 24, 2012
Re: AA with immutable values
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).
June 24, 2012
Re: AA with immutable values
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
June 24, 2012
Re: AA with immutable values
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.
Top | Discussion index | About this forum | D home