use v6;

sub find_first(@list, Matcher $matcher --> Int)
{
    @fl = @list.grep($matcher);
    if @fl.elems >= 0
    {
        for @list.kv -> $i, $v
        {
            return $i if $v eqv @fl[0];
        }
    }
    return Int;
}

class Symbol
{
    our @!strlist;
    has Int $!index;
    
    submethod BUILD(Str $data)
    {
        Int $ix = find_first(@!strlist, { $_.k eq $data });
        if $ix.defined
        {
            @!strlist[ix].v++;
            $!index = $ix;
        }
        else
        {
            $!index = @!strlist.elems;
            @!strlist.push($data => 1);
        }
    }
    
    multi method new(Str $data)
    {
        return self.bless(*, :$data);
    }

    submethod DESTROY()
    {
        @!strlist[$!index].v--;
        if @!strlist[$!index].v == 0
        {
            @!strlist.splice($!index, 1);
        }
    }

    multi method Str() is export
    {
        @!strlist[$!index].k;
    }
}

multi sub infix:<cmp>(Symbol $x, Symbol $y) is deep
{
    return $x.Str cmp $y.Str;
}

multi sub infix:<cmp>(Symbol $x, $y) is deep
{
    return $x.Str cmp ~$y;
}

multi sub infix:<cmp>($y, Symbol $x) is deep
{
    return ~$x. cmp $y.Str;
}

my $a = Symbol.new('lol');
my $b = Symbol.new('wut');
"$a {$a.WHERE}".say;
"$b {$b.WHERE}".say;
"----------------".say;
my $x = Symbol.new('lol');
my $y = Symbol.new('wut');
"$x {$x.WHERE}".say;
"$y {$y.WHERE}".say;