January 15, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Niall Douglas | My first post to this newsgroup, so hi everyone! > Now if for example I want a list object which maintains a list of another object, in Java I'd use a dual object approach - there'd be a list item object > which would be the base class of all items to be placed in the list and then the > list would manage those subclasses of the list item object. I am no fan of Java and might even completely misunderstand what you mean, but in Java and (as far as I can see) D, all classes inherits from a class Object. This means that some sort of list programmed around the Object class can include ALL types of object since they explicitly or implicitly inherits Object. When dealing with lists, the only need I can see for templates, is when making lists of some general approach but should store only one type of objects. (Maybe for performance reasons?) Since I've never come over this issue, I've never needed templates in Java. Please tell me if there are other needs for templates that cannot be solved in Java or a template free D. I am always eager to learn :) Lars Ivar |
January 15, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Woodhead | I answer multiple messssages, not sure which. > I have not met a single person that is happy with anything on a > computer, especially programming languages. And you are right, a lot > has to do with lack of knowledge. But you know what, things that are > intuative in the first place don't have problems with people not > understanding them. :) > Hello, i'm quite happy that i have a computer. :) It might very well be that i have some lack of knowledge. The language I started with was Delphi, and I was perfectly happy. I still can't stand C++ (obviously because of my lack of knowledge :> ). Delphi is quite simple, but pretty efficient and the language design is very clean, so that it helps prevent bugs. Too little to misunderstand. Well, to a certain point. The lack of featues is a source of bugs as well. Such as not having dynamic arrays and such. But as I didn't know other languages besides a bit of C, i was happy. To my opinion, it *IS* the fault of C++ that it is much easier to write bad code in it as in some other languages. I have seen really bad Delphi code only once, and it was written by a kid which abviously didn't have a "real" book or had a bad teacher :> like no identation, and so on. I doubt there would be a big project consisting of bad Delphi code. It is also the choise which each person makes. Noone has ever tried to write clean code in BEFUNGE, because the language has not been designed for it. Take a look at any piece of C code written by an experienced BEFUNGE programmer - it's ready for a world-class obfuscation contest. For the ones who don't know: BEFUNGE programs is a multidirectional array of statements, which can be run in *any* direction. So when you state "goto", you're not only giving a target but also a direction. It's rather a toy in my opinion. Well, D seems to be a solution for me. Though it is based on a dirty language, i think it might just have enough checks to prevent bad technique, filling C and especially C++ code. --------------------------------- > > What is the purpose in generic programming? > What problems does it solve? > Is that problem a language problem? > How does Java live without it? > Generic programming allows you to write code once and use it for many kinds of objects, allowing you to do the same with different objects. Possible ways are: ---- WARNING, DESCRIPTION FOR KIDS! ---- 1. Subclassing. You have a basic "abstract" class which declares methods, for example: - "Get", "Set", "Resize" - virtual or abstract methods, not implemented; - "Insert", "Append", "Sort", and so on, which use the abstract methods to operate the storage, not touching the storage directly. The basic class contains no storage. Then you create another class based on this one, containing storage, and implement your virtual methods, operating on it. The "Insert", "Append", "Sort" start working automatically. Now, for example your storage was an array. You can also make a new subclass managing a linked list. Then you would want to reimplement not only virtuals, but also the rest of the functions because it makes it efficient. But if course, you can also only overload the virtuals, and it will work but probably painfully slow. OK, this is one of the things limiting generic programming, and i don't think it's solved by any system. Let's see another example. You have a class (TSolidList) that stores a list of objects of, for example, TSolid class. If you derive another class, like, TBetterSolid, which behaves the same, but stores data differently, you can also collect instances of TBetterSolid inside TSolidList without changes. The problem which i had with that, was that in Delphi such stored descendants would decay, say TBetterSolid would become a TSolid inside a TSolidList, so that i would have to either subclass the TSlidList to TBetterSolidList, or to cast the TSolid-s back into TBetterSolid-s, which requieres some confidence and is error-prone. QUESTION: does D circumvent this problem? Either someone actually read this far and can answer, or i'll check it myself. I guess it does, because ClassInfo is a part of the root object. 2. Macros C programmers usually have a macro like: #define MIN(a,b) ( ((a)>(b)) ? (b) : (a) ) which would always yield a minimum of two numbers of any type, or even of other types which support comparison. It basically makes text search and replacement, and is error-prone. This is the simplest and probably the oldest type of generic programming. They bloat the code, since they're copied on every occasion, but are thus efficient. But i think an advanced compiler would also inline functions as tiny as that, making them just as efficient. 3. Templates They follow the idea of macros. They take a type name and generate a class or a function or whatever by text or simple parse tree processing. They basically, beyond subclassing features, allow you to use unrelated kinds of underlying storage, which have the operations requiered, but are not derived from any common type. For example, having a template for <something operating on numbers> you can create thus this <something> from types like single, double-precision foating points, or even bignums or such. They solve efficiency problems for very tiny types, like integers or floats, which would become inefficient if packed into a class. Explanation Simple types: +----------+ | Double- | +Precision + |FP Number | +----------+ - can be stored as that in another structore Classes: +----------+ | Pointer |-------+ +----------+ | \./ +----------+ | Pointer |-------> Table of Method pointers +----------+ |something?| +----------+ | Double- | +Precision + |FP Number | +----------+ - only pointers are stored in further structures. Classes are very good for large objects which can also appear at different places, because only the pointer is copied, not necessarily the object itself. Packing such a small type as a number into a class would requiere a significant overhead at every access and during garbage collection. But to my opinion, a compiler could just as well optimize out such small classes to enable tight storage. That is, if a decision is made to make a 100% OO language, and certain limitations are made. Java simply doesn't bother with efficiency. ---------- I personally think that templates are often overused. You can just as well write a basic class, subclass it for basic types which are few, and make the rest with classes. Then strings would have to become a class too. Hmm. Maybe templates are a right decision in D anyway. |
January 16, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Ivar Igesund | In article <b03cek$2lv8$1@digitaldaemon.com>, Lars Ivar Igesund says... >I am no fan of Java and might even completely misunderstand what you mean, >but in Java and (as far as I can see) D, all classes inherits from a class >Object. >This means that some sort of list programmed around the Object class can >include ALL types of object since they explicitly or implicitly inherits >Object. True, but such lists can only be basic collections. If you wanted a sorted list for example, you'd need some sort of comparison method. In C++, you'd overload the < operator and you could have as many different types in the list as < operator overloads exist. It's more intuitive. >When dealing with lists, the only need I can see for templates, is when >making >lists of some general approach but should store only one type of objects. >(Maybe >for performance reasons?) Since I've never come over this issue, I've never >needed >templates in Java. > >Please tell me if there are other needs for templates that cannot be solved >in Java >or a template free D. I am always eager to learn :) Well as I said in my original post, Java stores type information with its data whereas C++ does not. Thus Java always knows what to do with an unknown type whereas C++ can not. Thus, C++ needs extra features to account for this. I still think free form templates are useful in any language in their own right, just as C macros are useful (though unhealthy). Cheers, Niall |
January 16, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Niall Douglas | In article <b03a3c$2kig$1@digitaldaemon.com>, Niall Douglas says... > >In article <b02uv8$2cnb$1@digitaldaemon.com>, Ben Woodhead says... >> >>Hello, I have a few questions. Perhaps someone can help me out. > >I might be able to. I disagree fundamentally with OO and through my arguments with OO gurus, I've learned a lot (though not been convinced I'm wrong!) :) > >>What is the purpose in generic programming? >>What problems does it solve? >>Is that problem a language problem? >>How does Java live without it? > >Firstly, I don't think Java does live without it. It's like operator overloading - Sun just removed it completely. Operator overloading, when used correctly, actually produces far more reliable, intuitive and thus bug-free code. > >I'll just outline what it is for those not familiar with these things, then say why it was incorporated. > >Now if for example I want a list object which maintains a list of another object, in Java I'd use a dual object approach - there'd be a list item object which would be the base class of all items to be placed in the list and then the list would manage those subclasses of the list item object. > >Using templates, you specify the list object as taking one or more parameters ie; it's like a mould used to "stamp" out objects. So if I want a list of string objects, it's class list<string> and equally class list<class<string>> works too (a list of lists of string). The point is with templates you write the class guts once, and the parameters determine the actual implementation. > >If you're familiar with C, then most use of parameterised macros can be replaced with templates eg; > >#define ADD(type) \ >static type Add ## type (type a, type b) \ >{ return a + b; } > >In templates becomes: > >template<class type> type Add(type a, type b) >{ return a + b; } > >The great problem I see with C++ templates is they are limited to type parameters. I'd personally like to see free-form parameters. > >You may be asking what can templates let me do other approaches cannot? In Java, I don't think there are any - Java stores lengthy meta-data about all its data constructs so the language always knows what type some data is and thus how to work with it. > >In a static system like C++, there is no knowledge of data type except at time of compilation - hence "new X" is useless unless X's type is immediately known. Templates are the way of implementing multi-type generic code without requiring a run-time system. > >BTW if you're thinking fine, let's add a run-time system - well, that's why objective C failed in competing against C++. Nowadays you may get away with it, but TBH if you want a nice big helpful run-time system you'd use C# or Java. > >One other point is that Java's solution to the above problems would require more code than in C++. Using abstract base classes to generalise objects to some collection class is fine but it really needs multiple inheritance to be useful. > >I think the most productive future for D would be to remain as a primarily static system, though I wouldn't mind seeing optional dynamic features like ObjC has. > >Cheers, >Niall > > Hi, AFAIK C++ offers at least integer template parameters. If you read http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html you will find a template specialized by a integer parameter. I think other value types can be used too, but I may be wrong. Your remarks about Java are correct, as someone said: "Every use of reflection shows a hole in the type system". Best regards, Daniel Yokomiso. |
January 16, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | In article <b039up$2kh4$1@digitaldaemon.com>, Sean L. Palmer says... > >"Ben Woodhead" <zander@echotech.ca> wrote in message news:b02upv$2cm3$1@digitaldaemon.com... >> Java is a different way of thinking. If you start with that language then you will be fine, but coming from C is not going to be fun. I will have to look at the ada templates to comment on the rest but it sounds >interesting. >> All this generic programming could be a solution to a problem with the language. Fix the problem and remove the need for generic programming like templates. This approach worked for Java and walter also didn't think templates were needed. > >You cannot have typesafe containers without language-supported generics. Not unless you want to cut-and-paste all your container code for every new type you wish to put into such a container. Then duplicate all your algorithm code for every container type times the number of types contained therein. The combinatorial explosion happens quickly. People will write a non-typesafe container, or a braindead linear algorithm, rather than do all that work. Non-typesafe containers lead to bugs in user code. If they do make all those classes, they will be unmaintainable. A bug in the original gets copied into all the subsequent classes. > >Generics are a fundamentally good thing. They allow you to reuse more code than OO does. Write a template algorithm once, and use it on anything that supports the necessary interfaces. It'd be good to explicitly specify those interfaces in the requirements somehow. Self-documentation. > >It would be super nice if D unified the type system so that one could write a template that would work on either a basic type or a user-defined type without modification. C++ only goes about halfway with this. > >Sean > > Hi, Generics is orthogonal to OO when we talk about reuse. OO usually provides class-based inheritance, which is one of the four forms of polimorphism (), but if it allows other kinds of polimorphism it can allow the same amount of reuse. But I agree that they are a Good Thing. What are the current problems on D's type system that it disallows templates be used with both primitives and user-defined types? Best regards, Daniel Yokomiso. |
January 16, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Ivar Igesund | In article <b03cek$2lv8$1@digitaldaemon.com>, Lars Ivar Igesund says... > >My first post to this newsgroup, so hi everyone! > >> Now if for example I want a list object which maintains a list of another object, in Java I'd use a dual object approach - there'd be a list item >object >> which would be the base class of all items to be placed in the list and >then the >> list would manage those subclasses of the list item object. > >I am no fan of Java and might even completely misunderstand what you mean, >but in Java and (as far as I can see) D, all classes inherits from a class >Object. >This means that some sort of list programmed around the Object class can >include ALL types of object since they explicitly or implicitly inherits >Object. > >When dealing with lists, the only need I can see for templates, is when >making >lists of some general approach but should store only one type of objects. >(Maybe >for performance reasons?) Since I've never come over this issue, I've never >needed >templates in Java. > >Please tell me if there are other needs for templates that cannot be solved >in Java >or a template free D. I am always eager to learn :) > >Lars Ivar > > Hi, Generics are used to allow type-safe programming. If you read type theory articles or books (I recommend Luca Cardelli papers. There is also a good column about classification theory in the Journal of Object Technology www.jot.fm) you'll see that there are two classes of operations: those defined on types (e.g. addition is defined for numeric types) and those defined on sets or types, aka kinds or meta-types (e.g.: minimum is a operation defined for every type that has a binary comparison operator). If you want type safety, we need to define methods that work only for certain types. With overloading in D we can define: int min(int left, int right) { return left < right ? left : right; } float min(float left, float right) { return left < right ? left : right; } char min(char left, char right) { return left < right ? left : right; } 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; } } So this template is a function generator. Most OO languages provide a equality operation defined for type Object, so any object can be compared to any object, and possibly be equal. If we want to perform some value equality test in our objects, we need to redefine the equal(Object) method using runtime type information (e.g.: instanceof and cast operators in Java) to recover the type lost. That means: cast the other object to my type, if it's ok, use all operations (methods or attribute selection) to compare we two, else return false. This allows heteregenous collections be defined (e.g. Lists or Sets with Object type in its methods). With templates we can define function or class generators that create specialized classes for the type parameter we give it. If you define a Matrix type in Java you need to decide which kind of type you will work with (choose one of the primitives, or Number, or Integer, or something else). The code written and tested for you Matrix of double class will be useless if your user want a Matrix of Complex instead. Current state of art makes usage of a Matrix of Number be worse (one or more orders) than using primitives, due to vtables and all this inheritance stuff. This may be done with inheritance only, if you want to force your users to always inherit from a particular class. But on some problem domains it's not plausible to force them. Look at Java's nio Buffer classes. The generic Buffer interface doesn't define get and put operations, because those are type-sensitive, instead it relies on documentation to enforce this. Any usage of Java's collection classes force's you to cast everything you put inside the collections when you get it back. There is nothing that Java or a template free D can't do without templates. They're Turing complete ;-) But there are lots of thing that are really awkward to do, and some of these casts will bite you someday, specially in large programs (I've got one yesterday when one of my objects put something in a container but the other expected something different. The fun thing is that I needed tests to discover this, because the compiler thinks casts are nice). Best regards, Daniel Yokomiso. |
January 16, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | "Daniel Yokomiso" <Daniel_member@pathlink.com> wrote in message news:b06mfi$1ifv$1@digitaldaemon.com... > In article <b039up$2kh4$1@digitaldaemon.com>, Sean L. Palmer says... > >Generics are a fundamentally good thing. They allow you to reuse more code > >than OO does. Write a template algorithm once, and use it on anything that > >supports the necessary interfaces. It'd be good to explicitly specify those > >interfaces in the requirements somehow. Self-documentation. > > > >It would be super nice if D unified the type system so that one could write > >a template that would work on either a basic type or a user-defined type without modification. C++ only goes about halfway with this. > > > >Sean > > Hi, > > Generics is orthogonal to OO when we talk about reuse. OO usually provides class-based inheritance, which is one of the four forms of polimorphism (), but > if it allows other kinds of polimorphism it can allow the same amount of reuse. > But I agree that they are a Good Thing. The kind of things OO is good for aren't well solved by templates, and vice versa. > What are the current problems on D's type system that it disallows templates be > used with both primitives and user-defined types? > > Best regards, > Daniel Yokomiso. It will currently work... mostly. There are some gotchas though. For one, you can't initialize "any type" properly. To the default maybe, but default means something totally different for ints (zero), floats (NaN!!), and UDT's (pretty much a collection of ints and floats for structs, but you can make your own ctor for classes). You also can't call methods on basic types (though there are some properties masquerading as methods). And you can't overload all the operators on UDT's (assignment for instance). Not a huge deal. There's another hole in D's template system in that it doesn't allow template parameters to be values; they have to be types. Having compile time values as template parameters opens the door to easier compile time template metaprogramming. It can be hacked around inelegantly with the current setup, by making struct types that contain enums or whatever. Doing recursion this way is almost impossible since you can't just make a type like you can a variable. Sean |
January 16, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso |
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;
}
When applied to an argument name they mean a value that is trivially constfolded, so "(ClassInfo $a, TypeInfo $b)" fall into a special rule very nicely.
|
January 18, 2003 Re: C and/or C++ in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | Hi, Comments embedded. "Sean L. Palmer" <seanpalmer@directvinternet.com> escreveu na mensagem news:b06q50$1klc$1@digitaldaemon.com... > > "Daniel Yokomiso" <Daniel_member@pathlink.com> wrote in message news:b06mfi$1ifv$1@digitaldaemon.com... > > In article <b039up$2kh4$1@digitaldaemon.com>, Sean L. Palmer says... > > >Generics are a fundamentally good thing. They allow you to reuse more > code > > >than OO does. Write a template algorithm once, and use it on anything > that > > >supports the necessary interfaces. It'd be good to explicitly specify > those > > >interfaces in the requirements somehow. Self-documentation. > > > > > >It would be super nice if D unified the type system so that one could > write > > >a template that would work on either a basic type or a user-defined type > > >without modification. C++ only goes about halfway with this. > > > > > >Sean > > > > Hi, > > > > Generics is orthogonal to OO when we talk about reuse. OO usually provides > > class-based inheritance, which is one of the four forms of polimorphism > (), but > > if it allows other kinds of polimorphism it can allow the same amount of > reuse. > > But I agree that they are a Good Thing. > > The kind of things OO is good for aren't well solved by templates, and vice > versa. Yes. > > > What are the current problems on D's type system that it disallows > templates be > > used with both primitives and user-defined types? > > > > Best regards, > > Daniel Yokomiso. > > It will currently work... mostly. There are some gotchas though. For one, > you can't initialize "any type" properly. To the default maybe, but default > means something totally different for ints (zero), floats (NaN!!), and UDT's > (pretty much a collection of ints and floats for structs, but you can make > your own ctor for classes). You also can't call methods on basic types > (though there are some properties masquerading as methods). And you can't > overload all the operators on UDT's (assignment for instance). > 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(); } 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? > Not a huge deal. > > There's another hole in D's template system in that it doesn't allow template parameters to be values; they have to be types. Having compile time values as template parameters opens the door to easier compile time template metaprogramming. It can be hacked around inelegantly with the current setup, by making struct types that contain enums or whatever. Doing > recursion this way is almost impossible since you can't just make a type like you can a variable. > > Sean > Yes, but Walter changed his mind and will implement some kind of value parameters. 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? Best regards, Daniel Yokomiso. "Daddy, why doesn't this magnet pick up this floppy disk?" --- 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 Burton Radons | "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 ;-) > > When applied to an argument name they mean a value that is trivially constfolded, so "(ClassInfo $a, TypeInfo $b)" fall into a special rule very nicely. > Perhaps I'm just tired but I don't understand what you mean by that. Please enlighten me. --- 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 |
Copyright © 1999-2021 by the D Language Foundation