www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - runtime type and that bizarre "is()"

reply spir <denis.spir gmail.com> writes:
Hello,


Is there a way to check the runtime type of an element? Meaning, for instan=
ce, process differently according to the actual type in a hierarchy?

class C {}
class C1 : C {int i;}
bool checkTypeC1 (C c) {
    return is(typeof(c) =3D=3D C1);
}
void main () {
    C1 c1 =3D new C1();
    writeln(is(typeof(c1) =3D=3D C1));  // true, indeed!
    writeln(checkTypeC1(c1));       // false!
    C c =3D new C1();
    writeln(is(typeof(c) =3D=3D C1));   // false!
}

If, above, checktype is actualy a func that does more according to c's type=
 (or is called by a func that does more), then it bugs.
Should one write overloaded versions of the func depending on param type? B=
ut what about common parts of the process (sometimes, the difference is tin=
y)? One can factorise out into an additional func, but then there is func c=
all overhead, and the code structure gets complexified.

Also, I would like to ask about "is()". I don't understand its logics and u=
ses, even after reading TDPL pages about it. Seems uselessly complicated an=
d unintuitive. For instance, in the above cases, why do I need is() at all?=
 Why not just "typeof(c) =3D=3D C1"? or even better "typeof(c) is C1"?
By the way, why is "is(typeof(c) is C1)" refused by the compiler? It's more=
 logical than "=3D=3D", imo, as types should be compared by identity, not v=
alue. (For instance, 2 structs or classes that happen to define identically=
 named and typed fields are _not_ the same, unique, type.)


Denis
-- -- -- -- -- -- --
vit esse estrany =E2=98=A3

spir.wikidot.com
Nov 14 2010
parent bearophile <bearophileHUGS lycos.com> writes:
spir:

Only partial answers, other answers left to other people.

 Is there a way to check the runtime type of an element? Meaning, for instance,
process differently according to the actual type in a hierarchy?

You may use a cast(). If it return null then it's not castable.
 Also, I would like to ask about "is()". I don't understand its logics and
uses, even after reading TDPL pages about it. Seems uselessly complicated and
unintuitive. 

Lot of people think is() is indeed one of the less intuitive and easy to use parts of the language. Several people have suggested possible replacements, but not much has changed.
 For instance, in the above cases, why do I need is() at all? Why not just
"typeof(c) == C1"? or even better "typeof(c) is C1"?

Or better "c isa C1". I and other people have suggested that is(...) is not so nice, but I think for the compiler is simpler to keep the type world more separated from the world of expressions... And keeping the compiler simpler wins.
 By the way, why is "is(typeof(c) is C1)" refused by the compiler?

Maybe because the "is" syntax is newer, and maybe to avoid using is inside is.
 (For instance, 2 structs or classes that happen to define identically named
and typed fields are _not_ the same, unique, type.)

See on the Wikipedia the difference between nominative type systems and structural type systems. Bye, bearophile
Nov 14 2010