[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