www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How to make a global immutable associative array?

reply "dnspies" <dspies ualberta.ca> writes:
I want to create a global immutable associative array and have it 
be accessible from anywhere at compile-time.  How can I do that?

With:
immutable int[int] aa = [1:2,3:4];

I get:
source/thing.d(1): Error: non-constant expression [1:2, 3:4]

And with:
immutable int[int] aa;

static this(){
	aa = [1:2,3:4];
}

int c = aa[3];

I get:
source/thing.d(7): Error: static variable aa cannot be read at 
compile time

Also associative arrays don't seem to have a .idup

Is there any other way to do this?
Mar 18 2014
next sibling parent "Infiltrator" <Lt.Infiltrator gmail.com> writes:
On Wednesday, 19 March 2014 at 00:16:31 UTC, dnspies wrote:
 I want to create a global immutable associative array and have 
 it be accessible from anywhere at compile-time.  How can I do 
 that?

 With:
 immutable int[int] aa = [1:2,3:4];

 I get:
 source/thing.d(1): Error: non-constant expression [1:2, 3:4]

 And with:
 immutable int[int] aa;

 static this(){
 	aa = [1:2,3:4];
 }

 int c = aa[3];

 I get:
 source/thing.d(7): Error: static variable aa cannot be read at 
 compile time

 Also associative arrays don't seem to have a .idup

 Is there any other way to do this?

You just have to construct it first and then claim that it is unique and so safely cast it to immutable: import std.exception : assumeUnique; immutable int[int] aa; static this(){ auto temp = [1:2, 3:4]; aa = assumeUnique(temp); }
Mar 18 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
dnspies:

 I want to create a global immutable associative array and have 
 it be accessible from anywhere at compile-time.  How can I do 
 that?

 With:
 immutable int[int] aa = [1:2,3:4];

 I get:
 source/thing.d(1): Error: non-constant expression [1:2, 3:4]

 And with:
 immutable int[int] aa;

 static this(){
 	aa = [1:2,3:4];
 }

 int c = aa[3];

 I get:
 source/thing.d(7): Error: static variable aa cannot be read at 
 compile time

immutable int[int] aa; pure static this() { aa = [1: 2, 3: 4]; } void main() { int c = aa[3]; } Bye, bearophile
Mar 18 2014
prev sibling next sibling parent "Dan Killebrew" <danielk.misc gmail.com> writes:
 You just have to construct it first and then claim that it is 
 unique and so safely cast it to immutable:


 import std.exception : assumeUnique;

 immutable int[int] aa;

 static this(){
    auto temp = [1:2, 3:4];
    aa = assumeUnique(temp);
 }

Seems unintuitive and roundabout. Is this a bug or a feature?
Mar 18 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Dan Killebrew:

 Seems unintuitive and roundabout. Is this a bug or a feature?

It's a good feature. Generally immutable variables are initializable from strongly pure functions. If you think about what immutability and purity mean, it's a good match. Bye, bearophile
Mar 18 2014
prev sibling next sibling parent "Dan Killebrew" <danielk.misc gmail.com> writes:
On Wednesday, 19 March 2014 at 00:37:27 UTC, bearophile wrote:
 Dan Killebrew:

 Seems unintuitive and roundabout. Is this a bug or a feature?

It's a good feature. Generally immutable variables are initializable from strongly pure functions. If you think about what immutability and purity mean, it's a good match. Bye, bearophile

I meant something else. Why doesn't this work: immutable int[int] aa = [1:2,3:4]; Seems like it should work to me. After all, this works: immutable int[] a = [1,2,3,4]; So how is the second 'more constant' than the first? The fact that the first code block does not compile seems like a bug.
Mar 18 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Dan Killebrew:

 I meant something else. Why doesn't this work:

 immutable int[int] aa = [1:2,3:4];

 Seems like it should work to me. After all, this works:

 immutable int[] a = [1,2,3,4];

 So how is the second 'more constant' than the first? The fact 
 that the first code block does not compile seems like a bug.

