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