digitalmars.D - Overloading opCast with multiple types
- Reiner Pope (36/36) Sep 30 2006 As we all know, opCast can only have one overload per class, because D
- Kristian (48/65) Oct 01 2006 =
-
Jarrett Billingsley
(24/24)
Oct 01 2006
"Kristian"
wrote in message - Kristian (26/51) Oct 01 2006 use
-
Jarrett Billingsley
(16/16)
Oct 01 2006
"Kristian"
wrote in message - Georg Wrede (4/14) Oct 01 2006 In addition to quoting difficulties, are you not familiar with the
- Jarrett Billingsley (6/9) Oct 01 2006 Man, I'd better just go with the flow, hm? I sure don't want to be left...
- Derek Parnell (10/22) Oct 01 2006 LOL... I used to think that way too until I actually tried a purpose-bui...
- Jarrett Billingsley (5/8) Oct 02 2006 Thing is, I tried Thunderbird, and .. I couldn't really tell a differenc...
- Kristian (6/15) Oct 03 2006 Well, I have been using Opera and it has been working fine (in addition,...
- Stewart Gordon (19/29) Oct 23 2006 (Had this in my drafts folder for a while, keep meaning to post it!)
- Jarrett Billingsley (8/14) Oct 23 2006 None, actually. I only have one news server so I don't have trouble wit...
-
Stewart Gordon
(19/30)
Oct 01 2006
- pragma (12/43) Oct 02 2006 Well, while we're on the topic, I might as well mention this variant as
-
Stewart Gordon
(15/23)
Oct 03 2006
- Pragma (5/23) Oct 03 2006 Mea culpa.
- Kristian (20/23) Oct 01 2006 [snip]
- Stewart Gordon (21/42) Oct 03 2006 It's only simpler because the compiler wants to treat opCast just like
As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion. Anyway, I have a solution here: give it a parameter, which is the type (we pass this parameter in the form of a template). Here's the magic: class Test { int x; Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of the required type exists"); return new Foo(x); } Bar myCast(TBar : Bar)() { static assert(is(TBar == Bar), "No cast of the required type exists"); return new Bar(x); } FooExtender2 myCast(T : FooExtender2)() { static assert(is(T == FooExtender2), "No cast of the required type exists"); return new FooExtender2(x); } this(int _x) {x = _x;} } and it is called like this: Test a = new Test(5); Foo f = a.myCast!(Foo); // Property syntax means the second () is unnecessary, so it looks almost like cast(Foo)a; Bar b = a.myCast!(Bar); // Useless u = a.myCast!(Useless); // Fails -- no template specialization exists // FooExtender t = a.myCast!(FooExtender); // Fails the static assert (TFoo == Foo) This code works right now. The static asserts are necessary because template specialization doesn't have the expressiveness of is expressions. I want the ability to say, "use this specialization for this type only, and don't use it for the subtypes." If this were supported under opCast, I would say that it should work by using templates as I have above, and adding a specialization type, so that templates could look like this: myCast(TFoo == Foo)() { return new Foo(x); }. (The '==' syntax is the noteworthy bit) Let me know what you think, Reiner
Sep 30 2006
On Sun, 01 Oct 2006 01:25:15 +0300, Reiner Pope = <reiner.pope REMOVE.THIS.gmail.com> wrote:As we all know, opCast can only have one overload per class, because D==doesn't support overloading by return type. That is a really silly =limitation, in my opinion. Anyway, I have a solution here: give it a =parameter, which is the type (we pass this parameter in the form of a ==template). Here's the magic: class Test { int x; Foo myCast(TFoo : Foo)() { static assert(is(TFoo =3D=3D Foo), "No cas=t of =the required type exists"); return new Foo(x); } Bar myCast(TBar : Bar)() { static assert(is(TBar =3D=3D Bar), "No ca=st of =the required type exists"); return new Bar(x); } FooExtender2 myCast(T : FooExtender2)() { static assert(is(T =3D=3D =FooExtender2), "No cast of the required type exists"); return new =FooExtender2(x); } this(int _x) {x =3D _x;} }[snip] Actually I was thinking something similar a while ago. Then I thought th= at = maybe there is only one opCast() for a reason. And you could use functio= ns = as 'toString()' to do the casting (but, yeah, that's explicit). Anyway, I think the opCasts can also be implemented as follows: class Obj { int opCast(out int dst) {return(dst =3D ...);} Foo opCast(out Foo dst) {return(dst =3D ...);} } Or in some other way which don't complicate the implementation of = compilers. (Of course, the previous syntax makes it cumbersome to call = opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to us= e = cast statements anyway (e.g. "cast(int)obj").) Finally I have to say that I think the implicit type casting in C++ coul= d = work better. For example: class String { operator int() const; operator char *() const; }; void func(int v); void func(char *s); String s; func(s); //error: ambigious call Because 'String' can be casted to 'int' and 'char *', the compiler don't= = know which one to use. Of course, 's' should be casted to 'char *' becau= se = the class represents a string (i.e. 'char *'). This could be solved by using some kind of preference ordering. For = example (don't pay attention to the syntax): class String { preference 2 operator int() const; preference 1 operator char *() const; //prefer 'char *' over 'int'= }; So, if D will have multiple opCasts along with the implicit type = conversion, maybe something similar could be used to solve problems with= = implicit casting.
Oct 01 2006
"Kristian" <kjkilpi gmail.com> wrote in message news:op.tgqne1b35xlco7 mist... ------------------------------------------- Anyway, I think the opCasts can also be implemented as follows: class Obj { int opCast(out int dst) {return(dst = ...);} Foo opCast(out Foo dst) {return(dst = ...);} } Or in some other way which don't complicate the implementation of compilers. (Of course, the previous syntax makes it cumbersome to call opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to use cast statements anyway (e.g. "cast(int)obj").) -------------------------------------------- Of course, with that method, something like Obj o = new Obj(); func(cast(int)o); Wouldn't work, because there is no location to pass into the opCast; it's just a temporary. I've gotten quite used to just having ".toXXX" or ".asXXX" methods. It can be far more obvious what you're doing, and you can pass additional parameters to it unlike a cast. That, and it can look nicer too: int x = (cast(ArrayType)object)[4]; vs int x = object.asArrayType[4];
Oct 01 2006
On Sun, 01 Oct 2006 18:24:50 +0300, Jarrett Billingsley = <kb3ctd2 yahoo.com> wrote:"Kristian" <kjkilpi gmail.com> wrote in message news:op.tgqne1b35xlco7 mist... ------------------------------------------- Anyway, I think the opCasts can also be implemented as follows: class Obj { int opCast(out int dst) {return(dst =3D ...);} Foo opCast(out Foo dst) {return(dst =3D ...);} } Or in some other way which don't complicate the implementation of compilers. (Of course, the previous syntax makes it cumbersome to call=opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to =usecast statements anyway (e.g. "cast(int)obj").) -------------------------------------------- Of course, with that method, something like Obj o =3D new Obj(); func(cast(int)o); Wouldn't work, because there is no location to pass into the opCast; i=t'sjust a temporary.Well yes, unless the compiler generates a temporary object that will be = = valid within the scope. For example, the previous example, will become: int _tmp; Obj o =3D new Obj(); func(o.opCast(_tmp)); The syntax of opCast() is a matter of implementation only: which is the = = simpliest way for the compiler. If not, then the C++ styled operators = could be used in D also. BTW, you could also have: class Obj { int opCast(int) {return(...);} Foo opCast(Foo) {return(...);} } Parameters are just used to overload the operators.I've gotten quite used to just having ".toXXX" or ".asXXX" methods. I=t =can be far more obvious what you're doing, and you can pass additional parameters to it unlike a cast. That, and it can look nicer too: int x =3D (cast(ArrayType)object)[4]; vs int x =3D object.asArrayType[4];Yep, I also prefer such functions over cast statements. But if D would have implicit type conversion with multiple opCasts, then= = you could just do "x =3D y;". Would this be a good thing?... I don't kno= w. = (Surely it would be less informative, if nothing else.)
Oct 01 2006
"Kristian" <kjkilpi gmail.com> wrote in message news:op.tgq6xi1s5xlco7 mist... --------------------------------------------- Yep, I also prefer such functions over cast statements. But if D would have implicit type conversion with multiple opCasts, then you could just do "x = y;". Would this be a good thing?... I don't know. (Surely it would be less informative, if nothing else.) --------------------------------------------- (my newsreader does not like quoting your posts for some reason!) Walter has expressed his.. disgust? Lack of support? for C++-style implicit casts, and I agree with him to an extent. For trying to make "value" types (such as a BigInteger class or something), not having implicit casts can make it cumbersome to use the class, but to be honest, I've never had to write such a type. In any case, I wouldn't cross my fingers for anything like this to happen soon ;)
Oct 01 2006
Jarrett Billingsley wrote:"Kristian" <kjkilpi gmail.com> wrote in message news:op.tgq6xi1s5xlco7 mist... --------------------------------------------- Yep, I also prefer such functions over cast statements. But if D would have implicit type conversion with multiple opCasts, then you could just do "x = y;". Would this be a good thing?... I don't know. (Surely it would be less informative, if nothing else.) --------------------------------------------- (my newsreader does not like quoting your posts for some reason!)In addition to quoting difficulties, are you not familiar with the security and usage issues Microsoft Outlook Express v 6 has? Most other people here are already using something else.
Oct 01 2006
"Georg Wrede" <georg.wrede nospam.org> wrote in message news:45203A8F.6030800 nospam.org...In addition to quoting difficulties, are you not familiar with the security and usage issues Microsoft Outlook Express v 6 has? Most other people here are already using something else.Man, I'd better just go with the flow, hm? I sure don't want to be left out. This is the only newsgroup I read, and Kristian is the only user whose posts don't quote right. I think I can live with OE.
Oct 01 2006
On Sun, 1 Oct 2006 18:59:00 -0400, Jarrett Billingsley wrote:"Georg Wrede" <georg.wrede nospam.org> wrote in message news:45203A8F.6030800 nospam.org...LOL... I used to think that way too until I actually tried a purpose-built newsreader that adhered to standards. I'll never go back to that toy newsreader again. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 2/10/2006 10:01:16 AMIn addition to quoting difficulties, are you not familiar with the security and usage issues Microsoft Outlook Express v 6 has? Most other people here are already using something else.Man, I'd better just go with the flow, hm? I sure don't want to be left out. This is the only newsgroup I read, and Kristian is the only user whose posts don't quote right. I think I can live with OE.
Oct 01 2006
"Derek Parnell" <derek nomail.afraid.org> wrote in message news:96d4ls69hbtj.cdpdafq3hhs3.dlg 40tude.net...LOL... I used to think that way too until I actually tried a purpose-built newsreader that adhered to standards. I'll never go back to that toy newsreader again.Thing is, I tried Thunderbird, and .. I couldn't really tell a difference from OE. Except that it was slower. Are there any other good free readers for Windows then?
Oct 02 2006
On Mon, 02 Oct 2006 23:21:37 +0300, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:"Derek Parnell" <derek nomail.afraid.org> wrote in message news:96d4ls69hbtj.cdpdafq3hhs3.dlg 40tude.net...Well, I have been using Opera and it has been working fine (in addition, I like to surf and read NGs with the same program). Though it took a while to setup the digitalmars NGs: Opera didn't connect to the NG server right away.LOL... I used to think that way too until I actually tried a purpose-built newsreader that adhered to standards. I'll never go back to that toy newsreader again.Thing is, I tried Thunderbird, and .. I couldn't really tell a difference from OE. Except that it was slower. Are there any other good free readers for Windows then?
Oct 03 2006
Jarrett Billingsley wrote:"Derek Parnell" <derek nomail.afraid.org> wrote in message news:96d4ls69hbtj.cdpdafq3hhs3.dlg 40tude.net...(Had this in my drafts folder for a while, keep meaning to post it!) Whenever I've moved from OE to anything else, one of the first things I've noticed is freedom from OE's many annoying bugs. How many of these bit you? http://www.epinions.com/content_67328904836 OK, so other newsreaders have bugs too, but not many have an array of bugs that's quite as annoying as this.LOL... I used to think that way too until I actually tried a purpose-built newsreader that adhered to standards. I'll never go back to that toy newsreader again.Thing is, I tried Thunderbird, and .. I couldn't really tell a difference from OE. Except that it was slower.Are there any other good free readers for Windows then?How different is Thunderbird from the newsreader facilities of Mozilla Application Suite/SeaMonkey (which I use)? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Oct 23 2006
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:ehijj9$1r6d$3 digitaldaemon.com...to post it!)Whenever I've moved from OE to anything else, one of the first things I've noticed is freedom from OE's many annoying bugs. How many of these bit you? http://www.epinions.com/content_67328904836None, actually. I only have one news server so I don't have trouble with it posting to the wrong server; I don't have a signature; and I don't use any of the watch/ignore/view features. The only problem I've ever run into is the random not-quoting bug. So from my experience, it's OK for me :)How different is Thunderbird from the newsreader facilities of Mozilla Application Suite/SeaMonkey (which I use)?I've heard some people talking about SeaMonkey and how they like it. I'll have to check it out sometime.
Oct 23 2006
Reiner Pope wrote:As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion. Anyway, I have a solution here: give it a parameter, which is the type (we pass this parameter in the form of a template). Here's the magic: class Test { int x; Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of the required type exists"); return new Foo(x); }<snip> Something to this effect has been proposed before. However, the idea of having to put a static assert in each would make it somewhat more cumbersome than it should be. Moreover, a problem with using templates is deciding how the vtbl would work. There have been a number of proposals for ways to do multiple casts. http://www.prowiki.org/wiki4d/wiki.cgi?FeatureRequestList My proposal: http://tinyurl.com/p2pn4 Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Oct 01 2006
Stewart Gordon wrote:Reiner Pope wrote:Well, while we're on the topic, I might as well mention this variant as well. :) class Foobar{ void* opCast(TypeInfo type){ /* perform cast and return instance/value as needed } } Not only does this play fair with D's overload rules (no overload by return type) but it handles every possible case for casting, and IMO, is no more cumbersome than varargs are. For what it's worth, the runtime already does something similar when a dynamic cast is required.As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion. Anyway, I have a solution here: give it a parameter, which is the type (we pass this parameter in the form of a template). Here's the magic: class Test { int x; Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of the required type exists"); return new Foo(x); }<snip> Something to this effect has been proposed before. However, the idea of having to put a static assert in each would make it somewhat more cumbersome than it should be. Moreover, a problem with using templates is deciding how the vtbl would work. There have been a number of proposals for ways to do multiple casts. http://www.prowiki.org/wiki4d/wiki.cgi?FeatureRequestList My proposal: http://tinyurl.com/p2pn4 Stewart.
Oct 02 2006
pragma wrote: <snip>Well, while we're on the topic, I might as well mention this variant as well. :) class Foobar{ void* opCast(TypeInfo type){ /* perform cast and return instance/value as needed } }<snip> How can you return an artibrary value as a void*? Besides, it looks exactly like what you proposed ages ago and I've already critiqued, as you'd know if you'd read what I linked to. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Oct 03 2006
Stewart Gordon wrote:pragma wrote: <snip>Mea culpa. Sometimes, some ideas are hard to let go. :) -- - EricAnderton at yahooWell, while we're on the topic, I might as well mention this variant as well. :) class Foobar{ void* opCast(TypeInfo type){ /* perform cast and return instance/value as needed } }<snip> How can you return an artibrary value as a void*? Besides, it looks exactly like what you proposed ages ago and I've already critiqued, as you'd know if you'd read what I linked to. Stewart.
Oct 03 2006
On Sun, 01 Oct 2006 01:25:15 +0300, Reiner Pope <reiner.pope REMOVE.THIS.gmail.com> wrote:As we all know, opCast can only have one overload per class, because D doesn't support overloading by return type. That is a really silly limitation, in my opinion.[snip] I think it's not important to consider how overloadable opCasts can be implemented. The documentation indeed states "Since functions cannot be overloaded based on return value, there can be only one opCast per struct or class.", but that's not the actual reason why there is only one opCast. It may be a practical reason (which makes compiler implementation simplier), but it's not a physical restriction preventing multiple opCasts. The compiler could very well support the following: class Obj { int opCast(); float opCast(); } It just depends on how one makes the compiler parse source files. So, first we should discuss if there should be more than one opCast, and should there be implicit type conversion. How should it work in ambigious cases. Is that a reason why there is only one opCast? Or is it because implicit conversion makes code harder to read (it's less informative)?
Oct 01 2006
Kristian wrote: <snip>The documentation indeed states "Since functions cannot be overloaded based on return value, there can be only one opCast per struct or class.", but that's not the actual reason why there is only one opCast. It may be a practical reason (which makes compiler implementation simplier),It's only simpler because the compiler wants to treat opCast just like any other identifier. But that is itself partly down to the fact that opCast is an identifier like any other. As such, you can call it as obj.opCast() just like any other function.but it's not a physical restriction preventing multiple opCasts. The compiler could very well support the following: class Obj { int opCast(); float opCast(); } It just depends on how one makes the compiler parse source files. So, first we should discuss if there should be more than one opCast, and should there be implicit type conversion. How should it work in ambigious cases.My impression was that it works only on casting to the exact return type of opCast.Is that a reason why there is only one opCast? Or is it because implicit conversion makes code harder to read (it's less informative)?Please see my proposal http://tinyurl.com/p2pn4 It's very similar to your idea, but makes use of "cast", which is already a keyword, to be treated differently from ordinary function names. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Oct 03 2006
Stewart Gordon wrote:Please see my proposal http://tinyurl.com/p2pn4 It's very similar to your idea, but makes use of "cast", which is already a keyword, to be treated differently from ordinary function names. Stewart.I like that idea. Does anyone know what Walters long term plans are regarding the casting operator? It seems to me that a single cast operator is extremely lacking. So does anyone know if this is just temporary or does Walter not see a need for multiple casting operators?
Oct 03 2006
On Tue, 03 Oct 2006 21:39:15 +0300, Stewart Gordon <smjg_1998 yahoo.com> wrote:Kristian wrote: <snip>[snip]Please see my proposal http://tinyurl.com/p2pn4 It's very similar to your idea, but makes use of "cast", which is already a keyword, to be treated differently from ordinary function names. Stewart.If there will be multiple cast functions some day, I think the syntax "T cast() {...}" would be very nice. As you said, it makes a distinction from ordinary functions (and operator functions) by its name, which is a reserved word. (Of course, assuming that D will never have an ability to overload functions by their return values... ;) )
Oct 03 2006