D - Cast operators
- Matthew Wilson (3/3) Sep 17 2003 Any chance of our getting away from the overused round braces in casts, ...
- Philippe Mori (27/30) Sep 17 2003 Me I prefer function style cast... but I think that it should be the sam...
- Daniel Yokomiso (16/50) Sep 17 2003 as
- Charles Sanders (13/76) Sep 17 2003 This gets my vote. Keep the (cast) I vote.
- Felix (8/90) Sep 17 2003 What about smthng like "variable.doCast(newType)" (standard method call)...
- Felix (3/98) Sep 17 2003 And this approach will be easier to manage in the "intellisense" (code
- Philippe Mori (26/39) Sep 18 2003 I have no problem with having other casts as template provide it is poss...
- Andrew Edwards (6/9) Sep 17 2003 and
- John Boucher (11/22) Sep 17 2003 Well, you'd still need to tell it what to cast to wouldn't you?:
- Andrew Edwards (15/18) Sep 17 2003 not necessarily!
- Philippe Mori (16/27) Sep 18 2003 Automatic casting won't works with printf since the format string
- Dario (15/21) Sep 23 2003 I would prefer something like:
- Ant (5/6) Sep 23 2003 Yes! finally something that makes sense!
- Benji Smith (5/7) Sep 23 2003 I hate this one. It looks like your doing something to a "B" object.
- Philippe Mori (6/12) Sep 23 2003 Idem for me. I'd like the second syntax... and it is far better than the
- Antti =?iso-8859-1?Q?Syk=E4ri?= (24/33) Sep 23 2003 I stared that for a moment and thought that you surely made a typo there
- Philippe Mori (40/61) Sep 23 2003 In some case like casting the result of a function,
- Sean L. Palmer (7/18) Sep 24 2003 Sure! But we would need some official way to accept a _type_ as a funct...
- Philippe Mori (35/53) Sep 24 2003 I think this would surely be a good thing to accept a type as a function
- Hauke Duden (31/41) Sep 24 2003 This introduces the possibility to mess with some assumptions we have
- Philippe Mori (55/95) Sep 24 2003 In C++, we can define our owns conversion functions... The biggest
- Ant (8/17) Sep 23 2003 you mean:
- Sean L. Palmer (11/46) Sep 24 2003 Nah, Ant's form is better. Clearer.
- Felix (2/64) Sep 24 2003
- Dario (8/12) Sep 25 2003 That wan't a typo! ;-)
- Walter (4/16) Dec 02 2003 The postfix cast does look good, but I don't see it has much advantage o...
- Matthew Wilson (6/24) Dec 02 2003 there
- Sean L. Palmer (14/23) Dec 03 2003 Because it is not immediately obvious which of cast's two parameters are...
- Matthew Wilson (4/26) Dec 03 2003 it's
- Georg Wrede (8/14) Dec 03 2003 An idea, what if we could write
- davepermen (4/7) Dec 03 2003 we just need a good template syntax, and this problem is no problem anym...
- Felix (3/28) Dec 03 2003 Me too, I vote for diff. cast function. As for me, concerning the postfi...
- Berin Loritsch (14/18) Dec 03 2003 Umm, here is a simple, but maybe radical idea... why have explicit casts...
- Antti =?iso-8859-1?Q?Syk=E4ri?= (4/29) Dec 03 2003 Looks like a function call? ;-)
- Russ Lewis (6/8) Dec 03 2003 I like the idea of postfix cast because it makes long chained
- Berin Loritsch (13/26) Dec 03 2003 Honestly, I don't like having to type cast() at all. Although I agree
- Berin Loritsch (11/24) Dec 03 2003 How about this instead:
- Russ Lewis (8/39) Dec 03 2003 I use either one-line or multi-line solutions, based on which is more
- Hauke Duden (15/30) Dec 03 2003 That might be true for some situations, but this has the potential to
- Berin Loritsch (33/67) Dec 03 2003 Not necessarily. As long as there is no ambiguity, the implicit cast sh...
- Hauke Duden (23/47) Dec 03 2003 I think there is some kind of misunderstanding.
- Berin Loritsch (11/46) Dec 03 2003 Bad code. Shouldn't do it. More often than not, upcasting from a base ...
- Hauke Duden (14/23) Dec 03 2003 That is a pretty sweeping statement you make there. Here's an example
- Berin Loritsch (21/50) Dec 04 2003 Counter example:
- Hauke Duden (23/32) Dec 04 2003 That would work too, but you cannot FORCE programmers to use interfaces
- Ant (5/13) Dec 03 2003 I like castTo better because is more explicit and
- Matthew Wilson (5/13) Dec 03 2003 over
- Ant (5/19) Dec 04 2003 You might be right but anyway you cut it
- Ant (12/24) Sep 23 2003 list[i].castTo(CA).kid.castTo(CK).funct
- Robert (48/48) Dec 07 2003 from: http://www.digitalmars.com/drn-bin/wwwnews?D/19990
Any chance of our getting away from the overused round braces in casts, and adopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.
Sep 17 2003
Any chance of our getting away from the overused round braces in casts,andadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.Me I prefer function style cast... but I think that it should be the same as for template so that anyone could write it prefered cast as it is possible in C++. I would also like to have more cast as in C++ where we can explictly tell the compiler which kind of casting we want to allows. In fact, I would even like to have more cast than in C++. Some of the cast that I think of: static_cast // as in C++ reinterpret_cast // low level bit reinterpret const_cast // as in C++ (we should add const support to D) dynamic_cast // base to derived implicit_cast // Allows if cast/conversion is implictly allowed without error (and disable any vendor specific warnings) range_cast // Ensure that the value fit in the target same_layout_cast // allowed if the layout is the same (x, y, z vs pt[3] or renamed member) enum_cast // Similar to range cast but only for enums fit_cast // fit to target range (any value lower than target min would be set to target min or -INF for floatting points,...) ... and some more for plateform dependant cast, similar type cast (int to uint) .... We should have one cast for each kind of casting that can be done... and have cast if allowed on the current plateform vs defined exactly by the language... And I'd like to be able to add my owns...
Sep 17 2003
"Philippe Mori" <philippe_mori hotmail.com> escreveu na mensagem news:bk9q8l$27ov$1 digitaldaemon.com...asAny chance of our getting away from the overused round braces in casts,andadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.Me I prefer function style cast... but I think that it should be the samefor template so that anyone could write it prefered cast as it is possible in C++. I would also like to have more cast as in C++ where we can explictly tell the compiler which kind of casting we want to allows. In fact, I wouldevenlike to have more cast than in C++. Some of the cast that I think of: static_cast // as in C++ reinterpret_cast // low level bit reinterpret const_cast // as in C++ (we should add const support to D) dynamic_cast // base to derived implicit_cast // Allows if cast/conversion is implictly allowed without error (and disable any vendor specific warnings) range_cast // Ensure that the value fit in the target same_layout_cast // allowed if the layout is the same (x, y, z vs pt[3] or renamed member) enum_cast // Similar to range cast but only for enums fit_cast // fit to target range (any value lower than target min would be set to target min or -INF for floatting points,...) ... and some more for plateform dependant cast, similar type cast (int touint).... We should have one cast for each kind of casting that can be done... and have cast if allowed on the current plateform vs defined exactly by the language... And I'd like to be able to add my owns...IMO we should just keep the simple cast (using a "cast(type, value)" syntax to reduce the parameters) and have all the other casts as templates. If we do it this way we can keep the language clean of one hundred and one new keywords and the syntax of templates will certainly improve (just imagine dozens of developers frustrated with explicit instantiantion ;). Also templates are the standard way to provide generic code (i.e. you would be able to add your owns). --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.518 / Virus Database: 316 - Release Date: 11/9/2003
Sep 17 2003
This gets my vote. Keep the (cast) I vote. One thing that does worry me, is that there are now a ton of keywords in D, I realize that there all needed, but what are everyone elses thoughts on this ? Id like to keep it to as little as possible. Charles "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message news:bkaqnn$lbt$1 digitaldaemon.com..."Philippe Mori" <philippe_mori hotmail.com> escreveu na mensagem news:bk9q8l$27ov$1 digitaldaemon.com...casts,Any chance of our getting away from the overused round braces insameandadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.Me I prefer function style cast... but I think that it should be theasinfor template so that anyone could write it prefered cast as it is possibletellC++. I would also like to have more cast as in C++ where we can explictlypt[3]the compiler which kind of casting we want to allows. In fact, I wouldevenlike to have more cast than in C++. Some of the cast that I think of: static_cast // as in C++ reinterpret_cast // low level bit reinterpret const_cast // as in C++ (we should add const support to D) dynamic_cast // base to derived implicit_cast // Allows if cast/conversion is implictly allowed without error (and disable any vendor specific warnings) range_cast // Ensure that the value fit in the target same_layout_cast // allowed if the layout is the same (x, y, z vssyntaxor renamed member) enum_cast // Similar to range cast but only for enums fit_cast // fit to target range (any value lower than target min would be set to target min or -INF for floatting points,...) ... and some more for plateform dependant cast, similar type cast (int touint).... We should have one cast for each kind of casting that can be done... and have cast if allowed on the current plateform vs defined exactly by the language... And I'd like to be able to add my owns...IMO we should just keep the simple cast (using a "cast(type, value)"to reduce the parameters) and have all the other casts as templates. If we do it this way we can keep the language clean of one hundred and one new keywords and the syntax of templates will certainly improve (just imagine dozens of developers frustrated with explicit instantiantion ;). Also templates are the standard way to provide generic code (i.e. you would be able to add your owns). --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.518 / Virus Database: 316 - Release Date: 11/9/2003
Sep 17 2003
What about smthng like "variable.doCast(newType)" (standard method call). Yes, will be more difficult for expressions, but not always: (variable1+variable2/variable4).doCast(newType) Me, one, I would preffer this to (newType) (Variable1+Variable2); It is really necessar to have an operator-based syntax? Also, other casts should be easier to add. Yes, and please drop the "_" in function names. Just an innocent idea. In article <bkav5t$rdo$1 digitaldaemon.com>, Charles Sanders says...This gets my vote. Keep the (cast) I vote. One thing that does worry me, is that there are now a ton of keywords in D, I realize that there all needed, but what are everyone elses thoughts on this ? Id like to keep it to as little as possible. Charles "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message news:bkaqnn$lbt$1 digitaldaemon.com..."Philippe Mori" <philippe_mori hotmail.com> escreveu na mensagem news:bk9q8l$27ov$1 digitaldaemon.com...casts,Any chance of our getting away from the overused round braces insameandadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.Me I prefer function style cast... but I think that it should be theasinfor template so that anyone could write it prefered cast as it is possibletellC++. I would also like to have more cast as in C++ where we can explictlypt[3]the compiler which kind of casting we want to allows. In fact, I wouldevenlike to have more cast than in C++. Some of the cast that I think of: static_cast // as in C++ reinterpret_cast // low level bit reinterpret const_cast // as in C++ (we should add const support to D) dynamic_cast // base to derived implicit_cast // Allows if cast/conversion is implictly allowed without error (and disable any vendor specific warnings) range_cast // Ensure that the value fit in the target same_layout_cast // allowed if the layout is the same (x, y, z vssyntaxor renamed member) enum_cast // Similar to range cast but only for enums fit_cast // fit to target range (any value lower than target min would be set to target min or -INF for floatting points,...) ... and some more for plateform dependant cast, similar type cast (int touint).... We should have one cast for each kind of casting that can be done... and have cast if allowed on the current plateform vs defined exactly by the language... And I'd like to be able to add my owns...IMO we should just keep the simple cast (using a "cast(type, value)"to reduce the parameters) and have all the other casts as templates. If we do it this way we can keep the language clean of one hundred and one new keywords and the syntax of templates will certainly improve (just imagine dozens of developers frustrated with explicit instantiantion ;). Also templates are the standard way to provide generic code (i.e. you would be able to add your owns). --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.518 / Virus Database: 316 - Release Date: 11/9/2003
Sep 17 2003
And this approach will be easier to manage in the "intellisense" (code completion) based editors... In article <bkbe0c$1gsc$1 digitaldaemon.com>, Felix says...What about smthng like "variable.doCast(newType)" (standard method call). Yes, will be more difficult for expressions, but not always: (variable1+variable2/variable4).doCast(newType) Me, one, I would preffer this to (newType) (Variable1+Variable2); It is really necessar to have an operator-based syntax? Also, other casts should be easier to add. Yes, and please drop the "_" in function names. Just an innocent idea. In article <bkav5t$rdo$1 digitaldaemon.com>, Charles Sanders says...This gets my vote. Keep the (cast) I vote. One thing that does worry me, is that there are now a ton of keywords in D, I realize that there all needed, but what are everyone elses thoughts on this ? Id like to keep it to as little as possible. Charles "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message news:bkaqnn$lbt$1 digitaldaemon.com..."Philippe Mori" <philippe_mori hotmail.com> escreveu na mensagem news:bk9q8l$27ov$1 digitaldaemon.com...casts,Any chance of our getting away from the overused round braces insameandadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.Me I prefer function style cast... but I think that it should be theasinfor template so that anyone could write it prefered cast as it is possibletellC++. I would also like to have more cast as in C++ where we can explictlypt[3]the compiler which kind of casting we want to allows. In fact, I wouldevenlike to have more cast than in C++. Some of the cast that I think of: static_cast // as in C++ reinterpret_cast // low level bit reinterpret const_cast // as in C++ (we should add const support to D) dynamic_cast // base to derived implicit_cast // Allows if cast/conversion is implictly allowed without error (and disable any vendor specific warnings) range_cast // Ensure that the value fit in the target same_layout_cast // allowed if the layout is the same (x, y, z vssyntaxor renamed member) enum_cast // Similar to range cast but only for enums fit_cast // fit to target range (any value lower than target min would be set to target min or -INF for floatting points,...) ... and some more for plateform dependant cast, similar type cast (int touint).... We should have one cast for each kind of casting that can be done... and have cast if allowed on the current plateform vs defined exactly by the language... And I'd like to be able to add my owns...IMO we should just keep the simple cast (using a "cast(type, value)"to reduce the parameters) and have all the other casts as templates. If we do it this way we can keep the language clean of one hundred and one new keywords and the syntax of templates will certainly improve (just imagine dozens of developers frustrated with explicit instantiantion ;). Also templates are the standard way to provide generic code (i.e. you would be able to add your owns). --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.518 / Virus Database: 316 - Release Date: 11/9/2003
Sep 17 2003
syntaxWe should have one cast for each kind of casting that can be done... and have cast if allowed on the current plateform vs defined exactly by the language... And I'd like to be able to add my owns...IMO we should just keep the simple cast (using a "cast(type, value)"to reduce the parameters) and have all the other casts as templates. If we do it this way we can keep the language clean of one hundred and one new keywords and the syntax of templates will certainly improve (just imagine dozens of developers frustrated with explicit instantiantion ;). Also templates are the standard way to provide generic code (i.e. you would be able to add your owns).I have no problem with having other casts as template provide it is possible to implement the desired cast... Often the compiler knows the information while the programmer might or might not be able to knows it... I think that in D we have more informations on type (like enum range) so we could more easily define some of our cast... but some other might not be easily possible (is it possible to implement static_cast or dynamic_cast using only templates and existing cast by having specialisation for allowed and prohibited cases and ensuring that prohibited cases does not compile? So a minimum is needed to be able to do more... In C++, for example it is hard to detect if a type is a class, an enum, a member pointer, a POD, or to know if a class is abstract... without some support from the compiler. In D, for example, we might want to know if a type is a typedef of another one. Also we might want to be able to check layout compatibity of 2 types: struct S { double x; double y; double z }; alias double [3] Coord; S s; Coord c = layout_cast(s); // I want to compiler to validate that the layout is compatible (and as you can see, specifying the target might not be necessary (but implicit instanciation would be required). In fact, implicit instanciation is required for any user type as we do not want to have to specify both the source and target type... k = my_cast(TargetType, originalValue)
Sep 18 2003
"Matthew Wilson" <dmd synesis.com.au> wrote in message news:bk9ln8$21k9$1 digitaldaemon.com...Any chance of our getting away from the overused round braces in casts,andadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.How about a cast property? double d = 3.14159; printf("%d", d.cast); // outputs 3
Sep 17 2003
In article <bkaal5$2vat$1 digitaldaemon.com>, Andrew Edwards says..."Matthew Wilson" <dmd synesis.com.au> wrote in message news:bk9ln8$21k9$1 digitaldaemon.com...Well, you'd still need to tell it what to cast to wouldn't you?: d.cast(int) so what's the difference? And it would be better to have: d.toString(formatstring) d.toInt d.toUInt etc. and all the baggage that follows. John Boucher The King had Humpty pushed.Any chance of our getting away from the overused round braces in casts,andadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.How about a cast property? double d = 3.14159; printf("%d", d.cast); // outputs 3
Sep 17 2003
"John Boucher" <John_member pathlink.com> wrote in message news:bkacc2$ar$1 digitaldaemon.com...Well, you'd still need to tell it what to cast to wouldn't you?: d.cast(int) so what's the difference?not necessarily! format specifiers provides the format of the intended input (in this case int). Upon seeing the cast property, printf should automatically convert d.cast to the expected input. likewise, char [] dstr; char[30] cstr = "Is this even possible?"; dstr = cstr; // error dstr = cstr.cast; // ok the compiler already knows what's expected and will automatally bark at improperly typed inputs or rvalues. Upon seeing cstr.cast however, it should treat cstr as if it were a dynamic string. Andrew
Sep 17 2003
format specifiers provides the format of the intended input (in this case int). Upon seeing the cast property, printf should automatically convert d.cast to the expected input.Automatic casting won't works with printf since the format string may not be known to the compiler... and the compiler assumes that the type is correct!likewise, char [] dstr; char[30] cstr = "Is this even possible?"; dstr = cstr; // error dstr = cstr.cast; // ok the compiler already knows what's expected and will automatally bark at improperly typed inputs or rvalues. Upon seeing cstr.cast however, itshouldtreat cstr as if it were a dynamic string.For conversion, I do like the idea... And it would allows conversion that are normally explicit to be done implictly... So something like that should even be possible: int i; bool b = (1 + i).cast; double d; int j = (3.453 * d).cast; int k = d.cast; uint m; if (m == j.cast) // convert j to unsigned for comparison { }
Sep 18 2003
I would prefer something like: . class A {} . class B:A {void func(){}} . A b = new B; . B.cast(b).func(); Rather than having to write: . (cast(B) b).func(); Isn't the former easier to read? Consider more complex code like the following: . ((CK) ((CA) list[i]).kid).func(); That becomes: . CK.cast(CA.cast(list[i]).kid).func(); Andrew Edwards:How about a cast property? double d = 3.14159; printf("%d", d.cast); // outputs 3Matthew Wilson:Any chance of our getting away from the overused round braces in casts,andadopt something less ambiguous, along the lines of the C++ casts? It seems like a retrograde step.
Sep 23 2003
In article <bkq9th$17fn$1 digitaldaemon.com>, Dario says.... B.cast(b).func();Yes! finally something that makes sense! We have been waiting for this for decades. ? b.castTo(B).func() ? Ant
Sep 23 2003
I hate this one. It looks like your doing something to a "B" object. But you aren't. You're doing something to a "b" object. This syntax is very deceptive.. B.cast(b).func();b.castTo(B).func()This one, I like. A lot. --Benji
Sep 23 2003
Idem for me. I'd like the second syntax... and it is far better than the suggested on since it does not require too much parenthesis that we must look carefully... In fact, we just have to look inside the () after the predefined castTo method to know what we are casting... and in complex expression, this is surely easier to read than prefix casting.I hate this one. It looks like your doing something to a "B" object. But you aren't. You're doing something to a "b" object. This syntax is very deceptive.. B.cast(b).func();b.castTo(B).func()This one, I like. A lot.
Sep 23 2003
In article <bkq9th$17fn$1 digitaldaemon.com>, Dario says...I stared that for a moment and thought that you surely made a typo there and actually meant to write: b.cast(B).func(); Which kind of makes sense. (similarly as Ant suggested:) In article <bkqaoi$18hk$1 digitaldaemon.com>, Ant wrote:I would prefer something like: class A {} class B:A {void func(){}} A b = new B; B.cast(b).func();Yes! finally something that makes sense! We have been waiting for this for decades. ? b.castTo(B).func() ?How about: cast(B, b).func() cast(B: b).func(); cast(B; b).func(); // Syntax a bit similar to foreach(); emphasizes that // cast is not just any function or even cast(b, B).func(); cast(b to B).func(); cast(b as B).func(); cast(b -> B).func(); // too bad -> already has a meaning cast(b: B).func(); cast(B b).func(); cast(B) b.func(); // Java style, huh? (cast(B) b).func(); // What we have now. Cluttered. But for what it's worth, D isn't trying to be Java, so well-written programs contain very few casts anyway and those that remain deserve to stand out. Right? -Antti
Sep 23 2003
In some case like casting the result of a function, I like better f().castTo(double) than cast(double, f()) I'm not sure about the last suggestion but I think that even if it would be possible to uses a syntax without separator it is better to have a separtator (and in my opinion it should be ,) since if both the type and the expression are complex, it is easier to see where one ends and the other start. Also, I like using , as the separator as this is consistent with template...Yes! finally something that makes sense! We have been waiting for this for decades. ? b.castTo(B).func() ?How about: cast(B, b).func() cast(B: b).func(); cast(B; b).func(); // Syntax a bit similar to foreach(); emphasizes that // cast is not just any function or even cast(b, B).func(); cast(b to B).func(); cast(b as B).func(); cast(b -> B).func(); // too bad -> already has a meaning cast(b: B).func(); cast(B b).func();cast(B) b.func(); // Java style, huh?With this syntac as in C++, it is hard to knows where the cast end if the expression is a bit complex and we need extra (). For example, if we want to cast function result...(cast(B) b).func(); // What we have now. Cluttered. But for what it's worth, D isn't trying to be Java, so well-written programs contain very few casts anyway and those that remain deserve to stand out. Right?Cast should be easy to spot and should be easy to understand without needing to count ()... Also the selected syntax should be compatible with templates and should be extendable to user defined cast... If the object.cast syntax is used, then we might want to be able to define our cast to a given type : class C { operator castTo(D) { return ... } operator castTo(E) { return ... } template (T) operator castTo(T) { return member.castTo(T); } } OTHO, if we uses a syntax like cast(B, b), we should be able to define our owns casting functions that works the same way: // Cast and if not possible returns default (just an example) template (T, U) T cast_or_default(U u) { try { return cast(T) u; } catch(...) { return T.init; } }
Sep 23 2003
"Philippe Mori" <philippe_mori hotmail.com> wrote in message news:bkqfd3$1fkc$1 digitaldaemon.com...If the object.cast syntax is used, then we might want to be able to define our cast to a given type : class C { operator castTo(D) { return ... } operator castTo(E) { return ... } template (T) operator castTo(T) { return member.castTo(T); } }Sure! But we would need some official way to accept a _type_ as a function parameter!OTHO, if we uses a syntax like cast(B, b), we should be able to define our owns casting functions that works the same way:I really don't like this syntax; it's confusing which comes first, the type or the rvalue. Sean
Sep 24 2003
functionIf the object.cast syntax is used, then we might want to be able to define our cast to a given type : class C { operator castTo(D) { return ... } operator castTo(E) { return ... } template (T) operator castTo(T) { return member.castTo(T); } }Sure! But we would need some official way to accept a _type_ as aparameter!I think this would surely be a good thing to accept a type as a function parameter and it would be interesting for metaprogramming. Here a simple example for a factory: class Base { } class Der1 : Base { } class Der2 : Base { } class Der3 : Base { } Base CreateObject(type t, int arg1, int arg2) { return new t(arg1, arg2); } Base a = CreateObject(Der1, 5, 3); Base b = CreateObject(typeof(a), 6, 4); But for casting purpose this is not strictly necessary since in C++ we have conversion operator but we do not have type function parameters: class C { // C++ sample public: // the typename give the operator name. // for complex type a typedef might be required. operator double() const { return 23.4; } // template is even supported... // Here we allows any supported conversion from a member template <typename T> operator T { return member; } M member; }; So IMHO, we should choose the syntax mainly according to the following rules: - easy to uses and to read. - consistent with the language (template, predefine members syntax,...)typeOTHO, if we uses a syntax like cast(B, b), we should be able to define our owns casting functions that works the same way:I really don't like this syntax; it's confusing which comes first, theor the rvalue.I see... and with Ant sample, I see why this syntax is not elegant for complex expression in which there are multiples casts...Sean
Sep 24 2003
Philippe Mori wrote:If the object.cast syntax is used, then we might want to be able to define our cast to a given type : class C { operator castTo(D) { return ... } operator castTo(E) { return ... } template (T) operator castTo(T) { return member.castTo(T); } }This introduces the possibility to mess with some assumptions we have about casting. For example, it should be possible to cast the object that is returned by castTo back to the original type. This would have to be explicitly supported by the programmer the returned object. I'm not sure wether this is necessarily such a bad thing, though. After all, operator overloads can always cause stuff like this. On the other hand, this seems like it could get complicated pretty quickly. Imagine the following case: class A { B b; C c; operator castTo(B) { return b; } operator castTo(C) { return c; } }; A a; //This works a.castTo(C); //And this works; a.castTo(B); //Then this should work as well a.castTo(B).castTo(C) So B would not only have to know how it can be casted back to A, but it should also know how to cast to the "sister" interface C. Note that this concept is pretty similar to the way Microsoft's COM and the QueryInterface method works. MS uses this quite a bit to implement interfaces using aggregated objects. Does anyone have sufficient experience with this to offer an opinion on wether it is worth the trouble? Hauke
Sep 24 2003
In C++, we can define our owns conversion functions... The biggest problem we have in C++ are: - unintended conversion (a conversion that is not always desirable), like the conversion from some string classes to const char * or some automatic pointers classes to the pointer. - ambiguities when a class allows conversion to a class that accept original type in one of its constructor: class A; class B { public: operator A() const; }; class A { public: A (B const &b) { } };If the object.cast syntax is used, then we might want to be able to define our cast to a given type : class C { operator castTo(D) { return ... } operator castTo(E) { return ... } template (T) operator castTo(T) { return member.castTo(T); } }This introduces the possibility to mess with some assumptions we have about casting.For example, it should be possible to cast the object that is returned by castTo back to the original type. This would have to be explicitly supported by the programmer the returned object.Enven in the language not all casts allows to returns to the original exactly: double d = 1.2; int i = cast(int) d; double d2 = cast(double) i; d will be different than d2 (but in that case, the cast is allowed).I'm not sure wether this is necessarily such a bad thing, though. After all, operator overloads can always cause stuff like this. On the other hand, this seems like it could get complicated pretty quickly. Imagine the following case: class A { B b; C c; operator castTo(B) { return b; } operator castTo(C) { return c; } }; A a; //This works a.castTo(C); //And this works; a.castTo(B); //Then this should work as well a.castTo(B).castTo(C) So B would not only have to know how it can be casted back to A, but it should also know how to cast to the "sister" interface C. Note that this concept is pretty similar to the way Microsoft's COM and the QueryInterface method works. MS uses this quite a bit to implement interfaces using aggregated objects. Does anyone have sufficient experience with this to offer an opinion on wether it is worth thetrouble? For COM stuff, we need to be able to delegate to the outer object. That is the subobjects b and c need to be able to get the this pointer of the A object that contains them. IMO, the cleanest way to handled that would be to support local classes that have access to the outer class. In such a case, COM compatible casting would be easy to implement provide that cast operator have priority over predefined cast (to ensure that casting to IUnknown or I2 in the example below will return the proper interface). Also for COM programming, with need 2 casting operators: One that do the casting for a given object and one that forward casting to the outer object (otherwise, we would have infinite loops or case where the identity won't be respected (i.e. for I2 we always want to returns either A or C object - not sometime ones and other times the other- and that without depending on the source of the cast). class A : I1, I2 { local class B : I2 { template (T) operator castTo(T) { return outer.castTo(T); } } b; local class C : I3 { template (T) operator castTo(T) { return outer.castTo(T); } } c; operator castTo(I2) { return b.internal_castTo(I2) } operator castTo(I3) { return c.internal_castTo(I3) } } So to implement COM interface casting, which might be great for COM programming, I think we need some extra casting operators. In essence, we need an operator that is called by QueryInterface for each subobject. That operator will then forward to the outer object which will the uses our internal casting. Also we need blind query... but that we be done with a template and verifying the result of the cast....Hauke
Sep 24 2003
In article <slrnbn1eo0.dbp.jsykari pulu.hut.fi>, Antti =?iso-8859-1?Q?Syk=E4ri?= says...(similarly as Ant suggested:) In article <bkqaoi$18hk$1 digitaldaemon.com>, Ant wrote:you mean: cast(cast(list[i], B).kid), CK).func() nahhh... same old thing... list[i].castTo(CA).kid.castTo(CK).func() is still better! AntYes! finally something that makes sense! We have been waiting for this for decades. ? b.castTo(B).func() ?How about: cast(B, b).func()
Sep 23 2003
Nah, Ant's form is better. Clearer. b.cast(B).func(); Works even if B is a complicated typespec; easy to parse; easy to read. Self-documenting. myObjectPtr[n].cast(myFoo*[])[i]->DoFooStuff("foo baby".cast(wchar[])); This is good. I like it better than the cast D has now. DMD still hasn't gotten rid of C's typecast! I thought the D spec doesn't support C typecasts? Sean "Antti Sykäri" <jsykari gamma.hut.fi> wrote in message news:slrnbn1eo0.dbp.jsykari pulu.hut.fi...In article <bkq9th$17fn$1 digitaldaemon.com>, Dario says...I stared that for a moment and thought that you surely made a typo there and actually meant to write: b.cast(B).func(); Which kind of makes sense. (similarly as Ant suggested:) In article <bkqaoi$18hk$1 digitaldaemon.com>, Ant wrote:I would prefer something like: class A {} class B:A {void func(){}} A b = new B; B.cast(b).func();Yes! finally something that makes sense! We have been waiting for this for decades. ? b.castTo(B).func() ?How about: cast(B, b).func() cast(B: b).func(); cast(B; b).func(); // Syntax a bit similar to foreach(); emphasizes that // cast is not just any function or even cast(b, B).func(); cast(b to B).func(); cast(b as B).func(); cast(b -> B).func(); // too bad -> already has a meaning cast(b: B).func(); cast(B b).func(); cast(B) b.func(); // Java style, huh? (cast(B) b).func(); // What we have now. Cluttered. But for what it's worth, D isn't trying to be Java, so well-written programs contain very few casts anyway and those that remain deserve to stand out. Right? -Antti
Sep 24 2003
I like this kind of cast. I. e. variable.doCast(newType) etc... In article <bkrjpa$vg$1 digitaldaemon.com>, Sean L. Palmer says...Nah, Ant's form is better. Clearer. b.cast(B).func(); Works even if B is a complicated typespec; easy to parse; easy to read. Self-documenting. myObjectPtr[n].cast(myFoo*[])[i]->DoFooStuff("foo baby".cast(wchar[])); This is good. I like it better than the cast D has now. DMD still hasn't gotten rid of C's typecast! I thought the D spec doesn't support C typecasts? Sean "Antti Sykäri" <jsykari gamma.hut.fi> wrote in message news:slrnbn1eo0.dbp.jsykari pulu.hut.fi...In article <bkq9th$17fn$1 digitaldaemon.com>, Dario says...I stared that for a moment and thought that you surely made a typo there and actually meant to write: b.cast(B).func(); Which kind of makes sense. (similarly as Ant suggested:) In article <bkqaoi$18hk$1 digitaldaemon.com>, Ant wrote:I would prefer something like: class A {} class B:A {void func(){}} A b = new B; B.cast(b).func();Yes! finally something that makes sense! We have been waiting for this for decades. ? b.castTo(B).func() ?How about: cast(B, b).func() cast(B: b).func(); cast(B; b).func(); // Syntax a bit similar to foreach(); emphasizes that // cast is not just any function or even cast(b, B).func(); cast(b to B).func(); cast(b as B).func(); cast(b -> B).func(); // too bad -> already has a meaning cast(b: B).func(); cast(B b).func(); cast(B) b.func(); // Java style, huh? (cast(B) b).func(); // What we have now. Cluttered. But for what it's worth, D isn't trying to be Java, so well-written programs contain very few casts anyway and those that remain deserve to stand out. Right? -Antti
Sep 24 2003
Antti Sykäri:I stared that for a moment and thought that you surely made a typo there and actually meant to write: b.cast(B).func(); Which kind of makes sense.That wan't a typo! ;-) I thought of that because Ant's version is complicated to parse (function don't get types as parameters). Anyway I am convinced that Ant's version is more intuitive too. I noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?
Sep 25 2003
"Dario" <supdar yahoo.com> wrote in message news:bkvsqs$26e9$1 digitaldaemon.com...Antti Sykäri:The postfix cast does look good, but I don't see it has much advantage over the prefix cast.I stared that for a moment and thought that you surely made a typo there and actually meant to write: b.cast(B).func(); Which kind of makes sense.That wan't a typo! ;-) I thought of that because Ant's version is complicated to parse (function don't get types as parameters). Anyway I am convinced that Ant's version is more intuitive too. I noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?
Dec 02 2003
"Walter" <walter digitalmars.com> wrote in message news:bqjfni$nc0$1 digitaldaemon.com..."Dario" <supdar yahoo.com> wrote in message news:bkvsqs$26e9$1 digitaldaemon.com...thereAntti Sykäri:I stared that for a moment and thought that you surely made a typooverThe postfix cast does look good, but I don't see it has much advantageand actually meant to write: b.cast(B).func(); Which kind of makes sense.That wan't a typo! ;-) I thought of that because Ant's version is complicated to parse (function don't get types as parameters). Anyway I am convinced that Ant's version is more intuitive too. I noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?the prefix cast.Looks too much like a function call to me. What's wrong with cast(B, b) ? I agree that the prefix cast must die.
Dec 02 2003
"Matthew Wilson" <matthew.hat stlsoft.dot.org> wrote in message news:bqjrg3$19kg$1 digitaldaemon.com...Because it is not immediately obvious which of cast's two parameters are the thing to be casted, and which is the type to cast to. b.cast(B) is much clearer in this regard, which is why everybody was promoting it back then. Apparently Walter is just getting to that discussion. ;) B.cast(b) might work. Either way, it might need to have some extra parenthesis, like this: (new b).cast(B) (B*).cast(b); I wish a good cast syntax would be chosen, but picking one is not easy, it's all bad. SeanoverI noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?The postfix cast does look good, but I don't see it has much advantagethe prefix cast.Looks too much like a function call to me. What's wrong with cast(B, b) ? I agree that the prefix cast must die.
Dec 03 2003
?overI noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?The postfix cast does look good, but I don't see it has much advantagethe prefix cast.Looks too much like a function call to me. What's wrong with cast(B, b)theI agree that the prefix cast must die.Because it is not immediately obvious which of cast's two parameters arething to be casted, and which is the type to cast to. b.cast(B) is much clearer in this regard, which is why everybody was promoting it back then. Apparently Walter is just getting to that discussion. ;) B.cast(b) might work. Either way, it might need to have some extra parenthesis, like this: (new b).cast(B) (B*).cast(b); I wish a good cast syntax would be chosen, but picking one is not easy,it'sall bad.cast<B>(b) ??
Dec 03 2003
a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.fBar myBar = a.b; Foo myFoo = myBar.c.d; myFoo.e.f;An idea, what if we could write mything = cast(foo)g.cast(bar)h.i.j.cast(baz)k; Then the top example above, if I've understood it correctly, becomes a.cast(Foo)b.c.cast(Bar)d.e.f If we have to do a hairy mix of casts and methods it would still be legible: a.cast(I)b.factMethod(cast(J)c).method(cast(K)d,cast(L)e)
Dec 03 2003
I wish a good cast syntax would be chosen, but picking one is not easy, it's all bad. Seanwe just need a good template syntax, and this problem is no problem anymore.. just as static_cast, dynamic_cast, and all behave simply as templated functions in C++. (and that way you could introduce new casts... like com_cast, or any_cast, or lexical_cast..)
Dec 03 2003
Me too, I vote for diff. cast function. As for me, concerning the postfixed cast, I simply think that a.castTo(B) is best of all... In article <bqkcal$2365$1 digitaldaemon.com>, Sean L. Palmer says..."Matthew Wilson" <matthew.hat stlsoft.dot.org> wrote in message news:bqjrg3$19kg$1 digitaldaemon.com...Because it is not immediately obvious which of cast's two parameters are the thing to be casted, and which is the type to cast to. b.cast(B) is much clearer in this regard, which is why everybody was promoting it back then. Apparently Walter is just getting to that discussion. ;) B.cast(b) might work. Either way, it might need to have some extra parenthesis, like this: (new b).cast(B) (B*).cast(b); I wish a good cast syntax would be chosen, but picking one is not easy, it's all bad. SeanoverI noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?The postfix cast does look good, but I don't see it has much advantagethe prefix cast.Looks too much like a function call to me. What's wrong with cast(B, b) ? I agree that the prefix cast must die.
Dec 03 2003
Matthew Wilson wrote:Looks too much like a function call to me. What's wrong with cast(B, b) ? I agree that the prefix cast must die.Umm, here is a simple, but maybe radical idea... why have explicit casts at all? For example, what is wrong with this? CrisisManager crisis = serviceLocater.lookup(CrisisManager.ROLE); SubjectManager subject = serviceLocator.lookup(SubjectManager.ROLE); In both cases, it is perfectly clear what end type is desired. The cast from an object to the end type is all that is needed--which the compiler can take care of. For those times where there may be ambiguity, then we might have to work something out. Either always force the use of a holder variable for the cast to work, or use an "as" keyword like this: printf("Common string embedding %s", myCrisis.getTitle() as char*); That way you avoid unecessary prefix casting or postfix casting looking like a method call.
Dec 03 2003
In article <bqjrg3$19kg$1 digitaldaemon.com>, Matthew Wilson wrote:"Walter" <walter digitalmars.com> wrote in message news:bqjfni$nc0$1 digitaldaemon.com...Looks like a function call? ;-) But seriously, it does! -Antti"Dario" <supdar yahoo.com> wrote in message news:bkvsqs$26e9$1 digitaldaemon.com...thereAntti Sykäri:I stared that for a moment and thought that you surely made a typoLooks too much like a function call to me. What's wrong with cast(B, b) ?The postfix cast does look good, but I don't see it has much advantage over the prefix cast.and actually meant to write: b.cast(B).func(); Which kind of makes sense.That wan't a typo! ;-) I thought of that because Ant's version is complicated to parse (function don't get types as parameters). Anyway I am convinced that Ant's version is more intuitive too. I noticed that there are no comments from Walter... Walter, what do you think? You aren't going to keep the prefix cast, are you?
Dec 03 2003
Walter wrote:The postfix cast does look good, but I don't see it has much advantage over the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.f
Dec 03 2003
Russ Lewis wrote:Walter wrote:Honestly, I don't like having to type cast() at all. Although I agree that the example you had would look equally ugly in Java code: ((Bar)((Foo)a).b).c.d.e.f However, such a construct is not common IMO. At most there would be only one cast needed: ((Foo)mycollection.get("Foo")).doSomething(); And IMO, it would be even better to do something like this: Foo myfoo = mycollection.get("Foo"); myfoo.doSomething(); It is more clear that is what is going on, as opposed to placing the two method calls on the same line--in such a way that would fool sloc counters....The postfix cast does look good, but I don't see it has much advantage over the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.f
Dec 03 2003
Russ Lewis wrote:Walter wrote:How about this instead: Bar myBar = a.b; Foo myFoo = myBar.c.d; myFoo.e.f; It forces you to break up the expression into something less confusing and ends up being easier to read. Of course I would prefer to use "as" instead of "cast" if we had to clarify things. a.b.as(Foo).c.b.as(Bar).e.f; I just have trouble envisioning this need....The postfix cast does look good, but I don't see it has much advantage over the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.f
Dec 03 2003
Berin Loritsch wrote:Russ Lewis wrote:I use either one-line or multi-line solutions, based on which is more readable. In some scenarios, one is better; in others, the other. However, IMHO, prefix cast almost *forces* you to use multiple lines. That means that, sometimes, the code is less readable than it would have been if the language had been more flexible.Walter wrote:How about this instead: Bar myBar = a.b; Foo myFoo = myBar.c.d; myFoo.e.f;The postfix cast does look good, but I don't see it has much advantage over the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.fIt forces you to break up the expression into something less confusing and ends up being easier to read. Of course I would prefer to use "as" instead of "cast" if we had to clarify things. a.b.as(Foo).c.b.as(Bar).e.f; I just have trouble envisioning this need....I have run across it more than once. Two casts is rare, but having one cast, followed by some member accesses or method calls, is not unusual.
Dec 03 2003
Berin Loritsch wrote:That might be true for some situations, but this has the potential to get annoying in others. For example, you cannot take the return value of one function, cast it and directly pass it into another. Having to use temporaries all the time can be a bad thing. And it can also make code less readable by adding lots of unnecessary lines of code and locals that do not really serve a purpose. Also, I suspect (though I'm not sure) that this could make optimizing (particularly inlining) harder for the compiler. At the very least it will increase the compile time, because there are more local vars to consider. Also, such an implicit casting would water down D's strong type checking, which is a Bad Thing, IMHO. The postfix cast gets my vote! HaukeI like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.fHow about this instead: Bar myBar = a.b; Foo myFoo = myBar.c.d; myFoo.e.f; It forces you to break up the expression into something less confusing and ends up being easier to read.
Dec 03 2003
Hauke Duden wrote:Berin Loritsch wrote:Not necessarily. As long as there is no ambiguity, the implicit cast should continue to work: interface Bar {} int foo(Bar baz) { return 1; } class SubClass : Bar {} // .... in client code later on foo( new SubClass() ); // or foo( getInstance() ); // returning SubClass or other impl of BarThat might be true for some situations, but this has the potential to get annoying in others. For example, you cannot take the return value of one function, cast it and directly pass it into another. Having to use temporaries all the time can be a bad thing. And it can also make code less readable by adding lots of unnecessary lines of code and locals that do not really serve a purpose.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.fHow about this instead: Bar myBar = a.b; Foo myFoo = myBar.c.d; myFoo.e.f; It forces you to break up the expression into something less confusing and ends up being easier to read.Also, I suspect (though I'm not sure) that this could make optimizing (particularly inlining) harder for the compiler. At the very least it will increase the compile time, because there are more local vars to consider.If that is the case, the compiler is not very good.Also, such an implicit casting would water down D's strong type checking, which is a Bad Thing, IMHO. The postfix cast gets my vote!I don't think so. We are not talking about operator overloading here which waters it down for real. What we are talking about is leveraging the strong typing so that you can never *upcast*. One danger in allowing upcasts (i.e. casting to an interface/type that is higher in the heirarchy) is that you are no longer working with those types. This is the source of many ClassCastExceptions in Java. Another issue has to do with hijacking responsibility. For instance, if I have a component that I give a lookup service to, I want to be able to ensure no other component can hijack that lookup service. I have some Java code that demonstrates that issue--which can easily be thwarted with proxies. The only upcast that should ever work is one from the generic object type to an Interface. Once there is a definite type, no more upcasting. Then again, this might fall under the half-baked idea column. This comes from my loathing to type the cast all the time when my intention is only to use the interface as is. I would be more than willing to use generics, but there is no way to use generics when the return type is different depending on the lookup key.
Dec 03 2003
Berin Loritsch wrote:Not necessarily. As long as there is no ambiguity, the implicit cast should continue to work: interface Bar {} int foo(Bar baz) { return 1; } class SubClass : Bar {} // .... in client code later on foo( new SubClass() ); // or foo( getInstance() ); // returning SubClass or other impl of BarI think there is some kind of misunderstanding. If getInstance() returns a sub class of Bar, then there will be no cast necessary, because the returned object already is of the correct type.What we are talking about is leveraging the strong typing so that you can never *upcast*.Ah. I think I understand what you want. You just want to remove casting altogether, thus only allowing what you call "implicit casts", i.e. casts to a base type? Wouldn't work. For example, sometimes you just have to pass a sub class thorugh a program component that only knows the base class and cast it back up to the original type afterwards. Btw, what *I* thought you meant is to use temporary variables to perform a real cast. I.e. allow assigning any type to a local variable when that variable is constructed: Bar getBar(); void setFoo(Foo foo); Foo foo=getBar(); but not setFoo(getBar()); for unrelated types Foo and Bar. THAT would water down D's type system!The only upcast that should ever work is one from the generic object type to an Interface. Once there is a definite type, no more upcasting.That would just make casting harder, since you'd first have to cast down to Object and then back up to the class you want. Hauke
Dec 03 2003
Hauke Duden wrote:Berin Loritsch wrote:Bad code. Shouldn't do it. More often than not, upcasting from a base type other than the generic "object" is a poor substitute for what you really want. That's what interfaces are for. You specify your contracts in the interface, and pass your object so that the code uses the interface AND NOTHING ELSE.What we are talking about is leveraging the strong typing so that you can never *upcast*.Ah. I think I understand what you want. You just want to remove casting altogether, thus only allowing what you call "implicit casts", i.e. casts to a base type? Wouldn't work. For example, sometimes you just have to pass a sub class thorugh a program component that only knows the base class and cast it back up to the original type afterwards.Btw, what *I* thought you meant is to use temporary variables to perform a real cast. I.e. allow assigning any type to a local variable when that variable is constructed: Bar getBar(); void setFoo(Foo foo); Foo foo=getBar(); but not setFoo(getBar()); for unrelated types Foo and Bar. THAT would water down D's type system!Please, no.That is the point. Some things like collections *have* to use Object, so at that time you upcast to the interface you want. Notice, that I limited the upcast from object to interfaces? Granted this would nicely fit the way I work--but not everyone in the world.The only upcast that should ever work is one from the generic object type to an Interface. Once there is a definite type, no more upcasting.That would just make casting harder, since you'd first have to cast down to Object and then back up to the class you want.
Dec 03 2003
Berin Loritsch wrote:That is a pretty sweeping statement you make there. Here's an example against that: Consider an image manupulation algorithm that takes quite a while. It takes a bunch of objects of type Bitmap and works on them. However, YOUR bitmaps are of the type BitmapWithName, which is derived from Bitmap. The algorithm calls a progress function regularly, in which you update your GUI to reflect the progress. The current bitmap the algorithm works on is passed to that function, as a Bitmap reference. Since you want to display the name of the current bitmap and you know that all objects you feed the algorithm are your own BitmapWithName objects, you have to cast the object you get up to that class, in order to retrieve its name. Presto: an upcast from a class other than Object. HaukeWouldn't work. For example, sometimes you just have to pass a sub class thorugh a program component that only knows the base class and cast it back up to the original type afterwards.Bad code. Shouldn't do it. More often than not, upcasting from a base type other than the generic "object" is a poor substitute for what you really want.
Dec 03 2003
Hauke Duden wrote:Berin Loritsch wrote:;P You noticed?That is a pretty sweeping statement you make there. Here's an example against that:Wouldn't work. For example, sometimes you just have to pass a sub class thorugh a program component that only knows the base class and cast it back up to the original type afterwards.Bad code. Shouldn't do it. More often than not, upcasting from a base type other than the generic "object" is a poor substitute for what you really want.Consider an image manupulation algorithm that takes quite a while. It takes a bunch of objects of type Bitmap and works on them. However, YOUR bitmaps are of the type BitmapWithName, which is derived from Bitmap. The algorithm calls a progress function regularly, in which you update your GUI to reflect the progress. The current bitmap the algorithm works on is passed to that function, as a Bitmap reference. Since you want to display the name of the current bitmap and you know that all objects you feed the algorithm are your own BitmapWithName objects, you have to cast the object you get up to that class, in order to retrieve its name. Presto: an upcast from a class other than Object.Counter example: You know that somethimes there will be objects that must be namable, so you create an interface to represent that concern called "Namable" which essentially consists of a getName() method. Your new BitmapWithName object implements the Bitmap and Namable interfaces. The Progress function performs something like this: char[] name = ""; if ( progressiveObject instanceof Nameable ) { Nameable obj = progressiveObject; name = obj.getName(); } At least that is what you do in Java. If you make your contract directly with an Object, your code is bound to that object. If that object is horribly written and is cast aside later on your code will break in many unexpected ways. However if you make a contract with an interface, ANY object that implements that interface can be used. In fact your functions become more flexible and reusable because the progress function no longer expects to deal with Bitmap objects, but anything that can be namable.
Dec 04 2003
Berin Loritsch wrote:That would work too, but you cannot FORCE programmers to use interfaces for everything. In particular, if you just need a quick prototype (for example, for a demo that needs to be done yesterday) you'd probably want the option to just declare the functionality you need directly in the object class, without having to define additional interfaces. Also, right now there is a serious limitation to D's interfaces that pretty much prevents them from being used in that way. I always wanted to write an longer post about this issue, but never got around to it. The main problem is that if a class implements an interface A and a derived class wants to implement a sub-interface "B" of A, then you have to re-implement all the functions of A again (probably with stubs that call the base class). This is a serious issue if you build an interface hierarchy and want to reuse an existing implementation of a base-interface as a basis for an implementation of a more specific interface (which you often want!). You end up writing dozens of stub-methods that do nothing except calling the base class implementation, for each and every class and every interface it implements. I'll try to write the post on that topic tonight, with a better explanation of what I mean. This issue is actually pretty important to me, even critical for my decision of whether I'll ever switch to D. So I want to make sure that my point is understandable. HaukePresto: an upcast from a class other than Object.Counter example: You know that somethimes there will be objects that must be namable, so you create an interface to represent that concern called "Namable" which essentially consists of a getName() method. Your new BitmapWithName object implements the Bitmap and Namable interfaces.
Dec 04 2003
In article <bql580$4ki$1 digitaldaemon.com>, Russ Lewis says...Walter wrote:I like castTo better because is more explicit and avoids confusion for someone used to older languages. a.b.castTo(Foo).c.d.castTo(Bar).e.f AntThe postfix cast does look good, but I don't see it has much advantage over the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.f
Dec 03 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:bql580$4ki$1 digitaldaemon.com...Walter wrote:overThe postfix cast does look good, but I don't see it has much advantageHmmm. There's some mileage in the C++ philosophy of not facilitating the ease-of-expression; maybe casts should be nasty to type?the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.f
Dec 03 2003
In article <bqmiig$2901$1 digitaldaemon.com>, Matthew Wilson says..."Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:bql580$4ki$1 digitaldaemon.com...You might be right but anyway you cut it shoud be easy to read, that's the only advantage we a seeking with the postfix idea. AntWalter wrote:overThe postfix cast does look good, but I don't see it has much advantageHmmm. There's some mileage in the C++ philosophy of not facilitating the ease-of-expression; maybe casts should be nasty to type?the prefix cast.I like the idea of postfix cast because it makes long chained expressions easier to read. IMHO, this: a.b.cast(Foo).c.d.cast(Bar).e.f is easier to read than: (cast(Bar)((cast(Foo)(a.b)).c.d)).e.f
Dec 04 2003
In article <bkq9th$17fn$1 digitaldaemon.com>, Dario says...I would prefer something like: . class A {} . class B:A {void func(){}} . A b = new B; . B.cast(b).func(); Rather than having to write: . (cast(B) b).func(); Isn't the former easier to read? Consider more complex code like the following: . ((CK) ((CA) list[i]).kid).func(); That becomes: . CK.cast(CA.cast(list[i]).kid).func();list[i].castTo(CA).kid.castTo(CK).funct or list[i].cast(CA).kid.cast(CK).funct or list[i].to(CA).kid.to(CK).funct looks even better to me! and list[i].castTo(MyClass*) looks better then Class*.cast(list[i]) or (Class*).cast(list[i]) Ant
Sep 23 2003
from: http://www.digitalmars.com/drn-bin/wwwnews?D/19990 I've remembered that I thought about cast expression this April (but independently of D,) and have found the memo which was written then. I introduced two types of *postfix* cast in the memo. One is `down_cast' for down cast and another is `cast' for the other cast (exactly I introduced also `up_cast' for the case of multiple inheritance.) e.g.) A a = new A; B b = a.cast(B); C c = a.down_cast(D); The memo also says as follows: Casts are similar to constructors, but casts are opposite processes to constructors. Because "A a = new A; B b = a.cast(B);" makes B's instance from A's instance though the `cast' is A's member function. It gives the same result as new B(a) (if B(A) is defined,) however, the cast can be implemented even if B knows *nothing* about A. This is a very important aspect of casts, and supports that casts must be subject to the casted classes. Casts are treated as member functions, but the syntax is special. Because return value types are given from the arguments. It's a unique property of casts. Many cast functions seem to have no arguments (the same arguments), but they can be overloaded. `implicit' keyword allows implicit cast if not ambiguous. Overloaded casts should be explicit by default. e.g.) struct Point { public int x, y; public Size cast() { return new Size(x, y); } public implicit LongPoint cast() { return new LongPoint(x, y); } } Point pt; Size siz = pt.cast(size); LongPoint lpt = pt; Cast methods can have some additional arguments if necessary. Down casts must be treated with especial care, must not be overloaded, and make no instances, so they should be distinguished from normal casts and should be done with special keyword. Though some specs may be bizarre, I would appreciate hearing advices for it. Robert (Japanese)
Dec 07 2003