Thread overview
AA keys
Mar 16, 2008
bearophile
Mar 17, 2008
bearophile
Mar 17, 2008
Frits van Bommel
Mar 17, 2008
bearophile
March 16, 2008
Can you explain this to me?
Is this yet another corner case (or bug?)?

import std.stdio: writefln;

void main() {
    int[int] aa1 = [1:2, 3:4];
    int[int] aa2 = [5:6, 7:8];
    byte[int[int]] s;
    writefln(aa1, " ", aa2); // Prints: [1:2,3:4] [5:6,7:8]

    s[aa1] = 1;
    s[aa2] = 2;
    writefln(s); // Prints: [[1:2,3:4]:2]
}

Bye,
bearophile
March 16, 2008
"bearophile" <bearophileHUGS@lycos.com> wrote in message news:frjrkc$18k9$1@digitalmars.com...
> Can you explain this to me?
> Is this yet another corner case (or bug?)?
>
> import std.stdio: writefln;
>
> void main() {
>    int[int] aa1 = [1:2, 3:4];
>    int[int] aa2 = [5:6, 7:8];
>    byte[int[int]] s;
>    writefln(aa1, " ", aa2); // Prints: [1:2,3:4] [5:6,7:8]
>
>    s[aa1] = 1;
>    s[aa2] = 2;
>    writefln(s); // Prints: [[1:2,3:4]:2]
> }
>
> Bye,
> bearophile

And to confirm it, s.length is 1, not 2.  There were originally some bugs in std.format's array and AA handling, but this is definitely not an output bug.

I'd bugzilla it if I were you.


March 17, 2008
Jarrett Billingsley:
> There were originally some bugs in std.format's array and AA handling, but this is definitely not an output bug. I'd bugzilla it if I were you.

I think this is the 13th bug I have found so far :-)
I think this may be caused by the fact that AAs don't have an == defined yet (and no one seem to care). I can use my equalAA() function for most purposes, but I presume hashing needs an == too, and I can't fix that with an external function.

Bye,
bearophile
March 17, 2008
"bearophile" <bearophileHUGS@lycos.com> wrote in message news:frlmm1$2see$1@digitalmars.com...
> Jarrett Billingsley:
>> There were originally some bugs in std.format's array and AA handling, but this is definitely not an output bug. I'd bugzilla it if I were you.
>
> I think this is the 13th bug I have found so far :-)

Welcome to the club.  No one ever said the reference implementation was bulletproof ;)


March 17, 2008
bearophile wrote:
> I can use my equalAA() function for most purposes, but I presume hashing needs an == too, and I can't fix that with an external function.

Yeah, TypeInfo.{getHash,equals,compare} aren't implemented for TypeInfo_AssociativeArray, TypeInfo_Function and TypeInfo_Delegate in either Phobos or Tango. And all of those are required for the relevant types to work correctly as AA keys, IIRC.

Of course, you could implement them and attach the patch to the relevant bug report... which didn't exist yet.
Remedied that last part:
Phobos: <http://d.puremagic.com/issues/show_bug.cgi?id=1926>
Tango: <http://www.dsource.org/projects/tango/ticket/988>
March 17, 2008
Frits van Bommel Wrote:
> Of course, you could implement them and attach the patch to the relevant
> bug report... which didn't exist yet.
> Remedied that last part:
> Phobos: <http://d.puremagic.com/issues/show_bug.cgi?id=1926>
> Tango: <http://www.dsource.org/projects/tango/ticket/988>

You are good.
For reference this is the equalAA in my libs you can find online:


/***************************************
The == among two AAs.

DMD V.1.015 doesn't define < <= == != >= > among AAs.
(Python defines them all among dicts, so a full cmpAA can be defined too).
*/
bool equalAA(TyK1, TyV1, TyK2, TyV2)(TyV1[TyK1] aa1, TyV2[TyK2] aa2) {
    static if( !is(TyK1 == TyK2) || !is(TyV1 == TyV2) )
        return false;
    else {
        if (aa1.length != aa2.length)
            return false;

        foreach(k, v; aa1) {
            auto k_in_aa2 = k in aa2;
            if (!k_in_aa2 || (*k_in_aa2 != v))
                return false;
        }

        return true;
    }
}

unittest { // Test of equalAA()
    assert(  equalAA(AA!(int, int), AA!(int, int)) );
    assert( !equalAA(AA!(char, int), ['a':2, 'b':3]) );
    assert( !equalAA(['a':2, 'b':3], AA!(char, int)) );
    assert( !equalAA(['a':2, 'b':3], AA!(int, int)) );
    assert(  equalAA(['a':2, 'b':3], ['a':2, 'b':3]) );
    assert( !equalAA(['a':2, 'b':3], ['a':2]) );
    assert( !equalAA(['a':2, 'b':3], ['a':2, 'b':3, 'c':1]) );
    assert( !equalAA(['c':2, 'b':3], ['a':2, 'b':3]) );
    assert( !equalAA(['a':3, 'b':3], ['a':2, 'b':3]) );
    assert( !equalAA([2:'a', 3:'b'], ['a':2, 'b':3]) );
}

(AA!() creates an empty AA array).
Note it may not work if keys and/or values are static arrays (it can be modified in an ugly way to work in such situation too)
(Note that is gives false if the items are of different type, even if they can be cast-converted to each other. This may be different from arrays.)

Bye,
bearophile