D - Template-like feature idea (wildcard variables)
- David Caldwell (91/91) Aug 18 2001 Hello,
- Russell Bornschlegel (7/13) Aug 19 2001 The biggest limitation I see here is that you can only specialize
- David Caldwell (25/30) Aug 20 2001 No, maybe I didn't explain it properly. I guess all my examples were of
Hello, I read about your D language recently and I really like it. You seem to be trying to fix all the things that have been annoying me about c/c++. I have been pondering templates and #defines and what life would be like without them. Clearly something should replace their funcitonality in D. Here's my proposal for a replacement for template-ish functions and macros: It's pretty simple, just a new type: the wildcard type. I've been representing it as a "*" as a reference to globbing and regexs but perhaps * means too many things already. Heres a big example: * min(* a, * b) { if (a < b) return a; return b; } void swap(* inout a,* inout b) { * temp; temp = a; a = b; b = temp; } *[] fillarray(* a, * b) { *[] array; array[0] = a; array[1] = b; return array; } * GetYo(*a) { return a.yo; } main() { struct eat { int yo; } struct yikes { float yo; } eat e1,e2; yikes y1,y2; int i; float f; i = min(1,2); // ok i = min(3,3.14); // error (implicit cast, 2 possible return types) i = min(3,cast(int) 3.13); // ok (a and b are now both ints) i = min(3.1,3.14); // error (return type wrong) i = cast(int) min(3.1,3.14) // ok (since it explicitly cast, it's ok) e1 = min(e1,e2); // error (e1 < e2 fails in min()) (no operator overloading yet) swap(y1,y2); // ok swap(e1,e2); // ok swap(y1,i); // error (temp used inconsistantly, y1 = i fails) swap(y1,e1); // error (temp used inconsistantly, y1 = e1 fails) eat[] x = fillarray(e1,e2); // ok int[] y = fillarray(1,2); // ok float[] z = fillarray(1,2); // error (return type wrong) f = GetYo(y1); // ok f = GetYo(e1); // error (return type wrong) f = cast(float) GetYo(e1); // ok (since it explicitly cast, it's ok) } Notice that types are not ever name (like the conventional "T" in c++). My thinking is that it should be clear to the compiler what the types should be and if they are inconsistant then it's an error. Thanks to your great module idea the full source code to a wildcarded function is available at compile time to make sure that the types really are consistantly used. In the Swap() function the temp variable ends up being the same type as a because it is set to "a" and so if it was any other type it would be an error. Return values are determined by what type you actaully return. If a function has multiple return statements with different return types then that is an error. Therefore, the function that calls the wildcard function determines the types of the arguments, but the wildcard function itself determines the return type. In my examples here I've labelled implicit casting of return values as illegal but I'm not 100% sure if thats right. It would seem to cut down on errors, even if the implicit cast is normally legal. This is not addressing template classes, by the way. I've only thought about functions so far... Any comments anyone? To limiting? To much implicitness? It's certainly less verbose than c++ templates. And please forgive any obviously stupid D syntax errors, this is my first D-ish program. :) -David Caldwell david porkrind_org
Aug 18 2001
David Caldwell wrote:It's pretty simple, just a new type: the wildcard type. I've been representing it as a "*" as a reference to globbing and regexs but perhaps * means too many things already. [example snipped] Notice that types are not ever name (like the conventional "T" in c++). My thinking is that it should be clear to the compiler what the types should be and if they are inconsistant then it's an error.The biggest limitation I see here is that you can only specialize one type at a time here. If you want to write a generic associative array class, for example, you usually want to specialize by both lookup key and looked-up value. (Yeah, I know D already has associative arrays.) -Russell B
Aug 19 2001
Russell Bornschlegel wrote:The biggest limitation I see here is that you can only specialize one type at a time here. If you want to write a generic associative array class, for example, you usually want to specialize by both lookup key and looked-up value. (Yeah, I know D already has associative arrays.)No, maybe I didn't explain it properly. I guess all my examples were of one type, but this would work: * lookup(*[] a, * b) { for (int i=0;i<a.length;i++) if (a[i].key == b) return a[i].value; return void; // ??? unclear what this should be. maybe throw ??? } main() { struct assoc { int key; char[] value; } assoc[] a = { {1,"Hello"},{2,"there"} }; char[] s; s = lookup(a,1); // ok s = lookup(a,"hey"); // error a[i].key clashes with "b" in "if" statement int i = lookup(a,2); // error, return type clashes (its determined from "a[i].value") } -David david porkrind_org
Aug 20 2001