On Wed, 14 Mar 2012 14:51:54 -0400, Stewart Gordon <smjg_1...@yahoo.com> wrote:

With some containers, such as lists and trees (binary search trees aside), it doesn't matter if the elements can change state, since the data structure remains well-formed.

However, with others, such as sets and AAs, it's desirable if the keys don't mutate. Any operations on them won't work right if there are keys in the wrong hash slots or out of order (depending on the underlying data structure) because they have changed since being put into the container. Of course, this doesn't apply to _values_ in an AA, since these can safely mutate.

In Java and D1, it seems you just have to go on trust if you want your container to accept key types other than strict value types. But can we do better in D2 - short of forcing the key type to be immutable, which would hinder the container's usefulness?

But it seems D2 has taken one step in that general direction by automatically tail-consting the key type of an AA. But it doesn't stop modifications to the key through mutable references to the data. And if the key is of class type, you can still modify the object, since D2 conflates constancy of an object reference with constancy of the object itself. This is in itself silly. Really, D should have tail-const built in for stuff like this. OK, so there's Rebindable, but I've found it to be a PITA when trying to do generic programming with it, as well as leading to this AA key anomaly because it isn't a built-in feature.


I suppose there are a few possibilities for what constancy to apply to elements of a data structure to which changes might affect the structure's integrity:

(a) force the type to be tail-const if it's an array, otherwise don't add any constancy (b) force the type to be tail-const if it's an array, or fully const if it's a class (c) force the type to be tail-immutable if it's an array, otherwise don't add any constancy (d) force the type to be tail-immutable if it's an array, or fully immutable if it's a class
(e) don't add any constancy, but just rely on trust


Currently, AAs implement (a). (d) guarantees that changes to the data that mess up the data structure will never happen, at least if the programmer doesn't bypass the const system. (e) is the route D1 and Java are forced to take. Am I right in thinking that sets and maps in the C++ STL take the same path?


Anyway, what are people's thoughts on the right way to go here?

IMO, @safe code should only allow d, @system/trusted should allow e.

And the compiler shouldn't be "helping" you by adding const annotations. That is:

int[char[]] aa;

this line should either compile, and the type should be int[char[]] aa, or it should not compile.

D is supposed to be able to do "at your own risk" bare-metal types of things. This seems like it unnecessarily limits code.

-Steve

Reply via email to