digitalmars.D - Classes derived from basic type ?
- Vladimir (7/7) Mar 30 2005 Hello All !
- Carlos Santander B. (5/15) Mar 30 2005 There's no way to do it in D. In D (just like in many other languages)
- Georg Wrede (34/39) Apr 09 2005 While we're at subtleties in a language, this is a golden example of suc...
- Sean Kelly (27/39) Apr 09 2005 I agree. And the lack of consistency between arrays and primitive types...
- Kris (11/54) Apr 09 2005 such!
- pragma (4/15) Apr 11 2005 Would something like this work?
- Sean Kelly (3/19) Apr 11 2005 Yes :) This is an excellent proposal for how to implement this feature.
- Vladimir (46/48) Apr 12 2005 It seems good, but in my opinion typedef-blocks and structs are too simi...
- pragma (11/59) Apr 12 2005 This could work, but the only problem is that you loose implicit casting...
- Vladimir (5/58) Apr 13 2005 Absolutely agree.
-
Stewart Gordon
(16/34)
Apr 20 2005
- Vladimir (5/43) Apr 21 2005 In any case defining new type you loose implicit casting to base type. I...
- xs0 (11/28) Apr 10 2005 Hmm, wouldn't a struct fit better, because of value semantics? It should...
Hello All ! I'm just studying D and have been impressed with it's features. But some of its I can't understand, for example, presence of .sort method. I'm wondering, if D have so compicated base types, which in most senses looks exactly like classes, why can't I derive my own classes from it ? Is would be very useful in meny cases, and I'm remembering meny uses of it for example in python.
Mar 30 2005
Vladimir wrote:Hello All ! I'm just studying D and have been impressed with it's features. But some of its I can't understand, for example, presence of .sort method. I'm wondering, if D have so compicated base types, which in most senses looks exactly like classes, why can't I derive my own classes from it ? Is would be very useful in meny cases, and I'm remembering meny uses of it for example in python.There's no way to do it in D. In D (just like in many other languages) not everything is an object. _______________________ Carlos Santander Bernal
Mar 30 2005
But some of its I can't understand, for example, presence of .sort method. I'm wondering, if D have so compicated base types, which in most senses looks exactly like classes, why can't I derive my own classes from it ? Is would be very useful in meny cases, and I'm remembering meny uses of it for example in python.While we're at subtleties in a language, this is a golden example of such! A person new to D, looks at things like arrays, and sees .sort methods and other stuff. This leads -- most naturally -- one to think that we have classes here. Skimming the documentation while believing this, only makes a person confused: ehh, how come there's no proper documentation for these classes, where are all these methods, why can't I derive, etc. One does not immediately see that there _are_ no classes here. One only somehow (especially, this being a new language) assumes, that we then may have some new philosophy or new kinds of classes in _this_ language. Such significantly slows down the process of learning. With any bad luck, such misconceptions stay uncorrected for a longer time, and quite a lot learned during that period, gets its fundaments wrong in one's head. In other words, the reader is entertaining a mental model of the language that is not congruent with that of the developers', which leads to unnecessarily complicated mental structures and gymnastics, when trying to "understand" (or even just learn by heart) the properties of the language. Some of these may be very hard to undo, even after one has been told that the original concept was wrong. Even for smart persons, this often happens only after having visited each particular "collateral misconception" separately -- in spite of the fact that with reason one should be able to let the correction "cascade" through all the cases. Old and rooted (mis)conceptions don't die that easily. (Ex. Some people have a hard time quickly using the right name of many months late in the year.) Even if one is able to get the D facts right at the end, what really does stay, is a belief that this is a labyrinthine and complicated language. And full of trip stones. -- Yet another misconception in itself. ---- So, if something looks like A, it should be A and not B. Convenience shortcuts and such are bad *if* they hamper clarity of vision. What I am saying is: in the future we should avoid conveniences that to the uninitiated look like something they aren't.
Apr 09 2005
In article <42581AE6.5070103 nospam.org>, Georg Wrede says...I agree. And the lack of consistency between arrays and primitive types in this respect is IMO a bad thing. I would prefer if any function: R func( X val, ... ) Could be called normally: X val; func( val, a, b, c ); Or dotted: val.func( a, b, c ); Even better would be if the compiler saw a class derived from a primitive type: class X : int {} then the primitive type would be interpreted as a wrapper class exposing all the usual operator overloads and such. But this second bit isn't strictly necessary as it would be easy enough to define a template class for this purpose: So primitives could be inherited like so: class MyInt : ClassOf!(int) {} In fact I think I may define a class like this for Ares just to have it around. SeanBut some of its I can't understand, for example, presence of .sort method. I'm wondering, if D have so compicated base types, which in most senses looks exactly like classes, why can't I derive my own classes from it ? Is would be very useful in meny cases, and I'm remembering meny uses of it for example in python.While we're at subtleties in a language, this is a golden example of such! A person new to D, looks at things like arrays, and sees .sort methods and other stuff. This leads -- most naturally -- one to think that we have classes here. Skimming the documentation while believing this, only makes a person confused: ehh, how come there's no proper documentation for these classes, where are all these methods, why can't I derive, etc.
Apr 09 2005
"Sean Kelly" <sean f4.ca> wrote in message news:d39j88$2d2q$1 digitaldaemon.com...In article <42581AE6.5070103 nospam.org>, Georg Wrede says...such!But some of its I can't understand, for example, presence of .sort method. I'm wondering, if D have so compicated base types, which in most senses looks exactly like classes, why can't I derive my own classes from it ? Is would be very useful in meny cases, and I'm remembering meny uses of it for example in python.While we're at subtleties in a language, this is a golden example ofin thisA person new to D, looks at things like arrays, and sees .sort methods and other stuff. This leads -- most naturally -- one to think that we have classes here. Skimming the documentation while believing this, only makes a person confused: ehh, how come there's no proper documentation for these classes, where are all these methods, why can't I derive, etc.I agree. And the lack of consistency between arrays and primitive typesrespect is IMO a bad thing. I would prefer if any function: R func( X val, ... ) Could be called normally: X val; func( val, a, b, c ); Or dotted: val.func( a, b, c ); Even better would be if the compiler saw a class derived from a primitivetype:class X : int {} then the primitive type would be interpreted as a wrapper class exposingall theusual operator overloads and such. But this second bit isn't strictly necessary as it would be easy enough to define a template class for this purpose: So primitives could be inherited like so: class MyInt : ClassOf!(int) {} In fact I think I may define a class like this for Ares just to have itaround.SeanIt would indeed be very nice were D to cleanly support an ability for adding once noted) - Kris
Apr 09 2005
In article <d39pkv$313k$1 digitaldaemon.com>, Kris says..."Sean Kelly" <sean f4.ca> wrote in messageWould something like this work? http://www.prowiki.org/wiki4d/wiki.cgi?Typedef-Block - EricAnderton at yahooclass MyInt : ClassOf!(int) {} In fact I think I may define a class like this for Ares just to have itaround.SeanIt would indeed be very nice were D to cleanly support an ability for adding once noted)
Apr 11 2005
In article <d3e93k$2tco$1 digitaldaemon.com>, pragma says...In article <d39pkv$313k$1 digitaldaemon.com>, Kris says...Yes :) This is an excellent proposal for how to implement this feature. Sean"Sean Kelly" <sean f4.ca> wrote in messageWould something like this work? http://www.prowiki.org/wiki4d/wiki.cgi?Typedef-Blockclass MyInt : ClassOf!(int) {} In fact I think I may define a class like this for Ares just to have itaround.SeanIt would indeed be very nice were D to cleanly support an ability for adding once noted)
Apr 11 2005
pragma wrote:Would something like this work? http://www.prowiki.org/wiki4d/wiki.cgi?Typedef-BlockIt seems good, but in my opinion typedef-blocks and structs are too similar to exists as different constructs. If we allow struct inheritance by means of just adding base struct members to the front of child struct, and allow struct inheritance from basic types it would solve the problem. Casting child struct to base struct can be allowed, but all struct methods must be treated as non-virtual, so we can keep compitability with C structs. Examples: // analog for typedef int MyInt struct MyInt: int {} // ( super is just shortcat for cast(int*)this ) struct SmartInt: int { public SmartInt opPos(){ // change opPos into an absolute-value operator if(*super < 0) return(-*this); return(*this); } } // static array // ( using template syntax ) struct AutoSumIntArray(N): int[N] { private int _sum = 0; int sum() { return _sum; } int opIndexAssign(int val, int idx) { _sum -= (*super)[idx]; (*super)[idx] = val; _sum += (*super)[idx]; } int opSliceAssign(...) { ... } } // dynamic array // must use class syntax becouse of reference semantic class BoundedIntDynArray: int[] { int bound = 100; this(int l) { if(l > bound) assert(0); super(l); } void length(int l) { if(l > bound) assert(0); super.length = l; } } -- Vladimir
Apr 12 2005
In article <d3g3c6$2576$1 digitaldaemon.com>, Vladimir says...pragma wrote:This could work, but the only problem is that you loose implicit casting since the memory footprint of some of your examples are not the same as the underlying type. But then again, you'd have to use the typedef explicitly (casting and whatnot) to get the functionality you need, so I guess there's little difference. This way you get shorthand-templating for 'free' which is a huge plus. (use of 'super' is nice too) As long as you get to inherit the base scalar's operators and properties, I honestly don't care which style makes it through. Its too useful a construct not to have. :) - EricAnderton at yahooWould something like this work? http://www.prowiki.org/wiki4d/wiki.cgi?Typedef-BlockIt seems good, but in my opinion typedef-blocks and structs are too similar to exists as different constructs. If we allow struct inheritance by means of just adding base struct members to the front of child struct, and allow struct inheritance from basic types it would solve the problem. Casting child struct to base struct can be allowed, but all struct methods must be treated as non-virtual, so we can keep compitability with C structs. Examples: // analog for typedef int MyInt struct MyInt: int {} // ( super is just shortcat for cast(int*)this ) struct SmartInt: int { public SmartInt opPos(){ // change opPos into an absolute-value operator if(*super < 0) return(-*this); return(*this); } } // static array // ( using template syntax ) struct AutoSumIntArray(N): int[N] { private int _sum = 0; int sum() { return _sum; } int opIndexAssign(int val, int idx) { _sum -= (*super)[idx]; (*super)[idx] = val; _sum += (*super)[idx]; } int opSliceAssign(...) { ... } } // dynamic array // must use class syntax becouse of reference semantic class BoundedIntDynArray: int[] { int bound = 100; this(int l) { if(l > bound) assert(0); super(l); } void length(int l) { if(l > bound) assert(0); super.length = l; } } -- Vladimir
Apr 12 2005
pragma wrote:Only if I add new data members.Examples: // analog for typedef int MyInt struct MyInt: int {} // ( super is just shortcat for cast(int*)this ) struct SmartInt: int { public SmartInt opPos(){ // change opPos into an absolute-value operator if(*super < 0) return(-*this); return(*this); } } // static array // ( using template syntax ) struct AutoSumIntArray(N): int[N] { private int _sum = 0; int sum() { return _sum; } int opIndexAssign(int val, int idx) { _sum -= (*super)[idx]; (*super)[idx] = val; _sum += (*super)[idx]; } int opSliceAssign(...) { ... } } // dynamic array // must use class syntax becouse of reference semantic class BoundedIntDynArray: int[] { int bound = 100; this(int l) { if(l > bound) assert(0); super(l); } void length(int l) { if(l > bound) assert(0); super.length = l; } }This could work, but the only problem is that you loose implicit casting since the memory footprint of some of your examples are not the same as the underlyingtype. But then again, you'd have to use the typedef explicitly (casting and whatnot) to get the functionality you need, so I guess there's little difference. This way you get shorthand-templating for 'free' which is a huge plus. (use of 'super' is nice too) As long as you get to inherit the base scalar's operators and properties, I honestly don't care which style makes it through. Its too useful a construct not to have. :)Absolutely agree. -- Vladimir
Apr 13 2005
Vladimir wrote: <snip>If we allow struct inheritance by means of just adding base struct members to the front of child struct, and allow struct inheritance from basic types it would solve the problem. Casting child struct to base struct can be allowed, but all struct methods must be treated as non-virtual, so we can keep compitability with C structs. Examples: // analog for typedef int MyInt struct MyInt: int {} // ( super is just shortcat for cast(int*)this ) struct SmartInt: int { public SmartInt opPos(){ // change opPos into an absolute-value operator if(*super < 0) return(-*this); return(*this); } }<snip> This is like an idea that I thought of, though on existing structs/unions rather than primitive types. Under my idea, the derived type would be a union rather than a struct. This is because with the way D works, it doesn't make so much sense to add data members - since structs have value semantics, increasing the size means that it isn't really a value of the base type anymore. OTOH it does make a bit of sense to add methods and/or views of the data to an existing struct (such as one defined in an external API). But I guess this idea could work on built-in types as well.... Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 20 2005
Stewart Gordon wrote:Vladimir wrote: <snip>In any case defining new type you loose implicit casting to base type. In what situation size difference could cause a problem ?If we allow struct inheritance by means of just adding base struct members to the front of child struct, and allow struct inheritance from basic types it would solve the problem. Casting child struct to base struct can be allowed, but all struct methods must be treated as non-virtual, so we can keep compitability with C structs. Examples: // analog for typedef int MyInt struct MyInt: int {} // ( super is just shortcat for cast(int*)this ) struct SmartInt: int { public SmartInt opPos(){ // change opPos into an absolute-value operator if(*super < 0) return(-*this); return(*this); } }<snip> This is like an idea that I thought of, though on existing structs/unions rather than primitive types. Under my idea, the derived type would be a union rather than a struct. This is because with the way D works, it doesn't make so much sense to add data members - since structs have value semantics, increasing the size means that it isn't really a value of the base type anymore.OTOH it does make a bit of sense to add methods and/or views of the data to an existing struct (such as one defined in an external API).But I guess this idea could work on built-in types as well.... Stewart.-- Vladimir
Apr 21 2005
But this second bit isn't strictly necessary as it would be easy enough to define a template class for this purpose: So primitives could be inherited like so: class MyInt : ClassOf!(int) {} In fact I think I may define a class like this for Ares just to have it around.Hmm, wouldn't a struct fit better, because of value semantics? It should be much faster, too, because there's no "this" and virtual function dereferencing going on.. OTOH, you can't derive structs, afaik, so it may not be a good thing to do in a template. You could probably mixin stuff, though; having a template with all the usual operators, and being able to add new stuff should be ok, I guess (for a silly example, it may be dangerous to have a type that behaves like an int with all the operators, except that if you divide it by 5 it formats your hard drive? What if you forget it does that? :) xs0
Apr 10 2005