Thread overview
Error with associative array initializer DMD32 D Compiler v2.070.0
Mar 03, 2016
MGW
Mar 03, 2016
Anonymouse
Mar 03, 2016
asdf
Mar 03, 2016
MGW
Mar 03, 2016
asdf
Mar 03, 2016
mahdi
Mar 03, 2016
Andrew Edwards
Mar 03, 2016
Ali Çehreli
March 03, 2016
immutable long[string] aa = [
   "foo": 5,
   "bar": 10,
   "baz": 2000
];

... Error: non-constant expression ["foo":5L, "bar":10L, "baz":2000L]
March 03, 2016
On Thursday, 3 March 2016 at 10:01:47 UTC, MGW wrote:
> immutable long[string] aa = [
>    "foo": 5,
>    "bar": 10,
>    "baz": 2000
> ];
>
> ... Error: non-constant expression ["foo":5L, "bar":10L, "baz":2000L]

I'm not sure there's a way around this except by initialising it at runtime. So you can't get it in the rom segment.

immutable long[string] aa;

shared static this() {
    aa = [
        "foo": 5,
        "bar": 10,
        "baz": 2000
    ];
}

March 03, 2016
On Thursday, 3 March 2016 at 10:01:47 UTC, MGW wrote:
> immutable long[string] aa = [
>    "foo": 5,
>    "bar": 10,
>    "baz": 2000
> ];
>
> ... Error: non-constant expression ["foo":5L, "bar":10L, "baz":2000L]

D associative arrays are a dynamic runtime feature, thus can't be initialized without runtime expressions. :(

This ended up failing too:

struct slot_t { char* key; long value; };

slot_t bogus[3] = {
        { "foo", 5L },
        { "bar", 10L },
        { "baz", 2000L }
};

import std.stdio;

void main() {
        bogus.map.writeln();
}
March 03, 2016
The citation from https://dlang.org/spec/hash-map.html

Static Initialization of AAs
----------------------------

immutable long[string] aa = [
  "foo": 5,
  "bar": 10,
  "baz": 2000
];

unittest
{
    assert(aa["foo"] == 5);
    assert(aa["bar"] == 10);
    assert(aa["baz"] == 2000);
}

Judging by the text, it is static initialization, during compilation.

March 03, 2016
On Thursday, 3 March 2016 at 10:35:50 UTC, MGW wrote:
> The citation from https://dlang.org/spec/hash-map.html
>
> Static Initialization of AAs
> ----------------------------
>
> immutable long[string] aa = [
>   "foo": 5,
>   "bar": 10,
>   "baz": 2000
> ];
>
> unittest
> {
>     assert(aa["foo"] == 5);
>     assert(aa["bar"] == 10);
>     assert(aa["baz"] == 2000);
> }
>
> Judging by the text, it is static initialization, during compilation.

Hey your right! https://dlang.org/spec/hash-map.html

I don't actually understand D that much but runtime logic made sense...

That unit test passes somehow, perhaps because unit test are executed? Looks like a bug in the test and/or documentation!
March 03, 2016
On Thursday, 3 March 2016 at 10:35:50 UTC, MGW wrote:
> The citation from https://dlang.org/spec/hash-map.html
>
> Static Initialization of AAs
> ----------------------------
>
> immutable long[string] aa = [
>   "foo": 5,
>   "bar": 10,
>   "baz": 2000
> ];
>
> unittest
> {
>     assert(aa["foo"] == 5);
>     assert(aa["bar"] == 10);
>     assert(aa["baz"] == 2000);
> }
>
> Judging by the text, it is static initialization, during compilation.

You have to put that definition inside body of a function (a declaration). it should not be placed inside module's root level code.
March 03, 2016
On 3/3/16 7:01 PM, MGW wrote:
> immutable long[string] aa = [
>     "foo": 5,
>     "bar": 10,
>     "baz": 2000
> ];

The only way this can be done outside the body of a function is if it is a manifest constant. This works:

enum long[string] aa = [
    "foo": 5,
    "bar": 10,
    "baz": 2000
];
March 03, 2016
On 03/03/2016 05:17 AM, Andrew Edwards wrote:
> On 3/3/16 7:01 PM, MGW wrote:
>> immutable long[string] aa = [
>>     "foo": 5,
>>     "bar": 10,
>>     "baz": 2000
>> ];
>
> The only way this can be done outside the body of a function is if it is
> a manifest constant. This works:
>
> enum long[string] aa = [
>      "foo": 5,
>      "bar": 10,
>      "baz": 2000
> ];

With the caveat that 'aa' is a manifest constant, meaning that its values will be placed everywhere 'aa' appears in code. So, the following loop *creates* an associative array at avery iteration:

    while (/* ... */) {
        if (aa[s] == 5) {  // <-- oops :(
            // ...
        }
    }

I think initializing it in a 'shared static this()' (or 'static this()') block is better:

immutable long[string] aa;

shared static this() {
    aa = [
        "foo": 5,
        "bar": 10,
        "baz": 2000
    ];
}

void main() {
    assert(aa["foo"] == 5);
}

Ali