check type

spir denis.spir at gmail.com
Sat Nov 6 13:08:38 PDT 2010


On Sat, 06 Nov 2010 14:48:44 -0400
bearophile <bearophileHUGS at lycos.com> wrote:

> spir:
> 
> > What is the common idiom to check whether the type of a given element is what I expect?
> > Seems that
> > 	typeof(e) == Type
> > is refused by the compiler, for any reason? I get
> > 	DeeMatch.d(237): Error: type string is not an expression
> 
> I don't know why the language refuses a natural and more clean syntax like:
> if (typeof(x) == Type) {...
> I think it's to keep the compiler simple, clearly telling apart the compile-time phase that uses types (or CTFE) from the run-time that uses values.
> So you have to wrap it into a is(), often this is enough:
> if (is(typeof(x) == Type)) {...
> But look in the docs at the complex syntax of is() for the many other different ways to use it.

Right.
I looked at 'is' before, precisely. But there does not seem to be any direct idiom to test a variable's type. At least, the book TDPL does not show any. It shows only operations on types themselves (without any var). I'll check your proposal ==> works, thanks!

> > Also, how to override a class's field so that it is accessed according actual/runtime type? (Like method dispatch.)
> 
> This feature is named "double dispatch", and it's present in the object system named CLOS of CommonLisp, but unfortunately it's not present in D (or C++, Java, Python). Maybe the Scala language too has this feature. See:
> http://en.wikipedia.org/wiki/Double_dispatch
> http://en.wikipedia.org/wiki/Visitor_pattern
> 
> The D language allows you to perform the dispatch only on the compile time type of the arguments (or the dynamic type of the "this"). This means that if you have to perform double dispatch in D/C++/Python, then you need to implement/simulate this feature manually. There are several ways to do it, see . In some situations if your program needs to use double dispatch heavily, then you may invent a string mixin to reduce somehow the boilerplate code.
> 
> 
> > 	void method (SuperType x) {...access x.f...}
> > If I don't define f in SuperType, then I get a compiler error. If I do, then SuperType.f is accessed, not the field on actual class of x.
> 
> D is a statically typed language, this means that in general the choices about types (this mean choice of code path or code generation by templates) are performed only at compile time.
> 
> Despite languages like Java and D are statically typed, they allow a bit of dynamic typing, using the virtual table of the classes, and allowing run-time types of objects to differ from their compile-time type. But this bit of dynamic typing is limited and is not extended to double/multiple dispatch (on the other hand even very dynamic languages like Python lack double or multiple dispatch).

Hem, I'm not sure it's double dispatch. What I mean works in many languges, including python, Lua, and I guess OO langs of the Pascal family. Just this:

class SC {
    string f = "SC";
    void show() {writeln(this.f);}
}
class C : SC {
    string f = "C";
}
void main () {
    auto c = new C();
    writeln(c.f) ;  // OK, got "C"
    c.show() ;      // expected "C", got "SC"
    
    // below test for type
    if (is(typeof(c) == C)) {writeln("type C");} else {writeln("type SC");}
    auto sc = new SC();
    if (is(typeof(sc) == C)) {writeln("type C");} else {writeln("type SC");}
}

It's not double dispatch, I guess, but exactly the same dispatch on actual/runtime type for fields as we have for methods. And it woeks for sure in python (and many other languages):

class SC:
    f = "SC"
    def show(self):
        print self.f
class C (SC):
    f = "C"

c = C()
print c.f       # OK, got "C"
c.show()        # OK, got "C" as well

Well, actually, I don't need the feature anymore for the present use case, as it was only to work around the above issue (had a "typename" field). But I would still like to find a way of having fields accessed according actual type, or know for sure that it's impossible (and 'why" in option ;-).
I guess it may be so because field access is resolved at compile-time, unlike method access. (Meaning so-to-say "zero-dispatch" for fields, while we have single-dispatch for methods.) In dynamic languages, indeed, both are resolved at runtime. But, if I'm right on this, the D way surely is a big gain in efficiency.


Thank you, anyway,
Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



More information about the Digitalmars-d-learn mailing list