June 29, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | On Sat, 29 Jun 2002 11:49:40 -0700 "Sean L. Palmer" <seanpalmer@earthlink.net> wrote:
> $f[#b][#a] Inverse ($f matrix[uint #a][uint #b]) { ... }
All these $ and # suddenly make it feel like Perl - which
I hate, by the way, especially its synatx =)
Could we come with some more elegant decision? I wonder
if even C++-style < > brackets could be used, and teach
the compiler to hanle >> properly for templates?
|
June 29, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | Pavel Minayev <evilone@omen.ru> wrote in news:CFN374370467174768@news.digitalmars.com: > On Sat, 29 Jun 2002 11:49:40 -0700 "Sean L. Palmer" <seanpalmer@earthlink.net> wrote: > >> $f[#b][#a] Inverse ($f matrix[uint #a][uint #b]) { ... } > > All these $ and # suddenly make it feel like Perl - which > I hate, by the way, especially its synatx =) > > Could we come with some more elegant decision? I wonder > if even C++-style < > brackets could be used, and teach > the compiler to hanle >> properly for templates? > How about something like this. template { // Define parametric types type T1; type T2; uint XA; uint YA; uint XB; uint YB; // Define families of parametric fuctions // and structures T1[YA][XA] Inverse(T1[XA][YA] matrix) { } T1[XB][YA] Multipy(T1[XA][YA] m1,T1[XB][YB] m2) {} // struct foo(T1,T2) { T1[T2] bar; T1 func { } } } |
June 30, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Craig Black | Craig Black wrote: >> float[$b][$a] Inverse (float matrix[$a][$b]) { ... } > > So in a generic function the $symbol can be a type, or an integer, or > anything else? I could see where this ambiguity might be too much for the > compiler to handle. That is why C++ uses "template<>" for functions. For > classes I think its unnecessary, but for functions the compiler has to infer > what the type or value is, so it is best to give the compiler as many hints > as possible to reduce ambiguity. It would be different if we assumed that > all $symbol's were types. How about preceding each $symbol with a type > where the value is to be deduced? Not only will this specify what the type > is, but it will tell the compiler which parameter to get the value from. I > admit I've never designed a compiler, but I assume these kinds of generic > functions are difficult to implement. Let's keep in mind that somebody is > going to have to implement this stuff if it's ever going to work. Compiler-wise this matter is trivial (functions anyway); I wouldn't recommend it if I knew otherwise. For divining matches you'd merely take the call and cycle through the arguments, filling in as you walk along. Then create a signature out of it, and if it matches the arguments and has not been compiled do so. There's a good set of very well-defined steps for getting there from here. $ defines new mandatory trivial constant folding points to put it in its purest term. Couple hundred lines of code max. Blarg. I'm trying to figure out what kind of monster struct, class, and union would turn out to be if it could have specific values passed to its factory. This is haunting me: struct Matrix (TypeInfo $type, int rows, int cols) { $type [rows] [cols] array; } Matrix (float, 4, 4) foo; /* constant size */ Matrix (Color, h, w) bar; /* run-time sized using alloca */ struct Moof { Matrix (int) m; } Moof moof; moof.m = Matrix (int, h, w); I don't like the last part of the syntax which has some weird internal gymnastics and odd syntax. Maybe: struct Moof (int rows, int cols) { Matrix (int, rows, cols) m; } Moof (h, w) moof; But I don't like things propagating like this, even if it is consistent with templates. Hm. > float[$b][$a] Inverse (float matrix[int $a][int $b]) { ... } This is redundant. I don't particularly care how it goes - it's just that allowing "int $a" implies that you can do "float $a", and it's kind of confusing that "[int $a]" and "[int]" mean entirely different things. At least "(int $a)" and "(int)" are within speaking distance. |
June 30, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Down | On Sat, 29 Jun 2002 22:25:55 +0000 (UTC) Patrick Down <pat@codemoon.com> wrote:
> How about something like this.
>
> template
> {
> // Define parametric types
> type T1;
> type T2;
> uint XA;
> uint YA;
> uint XB;
> uint YB;
>
> // Define families of parametric fuctions
> // and structures
>
> T1[YA][XA] Inverse(T1[XA][YA] matrix) { }
>
> T1[XB][YA] Multipy(T1[XA][YA] m1,T1[XB][YB] m2) {}
>
> //
> struct foo(T1,T2)
> {
> T1[T2] bar;
>
> T1 func { }
> }
> }
Then how do you declare an instance of foo? Like this?
foo(char[], int) x;
Looks too much like a function pointer (or delegate). I think a distinct
syntax is still needed.
|
June 30, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | If D source could use Unicode characters, we could use French quotation marks << and >> for shifts, and < and > for templates. ;) I'd rather declare them once using $ or # or whatever and then use the identifier. I guess. Although the $ and # do make it quite clear that you're dealing with generic types or values. Sean "Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374370467174768@news.digitalmars.com... > On Sat, 29 Jun 2002 11:49:40 -0700 "Sean L. Palmer" <seanpalmer@earthlink.net> > wrote: > > > $f[#b][#a] Inverse ($f matrix[uint #a][uint #b]) { ... } > > All these $ and # suddenly make it feel like Perl - which > I hate, by the way, especially its synatx =) > > Could we come with some more elegant decision? I wonder > if even C++-style < > brackets could be used, and teach > the compiler to hanle >> properly for templates? |
June 30, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Down | Well this at least has a look that fits with the rest of D quite nicely. I agree with Pavel, I don't like the () syntax ... something else is needed. In fact the below doesn't even really need the (T1,T2) part in struct foo(T1,T2) as it's already well known that T1 and T2 are generic types since the whole thing is within a template{} declaration that defines T1 and T2. Perhaps you could name the template scope and instantiate the template scope with some special syntax to access the identifiers of the templated types? template T1 { type T; T min(T a, T b) { return (a<b) ? a : b; } } void main() { int x,y; return T1(int T).min(x,y); } Sean "Patrick Down" <pat@codemoon.com> wrote in message news:Xns923CB3E63DC17patcodemooncom@63.105.9.61... > Pavel Minayev <evilone@omen.ru> wrote in news:CFN374370467174768@news.digitalmars.com: > > > On Sat, 29 Jun 2002 11:49:40 -0700 "Sean L. Palmer" <seanpalmer@earthlink.net> wrote: > > > >> $f[#b][#a] Inverse ($f matrix[uint #a][uint #b]) { ... } > > > > All these $ and # suddenly make it feel like Perl - which > > I hate, by the way, especially its synatx =) > > > > Could we come with some more elegant decision? I wonder > > if even C++-style < > brackets could be used, and teach > > the compiler to hanle >> properly for templates? > > > > How about something like this. > > template > { > // Define parametric types > type T1; > type T2; > uint XA; > uint YA; > uint XB; > uint YB; > > // Define families of parametric fuctions > // and structures > > T1[YA][XA] Inverse(T1[XA][YA] matrix) { } > > T1[XB][YA] Multipy(T1[XA][YA] m1,T1[XB][YB] m2) {} > > // > struct foo(T1,T2) > { > T1[T2] bar; > > T1 func { } > } > } > |
July 01, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | > Compiler-wise this matter is trivial (functions anyway); I wouldn't > recommend it if I knew otherwise. > > For divining matches you'd merely take the call and cycle through the arguments, filling in as you walk along. Then create a signature out of it, and if it matches the arguments and has not been compiled do so. There's a good set of very well-defined steps for getting there from here. $ defines new mandatory trivial constant folding points to put it in its purest term. Couple hundred lines of code max. OK. Sounds like you know what you're talking about. Just to clarify in my mind, what is the justification for ditching the "template <>" or "generic []" syntax for generic functions? Is this just unnecessary? > Blarg. I'm trying to figure out what kind of monster struct, class, and union would turn out to be if it could have specific values passed to its factory. This is haunting me: > > struct Matrix (TypeInfo $type, int rows, int cols) > { > $type [rows] [cols] array; > } > > Matrix (float, 4, 4) foo; /* constant size */ > Matrix (Color, h, w) bar; /* run-time sized using alloca */ > > struct Moof > { > Matrix (int) m; > } > > Moof moof; > > moof.m = Matrix (int, h, w); > > I don't like the last part of the syntax which has some weird internal gymnastics and odd syntax. Maybe: > > struct Moof (int rows, int cols) > { > Matrix (int, rows, cols) m; > } > > Moof (h, w) moof; > > But I don't like things propagating like this, even if it is consistent with templates. Hm. Ouch! This stuff is starting to make my brain hurt. Are you trying to find a syntax that can instantiate a generic at run-time? What would we get if we removed the $ from "$type" in this template. A run-time generic? Is this what you are trying to accomplish? If so, perhaps we could use the same syntax for both run-time and compile-time. The same generic could be instantiated at compile-time or run-time. That way you wouldn't have to duplicate any code in order to have both compile-time and run-time generics. > > float[$b][$a] Inverse (float matrix[int $a][int $b]) { ... } > > This is redundant. I don't particularly care how it goes - it's just > that allowing "int $a" implies that you can do "float $a", and it's kind > of confusing that "[int $a]" and "[int]" mean entirely different things. > At least "(int $a)" and "(int)" are within speaking distance. float[$b][$a] Inverse (float matrix[$a][$b]) { ... } Hey, if the compiler doesn't mind, neither do I. |
July 02, 2002 Variable parameter generics | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Down | Hello, To my knowledge, D doesn't support variable parameters. C# has an excellent way to represet variable parameters using the params keyword. It works something like this. void print(params string [] strings) { ... } print("Any", "number", "of", "parameters"); Brace yourselves. This is a very advanced idea. But I encourage you to stretch your mind and think outside of the box. We could extend this variable parameter concept to templates. Observe. class Tuple<params type $types[]> { // We would have to provide some syntax to extract each type // outside of function syntax. The following is very sketchy. foreach (type T in $types) { T type.name##variable; // declar each variable } }; I know it looks bad. It's kinda like a C preprocessor macro combined with a C++ template combined with C# foreach and params. I'm looking for other suggestions as to how to best express this. Perhaps the "type" type approach suggested earlier. What is required is a syntax for conditional structure building. With the above generic you could have multiple return values: Tuple<int, float> func(); In C++ you would have to define a template for each number of parameters supported e.g. Tuple2, Tuple3, Tuple4, Tuple5, etc. But shouldn't we be able to define one template that can handle any number of parameters? --Craig |
July 03, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Craig Black | "Craig Black" <cblack@ara.com> wrote in message news:af7k2g$1f31$1@digitaldaemon.com... > First of all, I would like to say that I like the direction that D is going > so far, and appreciate your innovative work on this new language. Thanks! > I know support for generics in D is probably still on the horizin, but have > you given it any serious thought? We can definitely improve on C++ templates, both in ease of implementation and flexibility. Even before you > start on templates it would be good to have in mind at least a vague concept > of what you plan to do. I use C++ templates aggressively, so I have some ideas about features to add and drop. What I'm doing right now is finishing template support in the C++ compiler. That gives me a credible foundation to do a better job in D. > First, if you haven't read Modern C++ Design: Generic Programming and Design > Patterns Applied by Andrei Alexandrescu, you should get a copy. A great book! I have already applied many of the concepts he covers. It should be > required reading for anyone who wants in depth understand of Generic Programming. Ok, I'll check it out. Though if it advocates the STL design, I'm afraid I'm skeptical. > I have so many ideas and could write forever about generics, here's just some food for thought. If you're interested, I would be glad to share more > ideas. Fire away! > I will just give you a few insights of where you can improve on C++. First, > we generic programmers need a compile-time typeof operator. I have run into > so many cases where I said to myself, "I sure wish I had a typeof operator." > It would make generic programming so much more elegant. Then you could have > compile-time conditionals to handle different types in different ways, like > this: > > cswitch(typeof(variable)) > { > case int: // handle an integer > case string: // hangle a string > ... > } > > Here "cswitch" is a compile-time conditional. This means the conditional is > resolved at compile time, and optimized appropriately so that no performance > is lost and dead code is eliminated. You could also have cif, celse, etc. Ok, that's a good idea. > Another idea I have to improve on C++ is type specialization syntax. We could implement type specialization more explicitly using typelists. This would provide a more readable type specialization that (I think) would be easier to implement. > > Here's a simple example: > > template <typename T : {int, uint, long, ulong, float, double}> > T Add(T a, T b) > { > return a + b; > } > > This specializes the Add function to need apply only to int, float, double, > and extended. You could then write another Add template that would handle concatenation of container types. I have some ideas on type specialization, the syntax for C++ is terrible (and trust me, it's really hard to write a compiler for!). > This leads me to another feature that would be nice to have: type lists (see > chapter 3 of Modern C++ design.) It would be nice to categorize types something like this: > > typelist NumericTypes { int, uint, long, ulong, float, double }; typelist ContainerTypes { list, set, vector, queue, stack }; > > Then you could rewrite the Add function: > > template <typename T : NumericTypes> > T Add(T a, T b) > { > return a + b; > } > > template <typename T : ContainerTypes> > T Add(T a, T b) > { > T result; > result.append(a); > result.append(b); > return result; > } Ok, that's another good idea. |
July 03, 2002 Re: Generics in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "Burton Radons" <loth@users.sourceforge.net> wrote in message news:3D1AD1CD.3080308@users.sourceforge.net... > I _think_ the ambiguities that C++ was fighting against are nullified by D, which would be very good, as <> is not. That's some of the problem with C++ templates. The rest of the complexities come about because of implicit instantiation. If, instead, things are explicitly instantiated, most of the complexity goes away. None of the rules about partial ordering, etc., would be necessary. |
Copyright © 1999-2021 by the D Language Foundation