www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Multiple opCast per class

reply Vladimir <kv11111 mail.ru> writes:
Hello All !

From specs: "Since functions cannot be overloaded based on return value,
there can be only one opCast per struct or class."

Why not to invent some syntax to allow multiple opCast ? It would be really
convinient and usefull, moreover, it seems to be better then inventing some
more magic methods such as toString.
To do it we can use something like

int opCast(int dummy);
char opCast(char dummy);

or

void opCast(out int res);
void opCast(out char res);

or

void opCast_r(out int res);
void opCast_r(out char res);


-- 
          Vladimir
Mar 31 2005
next sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Vladimir wrote:
 void opCast(out int res);
 void opCast(out char res);

This has been proposed before, by me and by others previous to me. I still think its a really good idea, and hope you have more luck making it happen. -- Chris Sauls
Mar 31 2005
parent Vladimir <kv11111 mail.ru> writes:
Chris Sauls wrote:
 Vladimir wrote:
 void opCast(out int res);
 void opCast(out char res);

This has been proposed before, by me and by others previous to me. I still think its a really good idea, and hope you have more luck making it happen.

May be we can at least add this to wishlist ? -- Vladimir
Mar 31 2005
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
I think this would be very useful.


Sean
Mar 31 2005
prev sibling next sibling parent Benjamin Herr <ben 0x539.de> writes:
Vladimir wrote:
 Hello All !
 
 Why not to invent some syntax to allow multiple opCast ? It would be really
 convinient and usefull, moreover, it seems to be better then inventing some
 more magic methods such as toString.
 To do it we can use something like
 
 int opCast(int dummy);
 char opCast(char dummy);
 
 or
 
 void opCast(out int res);
 void opCast(out char res);
 
 or
 
 void opCast_r(out int res);
 void opCast_r(out char res);

I support this. -Benjamin
Mar 31 2005
prev sibling parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Vladimir wrote:
 Hello All !
 
 From specs: "Since functions cannot be overloaded based on return value,
 there can be only one opCast per struct or class."
 
 Why not to invent some syntax to allow multiple opCast ? It would be really
 convinient and usefull, moreover, it seems to be better then inventing some
 more magic methods such as toString.
 To do it we can use something like
 
 int opCast(int dummy);
 char opCast(char dummy);
 
 or
 
 void opCast(out int res);
 void opCast(out char res);
 
 or
 
 void opCast_r(out int res);
 void opCast_r(out char res);
 
 

void opCast (out resultType result, in valueType value) {... result = cast(resultType)value } This would allow conversion to be specified between any pair of types. It can't be included in the type spec, because then types defined afterwards couldn't have any conversion defined to types defined earlier. So two arguments are needed. Note that because this is a cast operation, the _r form doesn't apply, unless I'm overlooking something. Also note that this is NOT a function, but rather a procedure. It doesn't have a return value, it has an out parameter. (This shouldn't make a difference, as a function with one out parameter is logically equivalent to a function, but the D syntax rules cause it to make an effective difference.) The problem with this resolution is that the conversion becomes a procedure call...syntactically a different operation, and one that cannot be chained. This would require special compiler logic.
Apr 01 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Charles Hixson wrote:
<snip>
 Didn't you say it wrong?  Don't you want:
 void opCast (out resultType result, in  valueType value)
 {...
    result = cast(resultType)value
 
 }
 
 This would allow conversion to be specified between any pair of types.  
 It can't be included in the type spec, because then types defined 
 afterwards couldn't have any conversion defined to types defined 
 earlier.  So two arguments are needed.

I'm not sure what you mean.
 Note that because this is a cast operation, the _r form doesn't apply, 
 unless I'm overlooking something.

The _r form would be used to define conversions _to_ the type in which it is defined. However, the OP's signature doesn't really make sense for this. It would need to be something like static T opCast_r(int res);
 Also note that this is NOT a function, but rather a procedure. It 
 doesn't have a return value, it has an out parameter.  (This shouldn't 
 make a difference, as a function with one out parameter is logically 
 equivalent to a function, but the D syntax rules cause it to make an 
 effective difference.)
 
 The problem with this resolution is that the conversion becomes a 
 procedure call...syntactically a different operation, and one that 
 cannot be chained.  This would require special compiler logic.

