Thread overview
How to specialize template function for associative arrays?
Oct 19, 2007
Aarti_pl
Oct 19, 2007
Extrawurst
Oct 19, 2007
Aarti_pl
Oct 19, 2007
Regan Heath
Oct 19, 2007
Aarti_pl
Oct 19, 2007
Aarti_pl
Specialization/is syntax
Oct 19, 2007
Bill Baxter
Oct 20, 2007
Daniel Keep
Oct 19, 2007
Extrawurst
Oct 19, 2007
Marcin Kuszczak
October 19, 2007
void parse(T)() {
}

//What to write here???
void parse(T : ?????)() {
}

void main() {
    parse!(int[char[]])();
}
October 19, 2007
as far as i know:

void parse(T : A[B])() {
}

~Extrawurst


Aarti_pl schrieb:
> void parse(T)() {
> }
>
> //What to write here???
> void parse(T : ?????)() {
> }
>
> void main() {
>     parse!(int[char[]])();
> }
October 19, 2007
Extrawurst pisze:
> as far as i know:
> 
> void parse(T : A[B])() {
> }
> 
> ~Extrawurst
> 
> 

Unfortunately not... I was also thinking that it will work, but you get compile time error instead:

quicktest.d(13): Error: identifier 'B' is not defined
quicktest.d(13): Error: index is not a type or an expression
quicktest.d(13): Error: identifier 'A' is not defined
quicktest.d(13): Error: A is used as a type

I managed to catch associative arrays with 'static if' and templates, but it would be better to use template specialization to have better source code structure.

Any other ideas?

BR
Marcin Kuszczak
October 19, 2007
Aarti_pl wrote:
> Extrawurst pisze:
>> as far as i know:
>>
>> void parse(T : A[B])() {
>> }
>>
>> ~Extrawurst
>>
>>
> 
> Unfortunately not... I was also thinking that it will work, but you get compile time error instead:
> 
> quicktest.d(13): Error: identifier 'B' is not defined
> quicktest.d(13): Error: index is not a type or an expression
> quicktest.d(13): Error: identifier 'A' is not defined
> quicktest.d(13): Error: A is used as a type
> 
> I managed to catch associative arrays with 'static if' and templates, but it would be better to use template specialization to have better source code structure.
> 
> Any other ideas?

Does parse really have no arguments?  Or does it actally look a bit like:

import std.stdio;

void parse(T)(T t) {
	writefln("parse(T)");
}


void parse(V, K)(V[K] arr) {
	writefln("parse(V, K)");
}

void main() {
	int[char[]] arr;
	parse!(int, char[])(arr);
}

Regan
October 19, 2007
Regan Heath pisze:
> Aarti_pl wrote:
>> Extrawurst pisze:
>>> as far as i know:
>>>
>>> void parse(T : A[B])() {
>>> }
>>>
>>> ~Extrawurst
>>>
>>>
>>
>> Unfortunately not... I was also thinking that it will work, but you get compile time error instead:
>>
>> quicktest.d(13): Error: identifier 'B' is not defined
>> quicktest.d(13): Error: index is not a type or an expression
>> quicktest.d(13): Error: identifier 'A' is not defined
>> quicktest.d(13): Error: A is used as a type
>>
>> I managed to catch associative arrays with 'static if' and templates, but it would be better to use template specialization to have better source code structure.
>>
>> Any other ideas?
> 
> Does parse really have no arguments?  Or does it actally look a bit like:
> 
> import std.stdio;
> 
> void parse(T)(T t) {
>     writefln("parse(T)");
> }
> 
> 
> void parse(V, K)(V[K] arr) {
>     writefln("parse(V, K)");
> }
> 
> void main() {
>     int[char[]] arr;
>     parse!(int, char[])(arr);
> }
> 
> Regan

Nope. I just want to choose proper template function depending on parameter type (in this case associative array).

It should be something similar to:
void parse(T : T[])() {
    writefln("parse(T[])");
}
which actually works.

Maybe it is just doesn't work in D?

-----------

BTW: above syntax for normal arrays looks for me not very consistent. In fact it should be:
# void parse(T : E[])() {
#     writefln("Type: ", T.stringof, " Element type: ", A.stringof);
# }

and then proposal from Extrawurst would be just logical consequence.

BR
Marcin
October 19, 2007
Aarti_pl pisze:

> Nope. I just want to choose proper template function depending on parameter type (in this case associative array).

Depending on previously instantiated template's type argument.

(I just realized that my previous statement does not make much sense... Hopefully this approach will make more sense, although is not much easier to read. :-O)

BR
Marcin
October 19, 2007
Aarti_pl wrote:
> -----------
> 
> BTW: above syntax for normal arrays looks for me not very consistent. In fact it should be:
> # void parse(T : E[])() {
> #     writefln("Type: ", T.stringof, " Element type: ", A.stringof);
> # }
> 
> and then proposal from Extrawurst would be just logical consequence.

