digitalmars.D - Multiple Specialization?
- Xinok (27/27) Dec 22 2006 I'm not sure what else you could call this...
- Chris Nicholson-Sauls (7/42) Dec 22 2006 Or even just:
- Bill Baxter (18/42) Dec 22 2006 I agree with Chris that grouping the types seems like a better idea.
- Xinok (15/15) Dec 22 2006 I don't like the idea of using parenthesis or braces.
- Paul Findlay (43/48) Dec 23 2006 This is an idea I had one walk.. using something like a static switch. I...
- BCS (5/31) Dec 23 2006 Yes
I'm not sure what else you could call this... My idea for multiple specialization is to be able to associate multiple types with a single template. Take for example: template temp(T){ } template temp(T : int, T : long){ } // Specialized Template It would use the specialized template if T == int OR T == short I have two designs for this, the first you see above. Because the order of template arguments is important, all types must come in succession: template temp(T1, T2 : int, T2 : long, T3){ } // OK template temp(T1, T2 : int, T3, T2 : long){ } // Error - T2 is not in succession This is important, because the compiler can't be sure if T2 or T3 comes first: (T1, T2, T3) or (T1, T3, T2) My second design is to use braces: template temp(T1, T2 : {int, long}, T3){ } I also think you could use tuples somehow, but I have no idea how you could write that. But take for example: template tuple(T...){ alias T tuple; } template temp(T : tuple!(int, long)){ } I think tuples would work best because you can define aliases for them, where as you can't define an alias for the two other designs: alias tuple!(byte, short, int long) intset; template temp(T1 : intset, T2 : intset){ } What could this be used for? Suppose you wanted to make a specialized template for all int types? Or float types? Or char types? You would have to duplicate the template multiple times, especially if you have two or more types: template temp(T1 : {byte, short, int, long}, T2 : {byte, short, int long}){ } This would normally require you to define 16 specialized templates.
Dec 22 2006
Xinok wrote:I'm not sure what else you could call this... My idea for multiple specialization is to be able to associate multiple types with a single template. Take for example: template temp(T){ } template temp(T : int, T : long){ } // Specialized Template It would use the specialized template if T == int OR T == short I have two designs for this, the first you see above. Because the order of template arguments is important, all types must come in succession: template temp(T1, T2 : int, T2 : long, T3){ } // OK template temp(T1, T2 : int, T3, T2 : long){ } // Error - T2 is not in succession This is important, because the compiler can't be sure if T2 or T3 comes first: (T1, T2, T3) or (T1, T3, T2) My second design is to use braces: template temp(T1, T2 : {int, long}, T3){ } I also think you could use tuples somehow, but I have no idea how you could write that. But take for example: template tuple(T...){ alias T tuple; } template temp(T : tuple!(int, long)){ }Or even just: template temp(T : (int, long)) { }I think tuples would work best because you can define aliases for them, where as you can't define an alias for the two other designs: alias tuple!(byte, short, int long) intset; template temp(T1 : intset, T2 : intset){ } What could this be used for? Suppose you wanted to make a specialized template for all int types? Or float types? Or char types? You would have to duplicate the template multiple times, especially if you have two or more types: template temp(T1 : {byte, short, int, long}, T2 : {byte, short, int long}){ } This would normally require you to define 16 specialized templates.Or one template with a long static if at the beginning, which can be annoying for, say, template functions. Its an interesting idea at the least -- but I'm not sure what it might take in the compiler. -- Chris Nicholson-Sauls
Dec 22 2006
Chris Nicholson-Sauls wrote:Xinok wrote:I agree with Chris that grouping the types seems like a better idea. Repeating T is asking for trouble. (T : {a, b}) or somesuch. Or maybe multiple colons (T :a:b)I'm not sure what else you could call this... My idea for multiple specialization is to be able to associate multiple types with a single template. Take for example: template temp(T){ } template temp(T : int, T : long){ } // Specialized Template It would use the specialized template if T == int OR T == shortYeh, static if(is(...)) is the way I'd do this now. That also allows you to accept "any type implicitly convertable to T" which covers a lot of real-world cases. For the most part you don't care if it's one of 16 specific types, you care if it can be assigned to an 'int' or if an int can be assigned to it. Personally, I have yet to use specialization, because of it's annoying "feature" of disabling IFTI. (At least that's the way it seemed the last time I tried it -- correct me if I'm wrong there) I would love for it to become usable. But right now static if is more flexible and powerful. I agree that it would be nice if the same power were available via the specialization syntax. --bbWhat could this be used for? Suppose you wanted to make a specialized template for all int types? Or float types? Or char types? You would have to duplicate the template multiple times, especially if you have two or more types: template temp(T1 : {byte, short, int, long}, T2 : {byte, short, int long}){ } This would normally require you to define 16 specialized templates.Or one template with a long static if at the beginning, which can be annoying for, say, template functions. Its an interesting idea at the least -- but I'm not sure what it might take in the compiler.
Dec 22 2006
I don't like the idea of using parenthesis or braces. I'm trying to create a design which wouldn't require adding a new syntax to D. I really like the idea of using tuples, that is if multiple specialization were to be added to D. Tuples are already a part of D, so it wouldn't require adding anything new. Also, tuples have a few features which could come in handy with multiple specialization. The first feature I already mentioned, you can define aliases for tuples. alias tuple!(byte, short, int, long) intset; template temp(T : intset){ } Second, the splitting operator: template temp(T : intset[1..length]){ } // short, int, long Third, tuples can take both types and constants, so they could be used to specialize variables too. template temp(int V : tuple!(15, 30, 45)){ }
Dec 22 2006
Xinok wrote:I don't like the idea of using parenthesis or braces. I'm trying to create a design which wouldn't require adding a new syntax to D. I really like the idea of using tuples, that is if multiple specialization were to be added to D.This is an idea I had one walk.. using something like a static switch. I thought this would be a more natural step for D to get some pattern matching on template arguments. So from code I have seen in minid (which brilliant): public int write(T)(MDState s) { MDFile i = cast(MDFile)s.getInstanceParam(0, this); T val; static if(is(T == ubyte) || is(T == ushort) || is(T == int)) val = s.getIntParam(1); else static if(is(T == float)) val = s.getFloatParam(1); else static if(is(T == char) || is(T == wchar) || is(T == dchar)) val = s.getCharParam(1); //.. snip return 0; } a static switch version: public int write(T)(MDState s) { MDFile i = cast(MDFile)s.getInstanceParam(0, this); T val; static switch(T) { case(ubyte): case(ushort): case(int): val = s.getIntParam(1); break; case(float): val = s.getFloatParam(1); break; case(char): case(wchar): case(dchar): val = s.getCharParam(1); break; } //.. snip return 0; } and I imagined having static switch and case been able to handle type tuples if for example the function prototype was public int write(T...)(MDState s) // no example because I am lazy Does this make sense? - Paul
Dec 23 2006
Paul Findlay wrote:This is an idea I had one walk.. using something like a static switch.[...]a static switch version: public int write(T)(MDState s) { MDFile i = cast(MDFile)s.getInstanceParam(0, this); T val; static switch(T) { case(ubyte): case(ushort): case(int): val = s.getIntParam(1); break; case(float): val = s.getFloatParam(1); break; case(char): case(wchar): case(dchar): val = s.getCharParam(1); break; } //.. snip return 0; } and I imagined having static switch and case been able to handle type tuples if for example the function prototype was public int write(T...)(MDState s) // no example because I am lazy Does this make sense? - PaulYes I was thinking of posting about the same concept my self. (I second the ides)
Dec 23 2006