January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | Daniel Yokomiso wrote:
> "Burton Radons" <loth@users.sourceforge.net> escreveu na mensagem
> news:3E26F644.9090506@users.sourceforge.net...
>
>>
>>Daniel Yokomiso wrote:
>>
>>>which are always type correct. Using function generators, we can define
>
> a
>
>>>function, that given a type will return a function specialized for the
>
> given
>
>>>type. D's template mechanism can be used as a function generator.
>>>
>>>T fun(T,T) TMin(type T) {
>>>return T fun(T left, T right) {
>>>return left < right ? left : right;
>>>}
>>>}
>>>
>>>using template syntax:
>>>
>>>template TMin(T) {
>>>return T min(T left, T right) {
>>>return left < right ? left : right;
>>>}
>>>}
>>
>>The template method I suggested a long time ago would use:
>>
>> $T min ($T left, $T right)
>> {
>> return left < right ? left : right;
>> }
>
>
> I don't think I've read about them. Do you remember the date of the
> posts, so I can search them? I'm too lazy to just search everything manually
> ;-)
"Generics in D", starting on 24/06/2002. It's a simple syntax, just puts C++'s basic syntax inside the language instead of as a layer. Here's the body of my description of it:
For generic functions and generic class methods, a "$" followed by an identifier in the place where a type would exist indicates a generic type. The specific type of this generic is determined by the first argument using it; a function cannot return a generic type only. For example:
$type foo ($type a, $type b)
$type bar (int c); /* Illegal */
complex x = foo (4, 2.3); /* Returns int and casts 2.3 to int */
Generic values are also prefixed with a $ and must be trivially constant. Generic values of type "TypeInfo" or "ClassInfo" are special in that they can be used both as a value and a generic type, and if so must be the first argument to use this generic value:
$type cast (TypeInfo $type, $type value) { return value; }
$type tsac ($type value, TypeInfo $type) /* Illegal */
cast (int, 4.3); /* Returns 4 */
A generic function that takes only generic types and values and only accesses other similarly compile-time values is considered trivially constant and must be folded.
The generic function for a given function name and number of arguments is searched for eligibility after any specific-type functions. There can't be two generic functions with the same name and number of arguments as it's easy to make the overloading rules go crazy, and this restriction can be relaxed in the future.
On to struct, class, and union. I've only taken the most obvious choice:
struct Vector (TypeInfo $type, int $size)
{
$type [$size] array;
}
Vector (float, 4) v;
struct Vector2 (TypeInfo $type) : Vector ($type, 2)
{
float x () { return array [0]; }
float y () { return array [1]; }
}
struct Matrix (TypeInfo $type)
{
$type [,] array;
Vector ($vtype, $vsize) mul (Vector ($vtype, $vsize) v)
{
}
}
There's many ways in which it falls behind C++'s template's expressiveness, but matching it is not the point. I don't write interdependent templates where instantiating inner templates might need some intelligence, so the many complexities of C++'s templates are not used by me. What I exclusively need are simple single-layer templates like vectors and matrices, and template methods.
|
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "Burton Radons" <loth@users.sourceforge.net> escreveu na mensagem news:b0amv6$qlb$1@digitaldaemon.com... > Daniel Yokomiso wrote: > > "Burton Radons" <loth@users.sourceforge.net> escreveu na mensagem news:3E26F644.9090506@users.sourceforge.net... > > > >> > >>Daniel Yokomiso wrote: > >> > >>>which are always type correct. Using function generators, we can define > > > > a > > > >>>function, that given a type will return a function specialized for the > > > > given > > > >>>type. D's template mechanism can be used as a function generator. > >>> > >>>T fun(T,T) TMin(type T) { > >>>return T fun(T left, T right) { > >>>return left < right ? left : right; > >>>} > >>>} > >>> > >>>using template syntax: > >>> > >>>template TMin(T) { > >>>return T min(T left, T right) { > >>>return left < right ? left : right; > >>>} > >>>} > >> > >>The template method I suggested a long time ago would use: > >> > >> $T min ($T left, $T right) > >> { > >> return left < right ? left : right; > >> } > > > > > > I don't think I've read about them. Do you remember the date of the > > posts, so I can search them? I'm too lazy to just search everything manually > > ;-) > > "Generics in D", starting on 24/06/2002. It's a simple syntax, just puts C++'s basic syntax inside the language instead of as a layer. Here's the body of my description of it: > > For generic functions and generic class methods, a "$" followed by an identifier in the place where a type would exist indicates a generic type. The specific type of this generic is determined by the first argument using it; a function cannot return a generic type only. For example: > > $type foo ($type a, $type b) > $type bar (int c); /* Illegal */ > > complex x = foo (4, 2.3); /* Returns int and casts 2.3 to int */ > > Generic values are also prefixed with a $ and must be trivially constant. Generic values of type "TypeInfo" or "ClassInfo" are special in that they can be used both as a value and a generic type, and if so must be the first argument to use this generic value: > > $type cast (TypeInfo $type, $type value) { return value; } > $type tsac ($type value, TypeInfo $type) /* Illegal */ > > cast (int, 4.3); /* Returns 4 */ > > A generic function that takes only generic types and values and only accesses other similarly compile-time values is considered trivially constant and must be folded. > > The generic function for a given function name and number of arguments is searched for eligibility after any specific-type functions. There can't be two generic functions with the same name and number of arguments as it's easy to make the overloading rules go crazy, and this restriction can be relaxed in the future. > > On to struct, class, and union. I've only taken the most obvious choice: > > struct Vector (TypeInfo $type, int $size) > { > $type [$size] array; > } > > Vector (float, 4) v; > > struct Vector2 (TypeInfo $type) : Vector ($type, 2) > { > float x () { return array [0]; } > float y () { return array [1]; } > } > > struct Matrix (TypeInfo $type) > { > $type [,] array; > > Vector ($vtype, $vsize) mul (Vector ($vtype, $vsize) v) > { > } > } > > There's many ways in which it falls behind C++'s template's expressiveness, but matching it is not the point. I don't write interdependent templates where instantiating inner templates might need some intelligence, so the many complexities of C++'s templates are not used by me. What I exclusively need are simple single-layer templates like vectors and matrices, and template methods. > Hmmm, I think I lost these posts, because I wasn't lurking here before it (or was I? I don't remember). Anyway, it's a very simple but expressive syntax. I like it a lot. Maybe it isn't too late to sway Walter's opinion? --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.443 / Virus Database: 248 - Release Date: 11/1/2003 |
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Woodhead | "Ben Woodhead" <zander@echotech.ca> wrote in message news:b01afa$16dn$1@digitaldaemon.com... > As it is I have see a few feature that (although needed/wanted by the c++ > community) were not in the design that were put in (i.e. templates). I liked > Walters original plan of not putting it in. Java does fine without it. You make some excellent points, but one thing I want to stress is D templates were designed by trying to understand what problem C++ templates were trying to solve, and then trying to find a way to do the equivalent with far less complexity than the C++ design. One of the problems is, as you mentioned, one gets so used to doing things in C++ that it gets difficult to imagine doing it any other way. We all suffer from that, and we all repeatedly need to step back now and then and ask ourselves just what problem is <feature X> of C++ trying to solve, and should it be reengineered? |
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Niall Douglas | "Niall Douglas" <Niall_member@pathlink.com> wrote in message news:b03b5h$2l2s$1@digitaldaemon.com... > This then begs the question why Objective C didn't win since it also offered > backwards compatibility? It's a dynamic system, not static like C++ and thus > came with a runtime library. I'm still not quite sure why C++ won because in my > mind it was the technically inferior choice, but I'm guessing it had to do with: > (a) perceived efficiency (b) an excellent early translator to C (CFront from > AT&T) (c) the perception that ObjC was too "out there" coming from NextSTEP as > it did Back in '85 or '86, ObjC and C++ were neck-and-neck as enhancements to C (judging by the volume of messages in their respective newsgroups). At the time, only one implementation of each existed. There was, as I recall, a lot of arguing about which was better. But there was one crucial difference. AT&T was happy to let anyone build a C++ compiler without getting a license from AT&T (yes, I wrote AT&T's lawyers asking, and they said fine, go right ahead!). To do an ObjC clone, you had to get a license from Stepstone, which cost real money. So, I built a C++ compiler (the first native C++ compiler). We made it available inexpensively on the PC, and advertised that our intention was to be 100% AT&T compatible. We shipped a huge number of compilers, and that achieved the critical mass for C++ to gain ascendancy. |
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0ahk2$o3q$1@digitaldaemon.com... > All these are real problems that D template mechanism cannot address. > But you can workaround them using templates for these functions (except > assignment overloading), so you can have a common template: > > > template TNumericTraits(T) { > T zero(); > T one(); > } It is a pain to make such things. You almost need a template to help build your template. ;) > And overload template definitions for all primitives and for UDT's. Ugly > but it works. About assignment overloading, IMHO C++ design is ugly and very > error-prone. Ada provide the same thing, but their solution is simpler. What > you think about it? Ada's way can do the deal, or C++ like overloading of assignment is necessary? I don't know enough about Ada to be able to comment. I have messed around with designs of my own which do everything (copying, construction, conversion, i/o) using assignment. I don't think you really need all the forms that C++ has. For instance creating a new value from nothing would be overloading assignment to object reference from void. Copy construction is assignment from reference to reference of same type. Conversion is assignment to different type. I/O is assignment to or from a stream. Sure makes things conceptually simpler. I, too, am working on a language design, but time constraints make it very slow going. I know it will be very different than C/C++. Hopefully stay closer syntactically but diverge semantically. All the cool languages I've read about have very wierd syntax. All these restrictions on identifier casing, etc. Haskell, OOCaml, Sather; all very strange languages if you come from a C++ background. And it's not the concepts so much as just the look and feel of the language. I love the constructs, I just can't stand to look at the programs source; they just look ugly to me. > Yes, but Walter changed his mind and will implement some kind of value > parameters. That's good. Otherwise very hard to write recursive templates. > I thought you have some other problems with D's template mechanism, but > you share the critics with most of us. Or there's something more? My main problem with D's template system is the explicit instantiation. I am spoiled by C++'s templates. I also think C++'s templates don't go far enough. You really need language constructs to facilitate working with compile time values, such as "const functions" which have no side effects and rely on no runtime data and given constants as inputs generate a constant output, so are suitable for evaluation at compile time. Sean |
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | I like it better than what D has now. Sean "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0ao5r$rhs$1@digitaldaemon.com... > > "Generics in D", starting on 24/06/2002. It's a simple syntax, just puts C++'s basic syntax inside the language instead of as a layer. Here's the body of my description of it: > > > > For generic functions and generic class methods, a "$" followed by an identifier in the place where a type would exist indicates a generic type. The specific type of this generic is determined by the first argument using it; a function cannot return a generic type only. For example: > > > > $type foo ($type a, $type b) > > $type bar (int c); /* Illegal */ > > > > complex x = foo (4, 2.3); /* Returns int and casts 2.3 to int */ > > Hmmm, I think I lost these posts, because I wasn't lurking here before > it (or was I? I don't remember). Anyway, it's a very simple but expressive > syntax. I like it a lot. Maybe it isn't too late to sway Walter's opinion? |
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | Daniel Yokomiso wrote: > "Burton Radons" <loth@users.sourceforge.net> escreveu na mensagem > news:b0amv6$qlb$1@digitaldaemon.com... [snip] >>There's many ways in which it falls behind C++'s template's >>expressiveness, but matching it is not the point. I don't write >>interdependent templates where instantiating inner templates might need >>some intelligence, so the many complexities of C++'s templates are not >>used by me. What I exclusively need are simple single-layer templates >>like vectors and matrices, and template methods. > > Hmmm, I think I lost these posts, because I wasn't lurking here before > it (or was I? I don't remember). Anyway, it's a very simple but expressive > syntax. I like it a lot. Maybe it isn't too late to sway Walter's opinion? As far as I know you're the only user of the feature! So no, it's not too late. Glancing over the spec, my missing features are specialization and argument deduction, both of which fit in easily. First, specialization: struct TFoo (TypeInfo $T) { } struct TFoo (TypeInfo $T : $T []) { } struct TFoo (TypeInfo $T : char) { } struct TFoo (TypeInfo $T, TypeInfo $U, TypeInfo $V) { } TFoo (int) foo1; /* Instantiates #1 */ TFoo (double[]) foo2; /* Instantiates #2 with $T being double */ TFoo (char) foo3; /* Instantiates #3 */ TFoo (char, int) fooe; /* Error, number of arguments mismatch */ TFoo (char, int, int) foo4; /* Instantiates #4 */ Argument deduction: struct TBar (TypeInfo $D, TypeInfo $U : $D []) { } TBar (int, int[]) Bar1; /* $D is int, $U is int [] */ struct TBar (TypeInfo $D : $E *, TypeInfo $E) { } TBar (int *, int) Bar2; /* $D is int *, $E is int */ Bar2 additionally requires loosened rules on order of determining the type of a template value. I won't argue for this, as I don't use them. So it can be as flexible as the current syntax, with the addition of easily-expressed template functions and methods (which C++ doesn't have either). It is absolutely more intrusive; the struct/class types and functions all need an abstract template form. But I've never liked the implicit layered scheme of C++ or the explicit layering that D puts on the language; it's unnecessary at best and clumsy at its worst. The Walter factor needed is to convince him that implicit instantiation is a reasonable request to make of compiler authors. Honestly, I don't understand his objection to it; the only difference between these lines: instance TBar (int, 4) x; TBar (int, 4) y; Is a keyword. We can tell right during parsing that these must be instantiating template types. I don't see most of C++'s implicit instantiation rules as making any sense in our context, such as the: Z<int> a; // instantiation of class Z<int> required Z<char>* p; // instantiation of class Z<char> not required I can't even imagine the cavalcade of drugs the C++ designers must have been on to make some of their decisions. |
January 19, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@directvinternet.com> escreveu na mensagem news:b0c878$1o3f$1@digitaldaemon.com... > > "Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:b0ahk2$o3q$1@digitaldaemon.com... > > All these are real problems that D template mechanism cannot address. > > But you can workaround them using templates for these functions (except assignment overloading), so you can have a common template: > > > > > > template TNumericTraits(T) { > > T zero(); > > T one(); > > } > > It is a pain to make such things. You almost need a template to help build > your template. ;) IIRC Dijkstra once said that you can solve any problem just by adding another level of indirection ;-) > > > And overload template definitions for all primitives and for UDT's. > Ugly > > but it works. About assignment overloading, IMHO C++ design is ugly and > very > > error-prone. Ada provide the same thing, but their solution is simpler. > What > > you think about it? Ada's way can do the deal, or C++ like overloading of > > assignment is necessary? > > I don't know enough about Ada to be able to comment. I have messed around with designs of my own which do everything (copying, construction, conversion, i/o) using assignment. I don't think you really need all the forms that C++ has. For instance creating a new value from nothing would be > overloading assignment to object reference from void. Copy construction is > assignment from reference to reference of same type. Conversion is assignment to different type. I/O is assignment to or from a stream. Sure > makes things conceptually simpler. > > I, too, am working on a language design, but time constraints make it very slow going. I know it will be very different than C/C++. Hopefully stay closer syntactically but diverge semantically. All the cool languages I've > read about have very wierd syntax. All these restrictions on identifier casing, etc. Haskell, OOCaml, Sather; all very strange languages if you come from a C++ background. And it's not the concepts so much as just the look and feel of the language. I love the constructs, I just can't stand to > look at the programs source; they just look ugly to me. Sometimes when I read functional code it feels very elegant, but almost impossible to understand. I think it's their prediletion to write one character parameter names or truncate names. > > > Yes, but Walter changed his mind and will implement some kind of value > > parameters. > > That's good. Otherwise very hard to write recursive templates. > > > I thought you have some other problems with D's template mechanism, > but > > you share the critics with most of us. Or there's something more? > > My main problem with D's template system is the explicit instantiation. I am spoiled by C++'s templates. I also think C++'s templates don't go far enough. You really need language constructs to facilitate working with compile time values, such as "const functions" which have no side effects and rely on no runtime data and given constants as inputs generate a constant output, so are suitable for evaluation at compile time. > > Sean > IME explicit instantiation sometimes help you figure out what's going on, but whenever I work on DTL i use more and more aliases ;-) Pure functions also allow equational reasoning and let the compiler reorder expression evaluation, which when combined with cache-hit analysis can improve performance. Maybe they'll be in D after 1.0, unless we convince Walter first. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.443 / Virus Database: 248 - Release Date: 10/1/2003 |
January 19, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "Burton Radons" <loth@users.sourceforge.net> escreveu na mensagem news:b0cb3o$1pt0$1@digitaldaemon.com... > Daniel Yokomiso wrote: > > "Burton Radons" <loth@users.sourceforge.net> escreveu na mensagem news:b0amv6$qlb$1@digitaldaemon.com... > [snip] > >>There's many ways in which it falls behind C++'s template's expressiveness, but matching it is not the point. I don't write interdependent templates where instantiating inner templates might need some intelligence, so the many complexities of C++'s templates are not used by me. What I exclusively need are simple single-layer templates like vectors and matrices, and template methods. > > > > Hmmm, I think I lost these posts, because I wasn't lurking here before > > it (or was I? I don't remember). Anyway, it's a very simple but expressive > > syntax. I like it a lot. Maybe it isn't too late to sway Walter's opinion? > > As far as I know you're the only user of the feature! So no, it's not too late. I started using templates so I could convince Walter of changing them to fit my whims ;-) > > Glancing over the spec, my missing features are specialization and argument deduction, both of which fit in easily. First, specialization: > > struct TFoo (TypeInfo $T) { } > struct TFoo (TypeInfo $T : $T []) { } > struct TFoo (TypeInfo $T : char) { } > struct TFoo (TypeInfo $T, TypeInfo $U, TypeInfo $V) { } > > TFoo (int) foo1; /* Instantiates #1 */ > TFoo (double[]) foo2; /* Instantiates #2 with $T being double */ > TFoo (char) foo3; /* Instantiates #3 */ > TFoo (char, int) fooe; /* Error, number of arguments mismatch */ > TFoo (char, int, int) foo4; /* Instantiates #4 */ > Current DTL 0.0.2 uses specialization to overcome lack of value parameters in templates. > Argument deduction: > > struct TBar (TypeInfo $D, TypeInfo $U : $D []) { } > TBar (int, int[]) Bar1; /* $D is int, $U is int [] */ > > struct TBar (TypeInfo $D : $E *, TypeInfo $E) { } > TBar (int *, int) Bar2; /* $D is int *, $E is int */ > > Bar2 additionally requires loosened rules on order of determining the type of a template value. I won't argue for this, as I don't use them. > Argument deduction is a strange thing to me. First I thought them of being type constraints, but right now I don't know why or how I would use them. > So it can be as flexible as the current syntax, with the addition of easily-expressed template functions and methods (which C++ doesn't have either). It is absolutely more intrusive; the struct/class types and functions all need an abstract template form. But I've never liked the implicit layered scheme of C++ or the explicit layering that D puts on the language; it's unnecessary at best and clumsy at its worst. > > The Walter factor needed is to convince him that implicit instantiation is a reasonable request to make of compiler authors. Honestly, I don't understand his objection to it; the only difference between these lines: > > instance TBar (int, 4) x; > TBar (int, 4) y; As most of D posters here come from a C/C++ background, Walter fear adding features that will end making D another C++. I agree that explicit instantiation is too verbose, almost impossible to mix with generic methods. > Is a keyword. We can tell right during parsing that these must be instantiating template types. I don't see most of C++'s implicit instantiation rules as making any sense in our context, such as the: > > Z<int> a; // instantiation of class Z<int> required > Z<char>* p; // instantiation of class Z<char> not required > > I can't even imagine the cavalcade of drugs the C++ designers must have been on to make some of their decisions. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.443 / Virus Database: 248 - Release Date: 10/1/2003 |
January 19, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "Burton Radons" <loth@users.sourceforge.net> wrote in message news:b0cb3o$1pt0$1@digitaldaemon.com... > > Hmmm, I think I lost these posts, because I wasn't lurking here before > > it (or was I? I don't remember). Anyway, it's a very simple but expressive > > syntax. I like it a lot. Maybe it isn't too late to sway Walter's opinion? > > As far as I know you're the only user of the feature! So no, it's not too late. It still won't be easy. > Glancing over the spec, my missing features are specialization and argument deduction, both of which fit in easily. First, specialization: > > struct TFoo (TypeInfo $T) { } > struct TFoo (TypeInfo $T : $T []) { } > struct TFoo (TypeInfo $T : char) { } > struct TFoo (TypeInfo $T, TypeInfo $U, TypeInfo $V) { } > > TFoo (int) foo1; /* Instantiates #1 */ > TFoo (double[]) foo2; /* Instantiates #2 with $T being double */ > TFoo (char) foo3; /* Instantiates #3 */ > TFoo (char, int) fooe; /* Error, number of arguments mismatch */ > TFoo (char, int, int) foo4; /* Instantiates #4 */ That's a welcome addition, but it looks more like a Pascal typespec than a C one. Not that I like C typespecs. ;) Maybe struct TFoo (TypeInfo $T) { } struct TFoo (TypeInfo( $T [] ) $T) { } struct TFoo (TypeInfo( char ) $T) { } ? > Argument deduction: > > struct TBar (TypeInfo $D, TypeInfo $U : $D []) { } > TBar (int, int[]) Bar1; /* $D is int, $U is int [] */ > > struct TBar (TypeInfo $D : $E *, TypeInfo $E) { } > TBar (int *, int) Bar2; /* $D is int *, $E is int */ > > Bar2 additionally requires loosened rules on order of determining the type of a template value. I won't argue for this, as I don't use them. > > So it can be as flexible as the current syntax, with the addition of easily-expressed template functions and methods (which C++ doesn't have either). It is absolutely more intrusive; the struct/class types and functions all need an abstract template form. But I've never liked the implicit layered scheme of C++ or the explicit layering that D puts on the language; it's unnecessary at best and clumsy at its worst. > > The Walter factor needed is to convince him that implicit instantiation is a reasonable request to make of compiler authors. Honestly, I don't understand his objection to it; the only difference between these lines: > > instance TBar (int, 4) x; > TBar (int, 4) y; > > Is a keyword. We can tell right during parsing that these must be instantiating template types. I don't see most of C++'s implicit instantiation rules as making any sense in our context, such as the: > > Z<int> a; // instantiation of class Z<int> required > Z<char>* p; // instantiation of class Z<char> not required Just makes the compiler faster. It's the whole #include file mess. It would have to go ahead and instantiate Z<char> if you dereferenced p. > I can't even imagine the cavalcade of drugs the C++ designers must have been on to make some of their decisions. Some people don't need drugs to be stupid. ;) Sean |
Copyright © 1999-2021 by the D Language Foundation