Obviously cast(int) qwert would become something like this (function int(T t) { int i; t.opCast(i); return i; })(qwert) and then chaining would be straightforward. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 05 2005
parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stewart Gordon schrieb am Tue, 05 Apr 2005 14:23:42 +0100:
 Charles Hixson wrote:
<snip>
 Didn't you say it wrong?  Don't you want:
 void opCast (out resultType result, in  valueType value)
 {...
    result = cast(resultType)value
 
 }
 
 This would allow conversion to be specified between any pair of types.  
 It can't be included in the type spec, because then types defined 
 afterwards couldn't have any conversion defined to types defined 
 earlier.  So two arguments are needed.

I'm not sure what you mean.

Just a guess: # class A{ } # class B{ } # # void opCast(out A a, in B b){} # # void opCast(out B b, in A a){} Ofcourse the module names would have to be stripped from opCast's name. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCUpPJ3w+/yD4P9tIRAvhyAJ9CfG27o/IbHDnBki1IretbHJBltwCgvMUL cr5pLXmiuNj8KoXeTm+VNLA= =PVvg -----END PGP SIGNATURE-----
Apr 05 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Thomas Kuehne wrote:
 Stewart Gordon schrieb am Tue, 05 Apr 2005 14:23:42 +0100:
 
 Charles Hixson wrote:


 This would allow conversion to be specified between any pair of
 types. It can't be included in the type spec, because then types
 defined afterwards couldn't have any conversion defined to types
 defined earlier.  So two arguments are needed.

I'm not sure what you mean.

Just a guess: # class A{ } # class B{ } # # void opCast(out A a, in B b){} # # void opCast(out B b, in A a){}

What I actually meant is: how does putting it in the type spec not make it possible to do this kind of thing? Maybe Charles is stuck in the dark ages before forward references were invented? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 05 2005
next sibling parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stewart Gordon schrieb am Tue, 05 Apr 2005 17:20:35 +0100:
 Thomas Kuehne wrote:
 Stewart Gordon schrieb am Tue, 05 Apr 2005 14:23:42 +0100:
 
 Charles Hixson wrote:


 This would allow conversion to be specified between any pair of
 types. It can't be included in the type spec, because then types
 defined afterwards couldn't have any conversion defined to types
 defined earlier.  So two arguments are needed.

I'm not sure what you mean.

Just a guess: # class A{ } # class B{ } # # void opCast(out A a, in B b){} # # void opCast(out B b, in A a){}

What I actually meant is: how does putting it in the type spec not make it possible to do this kind of thing?

How do you declare opCast if the acutal implementation of the type is closed source? Either opCast is seperated from the type definition or opCast_receive has to be supported. In addition how do you cast from a buildin type to a user defined one? # long l; # BigInt i = cast(BigInt)l; Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCUsJF3w+/yD4P9tIRAjeIAKCTkoEf0lqMeJeRRE/ZnPVrMOzEHwCgqFsE ABVqTPU1FdGs5rQPvii1pek= =m2mJ -----END PGP SIGNATURE-----
Apr 05 2005
next sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <5bsai2-ij5.ln1 lnews.kuehne.cn>, Thomas Kuehne says...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stewart Gordon schrieb am Tue, 05 Apr 2005 17:20:35 +0100:
 Thomas Kuehne wrote:
 Stewart Gordon schrieb am Tue, 05 Apr 2005 14:23:42 +0100:
 
 Charles Hixson wrote:


 This would allow conversion to be specified between any pair of
 types. It can't be included in the type spec, because then types
 defined afterwards couldn't have any conversion defined to types
 defined earlier.  So two arguments are needed.

I'm not sure what you mean.

Just a guess: # class A{ } # class B{ } # # void opCast(out A a, in B b){} # # void opCast(out B b, in A a){}

What I actually meant is: how does putting it in the type spec not make it possible to do this kind of thing?

How do you declare opCast if the acutal implementation of the type is closed source? Either opCast is seperated from the type definition or opCast_receive has to be supported. In addition how do you cast from a buildin type to a user defined one? # long l; # BigInt i = cast(BigInt)l; Thomas

