[chuck-users] class abuse
Robert Poor
rdpoor at gmail.com
Wed Sep 30 19:11:23 EDT 2009
I can hardly call this a bug, since people who go around casting
classes get what they deserve, but it's unexpected behavior
nonetheless. Consider the following -- the salient point is that
General is a super class, Specific extends General.
===================
class General {
fun void announce() { <<< "I am general:", this.toString() >>>; }
}
class Specific extends General {
fun void announce() { <<< "I am specific:", this.toString() >>>; }
}
fun General create(int type) { // factory method
return (type==0)?(new General):((new Specific) $ General);
}
fun void process(General obj) {
<<< "processing general object:", obj.toString() >>>;
}
fun void process(Specific obj) {
<<< "processing specific object:", obj.toString() >>>;
}
General @ obj;
create(0) @=> obj; // [1] create a General object
obj.announce(); // [2] calls General.announce()
process(obj); // [3] calls process(General obj)
create(1) @=> obj; // [4] create a Specific object
obj.announce(); // [5] calls Specific.announce()
process(obj); // [6] calls process(General obj)
process(obj $ Specific); // [7] calls process(General obj)
===================
which produces the following (I've annotated the line numbers):
===================
r% chuck classtest.ck
[2] I am general: General:5df960
[3] processing general object: General:5df960
[5] I am specific: Specific:5de400
[6] processing general object: Specific:5de400
[7] processing general object: Specific:5de400
===================
Lines [1], [2], [3] do what you expect: creates a general object,
calls the General.announce() method, and calls the process() function
which has the <General obj> signature. So far so good.
Lines [4], [5] also do what's expected: creates a Specific object and
calls the Specific.announce() method.
Line [6] is up for grabs. I half expected it to call the version of
process() with the <Specific obj> signature (since it called the
Specific.announce() method at step [5]). On the other hand, obj was
declared as a General class, so it doesn't surprise me that it called
the version of process() with the <General obj> signature.
Line [7] is what bugs me: obj is cast to the Specific class, and the
ChucK compiler _knows_ this at compile time. Yet it calls the
process(General obj) function, NOT the process(Specific obj) function.
If ChucK uses run-time checking for signature discrimination, then [6]
should call process(Specific obj). But it uses compile time checking,
right? So why doesn't it call process(Specific obj) in step [7]?
I promise not to lose too much sleep over this. If someone familiar
with ChucK's type system wants to report this as a bug, be my guest.
I'm just happy to find that ChucK has a smidgen of run-time type
discrimination (as evidenced at [5]).
- Rob
More information about the chuck-users
mailing list