Thread overview
Sorry, I just love templates, AAs and mixins :)
Oct 16, 2009
Saaa
Oct 17, 2009
Ary Borenszweig
Oct 19, 2009
Saaa
Oct 19, 2009
Saaa
Oct 17, 2009
grauzone
Oct 17, 2009
Ellery Newcomer
Oct 19, 2009
Saaa
October 16, 2009
public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
{
  mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
  if( elements == null )
  {
    ET[] temp;
    temp.length = 1;
    temp[0] = element;
    mixin(var_name~`[key] = temp;`);
  }
  else
  {
    (*elements).length = (*elements).length + 1;
    (*elements)[(*elements).length-1] = element;
  }
}


October 17, 2009
Saaa wrote:
> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
> {
>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>   if( elements == null )
>   {
>     ET[] temp;
>     temp.length = 1;
>     temp[0] = element;
>     mixin(var_name~`[key] = temp;`);

Why `key`? Where's `key` defined?

>   }
>   else
>   {
>     (*elements).length = (*elements).length + 1;
>     (*elements)[(*elements).length-1] = element;

I don't understand this. Key is not used.

>   }
> } 

And how do you use it? I tried to but I failed. Also passing a string as var_name is not nice. Isn't it better to write something like:

char[int] x;
x.add(1, 'h');

?
October 17, 2009
Saaa wrote:
> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
> {
>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>   if( elements == null )
>   {
>     ET[] temp;
>     temp.length = 1;
>     temp[0] = element;
>     mixin(var_name~`[key] = temp;`);
>   }
>   else
>   {
>     (*elements).length = (*elements).length + 1;
>     (*elements)[(*elements).length-1] = element;
>   }
> } 
> 
> 

It's unreadable. What the hell does it do? How do you use it?
It's a good example how you can write-only code in D.
October 17, 2009
grauzone wrote:
> Saaa wrote:
>> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
>> {
>>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>>   if( elements == null )
>>   {
>>     ET[] temp;
>>     temp.length = 1;
>>     temp[0] = element;
>>     mixin(var_name~`[key] = temp;`);
>>   }
>>   else
>>   {
>>     (*elements).length = (*elements).length + 1;
>>     (*elements)[(*elements).length-1] = element;
>>   }
>> }
>>
> 
> It's unreadable.

No it isn't. It's an obfusticated version of

if( key in var) var[key] ~= element;
else var[key] = [element];

but who wants to write that boring code? :)
October 19, 2009
Ellery Newcomer wrote:
> grauzone wrote:
>> Saaa wrote:
>>> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
>>> {
>>>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>>>   if( elements == null )
>>>   {
>>>     ET[] temp;
>>>     temp.length = 1;
>>>     temp[0] = element;
>>>     mixin(var_name~`[key] = temp;`);
>>>   }
>>>   else
>>>   {
>>>     (*elements).length = (*elements).length + 1;
>>>     (*elements)[(*elements).length-1] = element;
>>>   }
>>> }
>>>
>>
>> It's unreadable.
>
> No it isn't. It's an obfusticated version of
>
> if( key in var) var[key] ~= element;
> else var[key] = [element];

No, it isn't. It's obfusticated version of the generic version of that code
:)
I always forget ~= and somehow [] with a single variable in it looks
strange, my bad!

So, thanks!
This is why I posted it in the first place; could you maybe look over DData
as well :)

I somehow like that I can tell the compiler precisely(mixins) how to generate generic(templates) code..

>
> but who wants to write that boring code? :)
Isn't your code slower because it always needs to search for the key twice :P

Here is the new and improved version :

public void addToAAA(char[] var_name, KT, ET)(KT key, ET element)
{
  mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
  if( elements == null )
  {
    mixin(var_name~`[key] = [element];`);
  }
  else
  {
    (*elements) ~= element;
  }
}


October 19, 2009
Ary Borenszweig wrote:
> Saaa wrote:
>> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
>> {
>>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>>   if( elements == null )
>>   {
>>     ET[] temp;
>>     temp.length = 1;
>>     temp[0] = element;
>>     mixin(var_name~`[key] = temp;`);
>
> Why `key`? Where's `key` defined?
Here: ...(KT key, ET element)
>
>>   }
>>   else
>>   {
>>     (*elements).length = (*elements).length + 1;
>>     (*elements)[(*elements).length-1] = element;
>
> I don't understand this. Key is not used.
That's because there is already a link to the key through elements.

>
>>   }
>> }
>
> And how do you use it? I tried to but I failed.
You need a AA defined like this:
BaseType[][KeyType] AAname;

addToAA!("AAname")(KeyType key, BaseType value);

