On Thursday, 7 August 2014 at 16:53:24 UTC, H. S. Teoh via Digitalmars-d wrote:
On Thu, Aug 07, 2014 at 11:46:48AM +0000, via Digitalmars-d wrote:
AAs are (like regular dynamic arrays) initialized to `null`. On first modification (i.e. assignment of an element), memory is allocated and
the AA variable updated to point at it.

However, is there a guarantee that AAs are never reallocated once they are initialized, i.e. is it then safe to assume that changes made through a copy of an AA variable (e.g. pass by value) are visible
through the original variable?

The current implementation behaves like this, but the language
reference does not mention it, AFAICS. I'd like to amend the
documentation if this behaviour is reliable.
[...]

I'm not the one to make the decision, but I'd vote for codifying this behaviour in the language reference. From what I understand, at least,
it seems that this is the intention anyway, and the current
implementation certainly suggests so. Otherwise, it leads to strange awkward semantics where passing AA's around may sometimes change the
original "view" of it, and sometimes not.

It's really just the .init value of null which causes odd behaviour with
empty AA's. Fun fact:

        void changeAA(int[string] aa) {
                aa["a"] = 123;
        }

        // Null AA:
        int[string] aa1; // null

        assert(aa1.length == 0);
        changeAA(aa1);  // no effect
for most of the new users the WAT part is actually here :-)

In all other occations AA behaves just like a reference type: You want to changeAA with assignment and you get an empty(null) AA, you should be able to change it.

refering to an null AA and not wanting to modify it is not a common case.

So I'd like to suggest a rule here similar to what assignment does to null AA:

If someone refers to an uninitialized null AA ( in implementation, that maybe, a copy of a null AA struct happens), allocate it first.

        assert(aa1.length == 0);

        // Empty but non-null AA:
        int[string] aa2; // null
        aa2["a"] = 0;
        aa2.remove("a"); // empty but non-null

        assert(aa2.length == 0);
        changeAA(aa2);  // has effect!
        assert(aa2.length == 1); // WAT :-)


T

Reply via email to