I agree with you.  T:E[] can be read as "T where T is an E[] for some E".  Very logical.  With T:T[] I never can remember if the T I get in the function is the type passed in or the type without the [].  It's the full type right?  So the :T[] really only means "where T is an array", and the reuse of T is just a distractor.  T:array would maybe be more to the point.  Oh, no wait, it's the other way isn't it.  The function gets the T stripped of [].  Gaaahh!

The is() syntax is also very odd
   if (is(T S : S[])) {
       // S now an alias of T stripped of its []
   }

I think it would be more logical as
   if (is(S;  T : S[])) {
       // S now an alias of T stripped of its []
   }

The S; is reminiscent of the first clause of foreach where you can declare new scoped symbols whose meaning is derived from what's on the right of the ';'.  So that's read "we're declaring a new S, where S is the type such that T is S[].

I think that would also make things like  is(F Args == function) a bit more logical too.
Currently it looks an awful lot like "Args equals a function" but it means we're defining a new Args to be the parameters of the function F?  Huh?  Compare with
     is(Args; F==function)
"Checking if F is a function and also declaring a new Args whose type is deduced from F"

--bb
October 19, 2007
what about just this :

void foo(A, B)(A[B] _aa)
{
   foreach(it; _aa)
   {
       writefln("%s",it);
   }
}

void main()
{
   string[int] bar = [2:"test"[], 55:"bar"];

   foo!(string,int)(bar);

   writefln("byye");
}


~Extrawurst



Aarti_pl schrieb:
> void parse(T)() {
> }
>
> //What to write here???
> void parse(T : ?????)() {
> }
>
> void main() {
>     parse!(int[char[]])();
> }
October 19, 2007
Extrawurst wrote:

> what about just this :
> 
> void foo(A, B)(A[B] _aa)
> {
>     foreach(it; _aa)
>     {
>         writefln("%s",it);
>     }
> }
> 
> void main()
> {
>     string[int] bar = [2:"test"[], 55:"bar"];
> 
>     foo!(string,int)(bar);
> 
>     writefln("byye");
> }
> 
> 
> ~Extrawurst

It will not work. Instantiation should be same for all types...

I found following solution:

void parse(T)() {
        static if (isAssociativeArray(T)) {
                ....
        } else {
                ....
        }
}

Template isAssociativeArray(T) is from Tango/core/traits.d. (Thank you,
Tango team!). Thanks to this template I could also get key type and value
type of associative array.

Anyway I think that it should work somehow for specializations, so I will put enhancement request on bugzilla.

-- 
Regards
Marcin Kuszczak (Aarti_pl)
-------------------------------------
Ask me why... I believe in Jesus - http://www.zapytajmnie.com (en/pl)
Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/
-------------------------------------

October 20, 2007

Bill Baxter wrote:
> Aarti_pl wrote:
>> -----------
>>
>> BTW: above syntax for normal arrays looks for me not very consistent.
>> In fact it should be:
>> # void parse(T : E[])() {
>> #     writefln("Type: ", T.stringof, " Element type: ", A.stringof);
>> # }
>>
>> and then proposal from Extrawurst would be just logical consequence.
> 
> I agree with you.  T:E[] can be read as "T where T is an E[] for some E".  Very logical.  With T:T[] I never can remember if the T I get in the function is the type passed in or the type without the [].  It's the full type right?  So the :T[] really only means "where T is an array", and the reuse of T is just a distractor.  T:array would maybe be more to the point.  Oh, no wait, it's the other way isn't it.  The function gets the T stripped of [].  Gaaahh!

I've never really had a problem with it.  I think of T:T[] as being "given the user passed in T[], give me T."  Granted, I know how you feel; there've been many things in my life that have confused me until I came up with a good way of remembering them.

> The is() syntax is also very odd
>    if (is(T S : S[])) {
>        // S now an alias of T stripped of its []
>    }
> 
> I think it would be more logical as
>    if (is(S;  T : S[])) {
>        // S now an alias of T stripped of its []
>    }

I do agree that the current syntax is a bit weird, but I can't say I like your solution.  :3  I look at it, and I can't quite work out what it's trying to say.

> The S; is reminiscent of the first clause of foreach where you can declare new scoped symbols whose meaning is derived from what's on the right of the ';'.  So that's read "we're declaring a new S, where S is the type such that T is S[].
> 
> I think that would also make things like  is(F Args == function) a bit
> more logical too.
> Currently it looks an awful lot like "Args equals a function" but it
> means we're defining a new Args to be the parameters of the function F?
>  Huh?  Compare with
>      is(Args; F==function)
> "Checking if F is a function and also declaring a new Args whose type is
> deduced from F"
> 
> --bb

I suppose is() and specialisation could use improvement.  I guess I'm just reticent to make sweeping changes to something that I've gotten used to.  Plus it means you won't be able to make templates that work in both D 1.0 and D 2.0!

	-- Daniel