On Sunday, October 29, 2017 22:24:57 Nordlöw via Digitalmars-d-learn wrote:
> Shouldn't associative arrays with key types (K) having mutable
> indirections (std.traits.hasAliasing!K) such as
>
>      string[ubyte[]]
>
> be disallowed?
>
> If not, in what cases do we want this?

Well, the built-in associative arrays _are_ kind of a mess (though the
situation has improved somewhat over time), but the way that this was
handled does make _some_ sense, even if it's still not correct. If you had
something like

string[ubyte[]] aa;
pragma(msg, (typeof).string);

This will print

string[const(ubyte)[]]

So, similar to C++'s std::map, const gets added for you underneath the hood
for the keys, which does prevent _some_ bad assignments. Unfortunately,
that's still not enough - it really should be immutable. For instance,

void main()
{
    string[ubyte[]] aa;
    ubyte[] a = [1, 2, 3];
    aa[a] = "hello";
}

fails to compile and gives the error

q.d(5): Error: associative arrays can only be assigned values with immutable 
keys, not int[]

but this code

void main()
{
    string[ubyte[]] aa;
    ubyte[] a = [1, 2, 3];
    const b = a;
    aa[b] = "hello";
}

does compile. So, the way it handles this avoids forcing you to explicitly
put the const or immutable on the key type, which makes for less typing, but
the fact that it's using const and not immutable is definitely a bug. Based
on the error message, clearly it was acknowledged that the keys need to be
immutable, but clearly that hasn't quite made it how the rest of it was
implemented. IIRC, the implementation using void* and casts everywhere, so
it's pretty trivial for it to break the type system if anything gets screwed
up.

But as I said, the built-in AAs are a mess. They work reasonably well for
basic cases but start falling apart when you do stuff like use classes for
keys. While the situation is better than it used to be, historically, we've
had tons of bugs in the implementation, and overall, I'd argue that having
AAs in the language was a mistake. It probably made more sense in the D1
days, but at this point, the only real advantage over a library type is that
the built-in AAs work with AA literals, and a library type wouldn't (though
with a solid DIP, I'm sure that that could be fixed).

Work has been done on templatizing the AA implementation, which should help,
but we'd be much better off sorting out a proper library type and
encouraging its use. One of the suggestions of how to improve things has
been to restrict keys for the built-in AAs to simpler types (e.g. no
classes), but there hasn't been agreement on that, and we'd actually need a
proper library type in Phobos before doing something like that (and the
situation with Phobos and containers is its own mess).

The whole AA mess comes up probably just about every dconf, and I expect
that it will be sorted out eventually, but when that will be, I don't know.
A big part of the question is what's going to happen with Martin's work on
templatizing the implementation. It may be that that can salvage things, but
in the interim, bugs in in the built-in AAs are no surprise. If anything,
it's probably a miracle that they work as well as they do.

- Jonathan M Davis


Reply via email to