This is exactly why I brought up the alternate syntax, much earlier in this NG:
 class Foo{
 void* opCast(TypeInfo to);
 }

It covers *all* the bases at least where classes are concerned. No extra method signatures are needed, nor is the operator decoupled from the affected type. - EricAnderton at yahoo
Apr 05 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
pragma wrote:
<snip>
In addition how do you cast from a buildin type to a user defined one?
# long l;
# BigInt i = cast(BigInt)l;

Thomas

This is exactly why I brought up the alternate syntax, much earlier in this NG:
class Foo{
void* opCast(TypeInfo to);
}

It covers *all* the bases at least where classes are concerned. No extra method signatures are needed, nor is the operator decoupled from the affected type.

How is it possible to add this function to a built-in type? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 06 2005
parent pragma <pragma_member pathlink.com> writes:
In article <d30ag5$1g35$2 digitaldaemon.com>, Stewart Gordon says...
pragma wrote:
<snip>
In addition how do you cast from a buildin type to a user defined one?
# long l;
# BigInt i = cast(BigInt)l;

Thomas

This is exactly why I brought up the alternate syntax, much earlier in this NG:
class Foo{
void* opCast(TypeInfo to);
}

It covers *all* the bases at least where classes are concerned. No extra method signatures are needed, nor is the operator decoupled from the affected type.

How is it possible to add this function to a built-in type?

Ah, there's the rub. :) D has no facility for overloading any operator for scalars. I've been longing for such a facility for some time. That's why I drafted the typeinfo-block concept over on the Wiki (which is in need of some revision). It would allow for typedefs to be defined which would directly extend scalars like classes, including operator overloads. That way, such a cast operator would merely be scoped to its enclosing definition: much like with classes. I'll admit that the other way to go "void opCast(out T outVal,in U inVal)" handles discrete casting cases much more easily than "void* opCast(TypeInfo to)". My proposal for a cast operator wouldn't work as well in a global context, since it's too general. Perhaps there's room for both then? - EricAnderton at yahoo
Apr 06 2005
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Thomas Kuehne wrote:
<snip>
 How do you declare opCast if the acutal implementation of the type is 
 closed source? Either opCast is seperated from the type definition or 
 opCast_receive has to be supported.
 
 In addition how do you cast from a buildin type to a user defined one?
 # long l;
 # BigInt i = cast(BigInt)l;

Answer to both questions: by defining an opCast_r function as I gave a little up the thread. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 06 2005
prev sibling parent Charles Hixson <charleshixsn earthlink.net> writes:
Stewart Gordon wrote:
 Thomas Kuehne wrote:
 
 Stewart Gordon schrieb am Tue, 05 Apr 2005 14:23:42 +0100:

 Charles Hixson wrote:


<snip>
 This would allow conversion to be specified between any pair of
 types. It can't be included in the type spec, because then types
 defined afterwards couldn't have any conversion defined to types
 defined earlier.  So two arguments are needed.

I'm not sure what you mean.

Just a guess: # class A{ } # class B{ } # # void opCast(out A a, in B b){} # # void opCast(out B b, in A a){}

<snip> What I actually meant is: how does putting it in the type spec not make it possible to do this kind of thing? Maybe Charles is stuck in the dark ages before forward references were invented? Stewart.

functions don't have their identity dependant on the type of their receiver. (There are languages where this isn't true, but to the best of my understanding [meager], D isn't one of them.) int i; uint ui; i = itoi(5); ui = itoi(5); The same function is guaranteed to be called by both invocations of atoi. You can't even define both: int itoi(int i) { return i; } and uint itoi(int i) { return abs(i); } // presuming that abs is defined somewhere somehow but you CAN define both: void itoi (out int i1, in int i2) {...} and void itoi (out uint u, in int i) {...} so procedures act more in the way that you are asking an opcast to work. Only to use them as an opcast, you need special handling by the compiler which would understand that this procedure appeared in the code as a function. (I may be wrong about D's limitations here. [D certainly isn't my major language.] If so, I appologize to all for wasting their time. I should have checked this, but currently my computer is ... in transition, and many features aren't what they should be.)
Apr 05 2005