If you meant defining directly the global associative arrays, it's a compiler/runtime limitation that will be removed. It's in Bugzilla since years. Bye, bearophile
Mar 18 2014
prev sibling next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 19 March 2014 at 00:16:31 UTC, dnspies wrote:
 I want to create a global immutable associative array and have 
 it be accessible from anywhere at compile-time.  How can I do 
 that?

 With:
 immutable int[int] aa = [1:2,3:4];

 I get:
 source/thing.d(1): Error: non-constant expression [1:2, 3:4]

 And with:
 immutable int[int] aa;

 static this(){
 	aa = [1:2,3:4];
 }

 int c = aa[3];

 I get:
 source/thing.d(7): Error: static variable aa cannot be read at 
 compile time

 Also associative arrays don't seem to have a .idup

 Is there any other way to do this?

Is an enum not appropriate? Because it can be used to push constants and available at ctfe. enum int[int] aa = [1: 2, 3: 4]; pragma(msg, aa);
Mar 18 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Rikki Cattermole:

 Is an enum not appropriate? Because it can be used to push 
 constants and available at ctfe.

 enum int[int] aa = [1: 2, 3: 4];
 pragma(msg, aa);

This is bad from an efficiency point of view. I think Don even suggested to disallow it. Bye, bearophile
Mar 18 2014
prev sibling next sibling parent "Meta" <jared771 gmail.com> writes:
On Wednesday, 19 March 2014 at 01:56:35 UTC, Rikki Cattermole 
wrote:
 Is an enum not appropriate? Because it can be used to push 
 constants and available at ctfe.

 enum int[int] aa = [1: 2, 3: 4];
 pragma(msg, aa);

This will create a new associative array at runtime wherever aa is used, rather than creating only one instance at compile time and referring to it wherever aa is used. This is also the case with normal arrays, and possibly objects... I can't remember.
Mar 18 2014
prev sibling next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 19 March 2014 at 04:10:21 UTC, Meta wrote:
 On Wednesday, 19 March 2014 at 01:56:35 UTC, Rikki Cattermole 
 wrote:
 Is an enum not appropriate? Because it can be used to push 
 constants and available at ctfe.

 enum int[int] aa = [1: 2, 3: 4];
 pragma(msg, aa);

This will create a new associative array at runtime wherever aa is used, rather than creating only one instance at compile time and referring to it wherever aa is used. This is also the case with normal arrays, and possibly objects... I can't remember.

Okay, well I learnt something.
Mar 18 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Wednesday, 19 March 2014 at 02:52:23 UTC, bearophile wrote:
 Rikki Cattermole:

 Is an enum not appropriate? Because it can be used to push 
 constants and available at ctfe.

 enum int[int] aa = [1: 2, 3: 4];
 pragma(msg, aa);

This is bad from an efficiency point of view. I think Don even suggested to disallow it. Bye, bearophile

It still only existing way to define compile-time usable AA value, disallowing it without fixing alternatives is not an option.
Mar 19 2014
prev sibling next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 19 March 2014 at 09:12:53 UTC, Dicebot wrote:
 On Wednesday, 19 March 2014 at 02:52:23 UTC, bearophile wrote:
 Rikki Cattermole:

 Is an enum not appropriate? Because it can be used to push 
 constants and available at ctfe.

 enum int[int] aa = [1: 2, 3: 4];
 pragma(msg, aa);

This is bad from an efficiency point of view. I think Don even suggested to disallow it. Bye, bearophile

It still only existing way to define compile-time usable AA value, disallowing it without fixing alternatives is not an option.

There might be another way depending on how good the compiler is at optimizing out pure functions. Because in theory it'll only call it once (did test in this context). But I don't know how it handles it within memory. property pure int[int] test() { pragma(msg, "hit"); return [1 : 2, 3 : 4]; } pragma(msg, test); pragma(msg, test); hit [1:2, 3:4] [1:2, 3:4]
Mar 19 2014
prev sibling parent "Don" <x nospam.com> writes:
On Wednesday, 19 March 2014 at 09:12:53 UTC, Dicebot wrote:
 On Wednesday, 19 March 2014 at 02:52:23 UTC, bearophile wrote:
 Rikki Cattermole:

 Is an enum not appropriate? Because it can be used to push 
 constants and available at ctfe.

 enum int[int] aa = [1: 2, 3: 4];
 pragma(msg, aa);

This is bad from an efficiency point of view. I think Don even suggested to disallow it. Bye, bearophile

It still only existing way to define compile-time usable AA value, disallowing it without fixing alternatives is not an option.

The only thing I've said we should disallow, is creating a runtime reference to a value which only exists at compile-time. I think it is logically nonsensical. I don't see any problem at all with creating a compile-time AA, and then looking up an index in it at compile time.
Mar 19 2014