> Also passing a string as var_name is not nice. Isn't it better to write something like:
>
> char[int] x;
> x.add(1, 'h');
>
> ?

The string is the actual variable name so I think that way doesn't work, right?

Check the new version(shorter)  in my other reply :D


October 19, 2009
Saaa wrote:
> Ary Borenszweig wrote:
>> Saaa wrote:
>>> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
>>> {
>>>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>>>   if( elements == null )
>>>   {
>>>     ET[] temp;
>>>     temp.length = 1;
>>>     temp[0] = element;
>>>     mixin(var_name~`[key] = temp;`);
>> Why `key`? Where's `key` defined?
> Here: ...(KT key, ET element)
>>>   }
>>>   else
>>>   {
>>>     (*elements).length = (*elements).length + 1;
>>>     (*elements)[(*elements).length-1] = element;
>> I don't understand this. Key is not used.
> That's because there is already a link to the key through elements.
> 
>>>   }
>>> }
>> And how do you use it? I tried to but I failed.
> You need a AA defined like this:
> BaseType[][KeyType] AAname;
> 
> addToAA!("AAname")(KeyType key, BaseType value);
> 
>> Also passing a string as var_name is not nice. Isn't it better to write something like:
>>
>> char[int] x;
>> x.add(1, 'h');
>>
>> ?
> 
> The string is the actual variable name so I think that way doesn't work, right?
> 
> Check the new version(shorter)  in my other reply :D
> 
> 

This worked just now with DMD 2.035:

////////////////////////////// BEGIN CODE
module test1;

import std .stdio ;

public void add ( AAA : E[][K], K, E ) ( ref AAA aa, K key, E[] elem ... ) {
    if ( auto ptr = key in aa ) {
        *ptr ~= elem;
    }
    else {
        aa[ key ] = elem;
    }
}

void main () {
    int[][ char ] sandbox ;

    sandbox.add( 'a', 1 );
    sandbox.add( 'b', 1, 2 );
    sandbox.add( 'c', 1 );
    sandbox.add( 'a', 2, 3 );

    foreach ( key, elems ; sandbox ) {
        writeln(`    [`, key, `] `, elems);
    }
}
////////////////////////////// END CODE

-- Chris Nicholson-Sauls
October 19, 2009
Chris Nicholson-Sauls wrote:
> Saaa wrote:
>> Ary Borenszweig wrote:
>>> Saaa wrote:
>>>> public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
>>>> {
>>>>   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
>>>>   if( elements == null )
>>>>   {
>>>>     ET[] temp;
>>>>     temp.length = 1;
>>>>     temp[0] = element;
>>>>     mixin(var_name~`[key] = temp;`);
>>> Why `key`? Where's `key` defined?
>> Here: ...(KT key, ET element)
>>>>   }
>>>>   else
>>>>   {
>>>>     (*elements).length = (*elements).length + 1;
>>>>     (*elements)[(*elements).length-1] = element;
>>> I don't understand this. Key is not used.
>> That's because there is already a link to the key through elements.
>>
>>>>   }
>>>> }
>>> And how do you use it? I tried to but I failed.
>> You need a AA defined like this:
>> BaseType[][KeyType] AAname;
>>
>> addToAA!("AAname")(KeyType key, BaseType value);
>>
>>> Also passing a string as var_name is not nice. Isn't it better to write something like:
>>>
>>> char[int] x;
>>> x.add(1, 'h');
>>>
>>> ?
>>
>> The string is the actual variable name so I think that way doesn't work, right?
>>
>> Check the new version(shorter)  in my other reply :D
>>
>>
>
> This worked just now with DMD 2.035:
>
> ////////////////////////////// BEGIN CODE
> module test1;
>
> import std .stdio ;
>
> public void add ( AAA : E[][K], K, E ) ( ref AAA aa, K key, E[] elem ... )
> {
>     if ( auto ptr = key in aa ) {
>         *ptr ~= elem;
>     }
>     else {
>         aa[ key ] = elem;
>     }
> }
>
> void main () {
>     int[][ char ] sandbox ;
>
>     sandbox.add( 'a', 1 );
>     sandbox.add( 'b', 1, 2 );
>     sandbox.add( 'c', 1 );
>     sandbox.add( 'a', 2, 3 );
>
>     foreach ( key, elems ; sandbox ) {
>         writeln(`    [`, key, `] `, elems);
>     }
> }
> ////////////////////////////// END CODE
>
> -- Chris Nicholson-Sauls

Thanks, that looks nice.
One small difference is that  main() now needs to have access to sandbox
whereas using mixins you could keep sandbox private to add()'s location.