Re: [chuck-users] determining the type of an Object in code
Hello, fellow Chuckers! I keep finding myself returning to this issue of trying to determine the class of an object instance at runtime. We talked about it here: https://lists.cs.princeton.edu/pipermail/chuck-users/2008-September/003242.h... I recently pulled from CVS and started fooling around and discovered a remarkably simple hack. There's a method in Object, toString(), which returns a string containing the class of the object as well as the reference ID. Like this (supposing a class called "Test"): "Test:11ceff0" There's also a stub in chuck_lang.cpp for a method getType(), which isn't implemented (yet). So, I copied the implementation of toString(), minus the printing of the reference ID, and placed it where the implementation of getType() should be. Now all objects (not UGens yet, although that would be sweet) respond to getType(). Example: class Test { 5 => int i; fun void sayHi() { <<< "hi" >>>; } } Test test; test @=> Object o; // Object still knows it's a Test! <<< o.toString() >>>; <<< o.getType() >>>; // Object can't sayHi() //o.sayHi(); // but this is now possible if( o.getType() == "Test" ) { (o $ Test).sayHi(); } The above code will print this: "Test:11cf160" : (string) "Test" : (string) "hi" : (string) This makes me very happy and opens up many doors, although I have no idea what getType() was originally intended to do--I assume a similar purpose. I'm sure that this will work as a mod to the current release as well, although I made my changes in the CVS version (I'm excited for FileIO). This ought to make implementing things like ArrayList a lot easier. ;-) I consider this a feature request (for this or something like it). I think this would be super helpful for UGens and primitives also. Primitives, however, don't support the dot notation... Oh well. I'll take what I can get. -Mike -- http://michaelclemow.com http://semiotech.org
2009/2/10 mike clemow
I recently pulled from CVS and started fooling around and discovered a remarkably simple hack. There's a method in Object, toString(), which returns a string containing the class of the object as well as the reference ID. Like this (supposing a class called "Test"):
"Test:11ceff0"
There's also a stub in chuck_lang.cpp for a method getType(), which isn't implemented (yet). So, I copied the implementation of toString(), minus the printing of the reference ID, and placed it where the implementation of getType() should be. Now all objects (not UGens yet, although that would be sweet) respond to getType().
Haha, awesome! I guess if getType() is going to be something different you're a little screwed, but an interesting solution. Do you have a GitHub account to publish this in a fork with? Not necessary, but even if you just clone it locally and make a branch on your computer, then it'll be easier to maintain the change as versions go by. -- Tom Lieber http://AllTom.com/
Hi Tom,
Github, yes. The fork is here:
http://github.com/clembie/mc_chuck_dev/
I may make some other modifications. I'll publish those as well. The
v2 folder is where you should build from.
If getType() was stubbed out, then my guess is that we shouldn't mess
with it. Perhaps we should change the name of this method to
something else. getClass() maybe...
-Mike
On Tue, Feb 10, 2009 at 10:25 PM, Tom Lieber
2009/2/10 mike clemow
: I recently pulled from CVS and started fooling around and discovered a remarkably simple hack. There's a method in Object, toString(), which returns a string containing the class of the object as well as the reference ID. Like this (supposing a class called "Test"):
"Test:11ceff0"
There's also a stub in chuck_lang.cpp for a method getType(), which isn't implemented (yet). So, I copied the implementation of toString(), minus the printing of the reference ID, and placed it where the implementation of getType() should be. Now all objects (not UGens yet, although that would be sweet) respond to getType().
Haha, awesome! I guess if getType() is going to be something different you're a little screwed, but an interesting solution.
Do you have a GitHub account to publish this in a fork with? Not necessary, but even if you just clone it locally and make a branch on your computer, then it'll be easier to maintain the change as versions go by.
-- Tom Lieber http://AllTom.com/ _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
2009/2/11 mike clemow
If getType() was stubbed out, then my guess is that we shouldn't mess with it. Perhaps we should change the name of this method to something else. getClass() maybe...
How about ".isA( type)" that would return true or false ? I'm suggesting that because some object may be *a Object *a UGen *a STKInstrument *a Sitar ...all at the same time. So; "my_sitar" would return true for all those and this; if ( my_sitar.isA( Event ) ) do.someThing(); ...wouldn't work. Does that make sense to you? Kas.
Yes, like instanceOf() in other languages.
First off, I think that makes perfect sense, but I also don't have the
slightest clue how to implement it. ;-)
Taking a class per se as an argument would necessitate looking that
token up in some list of classes available at runtime, no? Also, it
seems that these things would have to be defined separately for UGen
and Object--as far as I can tell. My C++ skills are next-to-absent,
to be honest.
In the meantime, taking a string representation of a class, like
"Object", for an argument would be much easier to implement (for me,
anyway). We could do this just to prototype the feature, see if it's
useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running
quickly to try it out. Perhaps then someone smarter than me would be
interested in looking into making it so that it could be done without
the quotes (i.e. as a class and not a string), which, I assume, would
be safer.
-Mike
On Wed, Feb 11, 2009 at 12:25 AM, Kassen
2009/2/11 mike clemow
If getType() was stubbed out, then my guess is that we shouldn't mess with it. Perhaps we should change the name of this method to something else. getClass() maybe...
How about ".isA( type)" that would return true or false ?
I'm suggesting that because some object may be *a Object *a UGen *a STKInstrument *a Sitar
...all at the same time. So; "my_sitar" would return true for all those and this;
if ( my_sitar.isA( Event ) ) do.someThing();
...wouldn't work.
Does that make sense to you?
Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Mike; Yes, like instanceOf() in other languages.
Exactly. Maybe we should stick to conventions where they exist, even if .isA() is good for lazy typists.
Taking a class per se as an argument would necessitate looking that token up in some list of classes available at runtime, no?
Well, yes, I suppose, but that gets done anyway as ChucK has to make sure all objects we define are of a known type so ChucK already has to go over all previously defined types as well as the ones in the current file anyway. Clearly such a list exists somewhere in the system already (that need not mean it'll be easy to find for you or me, of course....).
Also, it seems that these things would have to be defined separately for UGen and Object--as far as I can tell. My C++ skills are next-to-absent, to be honest.
Hmmmm, but UGens are Objects too, and UGens do know their type, at least
this shows us that their type is known.
Gain shoe;
<<<shoe>>>;
<<
In the meantime, taking a string representation of a class, like "Object", for an argument would be much easier to implement (for me, anyway). We could do this just to prototype the feature, see if it's useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running quickly to try it out. Perhaps then someone smarter than me would be interested in looking into making it so that it could be done without the quotes (i.e. as a class and not a string), which, I assume, would be safer.
Sure! Still, there are cases like STKInstrument where it would be very useful to know what type a certain object inherits from. In certain cases that might be even more interesting than the type of the object itself. Anyway, I like this plan. It's based on stuff we already have and it will make things like the type casting we talked about a short while ago much safer and more practical. Actually I think that we should make info that's available in the system already available within the language as much as possible. It will also be useful to be able to get the type of a object, like you sugest above, in adition to my idea because my proposal doesn't allow for comparing whether two objects are of the same type. I could imagine that making sure two objects are of the same type could come handy at times. Would it be possible to have a type "type"? It seems that that is something we are heading towards here if we'd like to avoid strings in this situation. Would that cause terrible paradoxes that might destabilise the nature of the universe? Yours, Kas.
Greetings.
I submitted a patch to the dev-list ages ago for one of my hacks
https://lists.cs.princeton.edu/pipermail/chuck-dev/2006-March/000135.html
It's probably not the best way to do this, as it introduces a new bytecode.
anyway
Graham
On Wed, Feb 11, 2009 at 7:17 AM, Kassen
Mike;
Yes, like instanceOf() in other languages.
Exactly. Maybe we should stick to conventions where they exist, even if .isA() is good for lazy typists.
Taking a class per se as an argument would necessitate looking that token up in some list of classes available at runtime, no?
Well, yes, I suppose, but that gets done anyway as ChucK has to make sure all objects we define are of a known type so ChucK already has to go over all previously defined types as well as the ones in the current file anyway. Clearly such a list exists somewhere in the system already (that need not mean it'll be easy to find for you or me, of course....).
Also, it seems that these things would have to be defined separately for UGen and Object--as far as I can tell. My C++ skills are next-to-absent, to be honest.
Hmmmm, but UGens are Objects too, and UGens do know their type, at least this shows us that their type is known.
Gain shoe; <<<shoe>>>; <<
>>; I'm not sure I see the difference with other objects though there may be a big one in the C++ code?
In the meantime, taking a string representation of a class, like "Object", for an argument would be much easier to implement (for me, anyway). We could do this just to prototype the feature, see if it's useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running quickly to try it out. Perhaps then someone smarter than me would be interested in looking into making it so that it could be done without the quotes (i.e. as a class and not a string), which, I assume, would be safer.
Sure! Still, there are cases like STKInstrument where it would be very useful to know what type a certain object inherits from. In certain cases that might be even more interesting than the type of the object itself.
Anyway, I like this plan. It's based on stuff we already have and it will make things like the type casting we talked about a short while ago much safer and more practical. Actually I think that we should make info that's available in the system already available within the language as much as possible.
It will also be useful to be able to get the type of a object, like you sugest above, in adition to my idea because my proposal doesn't allow for comparing whether two objects are of the same type. I could imagine that making sure two objects are of the same type could come handy at times.
Would it be possible to have a type "type"? It seems that that is something we are heading towards here if we'd like to avoid strings in this situation. Would that cause terrible paradoxes that might destabilise the nature of the universe?
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Hi Graham,
Sweeter still! This the key feature that your hack provides is this:
SinOsc s;
s instanceOf SinOsc; // true
s instanceOf UGen; // also true
My hack only knows the type it was instantiated as. The only issue I
see with this is that, unless it also works on primitives, I would say
that it ought to be a method of Object rather than a keyword/operator.
Also, now that I'm typing this out, I'm favoring the keystroke-light
isA() method... hrm...
-Mike
On Wed, Feb 11, 2009 at 7:27 AM, Graham Coleman
Greetings.
I submitted a patch to the dev-list ages ago for one of my hacks https://lists.cs.princeton.edu/pipermail/chuck-dev/2006-March/000135.html
It's probably not the best way to do this, as it introduces a new bytecode.
anyway
Graham
On Wed, Feb 11, 2009 at 7:17 AM, Kassen
wrote: Mike;
Yes, like instanceOf() in other languages.
Exactly. Maybe we should stick to conventions where they exist, even if .isA() is good for lazy typists.
Taking a class per se as an argument would necessitate looking that token up in some list of classes available at runtime, no?
Well, yes, I suppose, but that gets done anyway as ChucK has to make sure all objects we define are of a known type so ChucK already has to go over all previously defined types as well as the ones in the current file anyway. Clearly such a list exists somewhere in the system already (that need not mean it'll be easy to find for you or me, of course....).
Also, it seems that these things would have to be defined separately for UGen and Object--as far as I can tell. My C++ skills are next-to-absent, to be honest.
Hmmmm, but UGens are Objects too, and UGens do know their type, at least this shows us that their type is known.
Gain shoe; <<<shoe>>>; <<
>>; I'm not sure I see the difference with other objects though there may be a big one in the C++ code?
In the meantime, taking a string representation of a class, like "Object", for an argument would be much easier to implement (for me, anyway). We could do this just to prototype the feature, see if it's useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running quickly to try it out. Perhaps then someone smarter than me would be interested in looking into making it so that it could be done without the quotes (i.e. as a class and not a string), which, I assume, would be safer.
Sure! Still, there are cases like STKInstrument where it would be very useful to know what type a certain object inherits from. In certain cases that might be even more interesting than the type of the object itself.
Anyway, I like this plan. It's based on stuff we already have and it will make things like the type casting we talked about a short while ago much safer and more practical. Actually I think that we should make info that's available in the system already available within the language as much as possible.
It will also be useful to be able to get the type of a object, like you sugest above, in adition to my idea because my proposal doesn't allow for comparing whether two objects are of the same type. I could imagine that making sure two objects are of the same type could come handy at times.
Would it be possible to have a type "type"? It seems that that is something we are heading towards here if we'd like to avoid strings in this situation. Would that cause terrible paradoxes that might destabilise the nature of the universe?
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Graham,
I'm officially in over my head. ;-) Could the same thing be done as
a method of Object so that
SinOsc s;
s.instanceOf(SinOsc); // returns 1 and
s.instanceOf(UGen); // also returns 1?
Are you on github?
-Mike
On Wed, Feb 11, 2009 at 11:09 AM, mike clemow
Hi Graham,
Sweeter still! This the key feature that your hack provides is this:
SinOsc s;
s instanceOf SinOsc; // true s instanceOf UGen; // also true
My hack only knows the type it was instantiated as. The only issue I see with this is that, unless it also works on primitives, I would say that it ought to be a method of Object rather than a keyword/operator.
Also, now that I'm typing this out, I'm favoring the keystroke-light isA() method... hrm...
-Mike
On Wed, Feb 11, 2009 at 7:27 AM, Graham Coleman
wrote: Greetings.
I submitted a patch to the dev-list ages ago for one of my hacks https://lists.cs.princeton.edu/pipermail/chuck-dev/2006-March/000135.html
It's probably not the best way to do this, as it introduces a new bytecode.
anyway
Graham
On Wed, Feb 11, 2009 at 7:17 AM, Kassen
wrote: Mike;
Yes, like instanceOf() in other languages.
Exactly. Maybe we should stick to conventions where they exist, even if .isA() is good for lazy typists.
Taking a class per se as an argument would necessitate looking that token up in some list of classes available at runtime, no?
Well, yes, I suppose, but that gets done anyway as ChucK has to make sure all objects we define are of a known type so ChucK already has to go over all previously defined types as well as the ones in the current file anyway. Clearly such a list exists somewhere in the system already (that need not mean it'll be easy to find for you or me, of course....).
Also, it seems that these things would have to be defined separately for UGen and Object--as far as I can tell. My C++ skills are next-to-absent, to be honest.
Hmmmm, but UGens are Objects too, and UGens do know their type, at least this shows us that their type is known.
Gain shoe; <<<shoe>>>; <<
>>; I'm not sure I see the difference with other objects though there may be a big one in the C++ code?
In the meantime, taking a string representation of a class, like "Object", for an argument would be much easier to implement (for me, anyway). We could do this just to prototype the feature, see if it's useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running quickly to try it out. Perhaps then someone smarter than me would be interested in looking into making it so that it could be done without the quotes (i.e. as a class and not a string), which, I assume, would be safer.
Sure! Still, there are cases like STKInstrument where it would be very useful to know what type a certain object inherits from. In certain cases that might be even more interesting than the type of the object itself.
Anyway, I like this plan. It's based on stuff we already have and it will make things like the type casting we talked about a short while ago much safer and more practical. Actually I think that we should make info that's available in the system already available within the language as much as possible.
It will also be useful to be able to get the type of a object, like you sugest above, in adition to my idea because my proposal doesn't allow for comparing whether two objects are of the same type. I could imagine that making sure two objects are of the same type could come handy at times.
Would it be possible to have a type "type"? It seems that that is something we are heading towards here if we'd like to avoid strings in this situation. Would that cause terrible paradoxes that might destabilise the nature of the universe?
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
I think both a member function and a keyword are good to have. The keyword way is much safer (the type can be verified at compile-time, and it doesn't need to throw an exception if the instance being tested is null). The member function way can be allowed to accept arbitrary, potentially non-existent type names, which comes in handy every now and then (suppose that you know a type will exist in the future, but its .ck file hasn't been added yet). You could also use a .isA() member function to implement hack-y generic container classes purely in ChucK code, which would be really cool to have. To the member-fun method's detriment, extending ChucK to allow compile- time type-checking of the type specified to .isA() seems pretty invasive, and without that it can be prone to simple but potentially elusive errors like .isA("Sinosc"). Similarly, modifying ChucK to accept raw, unquoted typenames as function arguments is no small task. Perhaps the solution here is adding a Object.typeName static method/ static variable, which returns a string, allowing code like s.isA(SinOsc.typeName) to work. That doesn't win any awards for terseness, but it seems like a good way to type-check this at compile- time without adding a new keyword. spencer On Feb 11, 2009, at 8:44 AM, mike clemow wrote:
Graham,
I'm officially in over my head. ;-) Could the same thing be done as a method of Object so that
SinOsc s; s.instanceOf(SinOsc); // returns 1 and s.instanceOf(UGen); // also returns 1?
Are you on github?
-Mike
On Wed, Feb 11, 2009 at 11:09 AM, mike clemow
wrote: Hi Graham,
Sweeter still! This the key feature that your hack provides is this:
SinOsc s;
s instanceOf SinOsc; // true s instanceOf UGen; // also true
My hack only knows the type it was instantiated as. The only issue I see with this is that, unless it also works on primitives, I would say that it ought to be a method of Object rather than a keyword/ operator.
Also, now that I'm typing this out, I'm favoring the keystroke-light isA() method... hrm...
-Mike
On Wed, Feb 11, 2009 at 7:27 AM, Graham Coleman
wrote: Greetings.
I submitted a patch to the dev-list ages ago for one of my hacks https://lists.cs.princeton.edu/pipermail/chuck-dev/2006-March/000135.html
It's probably not the best way to do this, as it introduces a new bytecode.
anyway
Graham
On Wed, Feb 11, 2009 at 7:17 AM, Kassen
wrote: Mike;
Yes, like instanceOf() in other languages.
Exactly. Maybe we should stick to conventions where they exist, even if .isA() is good for lazy typists.
Taking a class per se as an argument would necessitate looking that token up in some list of classes available at runtime, no?
Well, yes, I suppose, but that gets done anyway as ChucK has to make sure all objects we define are of a known type so ChucK already has to go over all previously defined types as well as the ones in the current file anyway. Clearly such a list exists somewhere in the system already (that need not mean it'll be easy to find for you or me, of course....).
Also, it seems that these things would have to be defined separately for UGen and Object--as far as I can tell. My C++ skills are next-to- absent, to be honest.
Hmmmm, but UGens are Objects too, and UGens do know their type, at least this shows us that their type is known.
Gain shoe; <<<shoe>>>; <<
>>; I'm not sure I see the difference with other objects though there may be a big one in the C++ code?
In the meantime, taking a string representation of a class, like "Object", for an argument would be much easier to implement (for me, anyway). We could do this just to prototype the feature, see if it's useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running quickly to try it out. Perhaps then someone smarter than me would be interested in looking into making it so that it could be done without the quotes (i.e. as a class and not a string), which, I assume, would be safer.
Sure! Still, there are cases like STKInstrument where it would be very useful to know what type a certain object inherits from. In certain cases that might be even more interesting than the type of the object itself.
Anyway, I like this plan. It's based on stuff we already have and it will make things like the type casting we talked about a short while ago much safer and more practical. Actually I think that we should make info that's available in the system already available within the language as much as possible.
It will also be useful to be able to get the type of a object, like you sugest above, in adition to my idea because my proposal doesn't allow for comparing whether two objects are of the same type. I could imagine that making sure two objects are of the same type could come handy at times.
Would it be possible to have a type "type"? It seems that that is something we are heading towards here if we'd like to avoid strings in this situation. Would that cause terrible paradoxes that might destabilise the nature of the universe?
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- http://michaelclemow.com http://semiotech.org _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
... You could also use a .isA() member function to implement hack-y generic container classes purely in ChucK code, which would be really cool to have.
Yes-Yes!
Perhaps the solution here is adding a Object.typeName static method/static variable, which returns a string, allowing code like s.isA(SinOsc.typeName) to work. That doesn't win any awards for terseness, but it seems like a good way to type-check this at compile-time without adding a new keyword.
I like this idea. What about a compromise: s.isA( SinOsc.type ) I think that reads better. Also, while I'm more in favor of a static member--for typing's sake--it seems to be the Chuckian way to differentiate between .gain and .gain(), the latter being the accessor methods that returns the value. Hence, s.isA( SinOsc.type() ) seems to be more in keeping with the rest of Chuck, stylistically speaking. I'll poke around for another static method on which to model this one. Cheers, Mike
Kas,
Hmmmm, but UGens are Objects too, and UGens do know their type, at least this shows us that their type is known.
You're right: they both inherit from Chuck_Object in the C++. And, this hack works just as well with SinOsc as it does with any handmade class apparently.
Would that cause terrible paradoxes that might destabilise the nature of the universe?
Well, that would take the "play" out of all this, wouldn't it? ;-)
-Mike
On Wed, Feb 11, 2009 at 1:17 AM, Kassen
Mike;
Yes, like instanceOf() in other languages.
Exactly. Maybe we should stick to conventions where they exist, even if .isA() is good for lazy typists.
Taking a class per se as an argument would necessitate looking that token up in some list of classes available at runtime, no?
Well, yes, I suppose, but that gets done anyway as ChucK has to make sure all objects we define are of a known type so ChucK already has to go over all previously defined types as well as the ones in the current file anyway. Clearly such a list exists somewhere in the system already (that need not mean it'll be easy to find for you or me, of course....).
Also, it seems that these things would have to be defined separately for UGen and Object--as far as I can tell. My C++ skills are next-to-absent, to be honest.
Hmmmm, but UGens are Objects too, and UGens do know their type, at least this shows us that their type is known.
Gain shoe; <<<shoe>>>; <<
>>; I'm not sure I see the difference with other objects though there may be a big one in the C++ code?
In the meantime, taking a string representation of a class, like "Object", for an argument would be much easier to implement (for me, anyway). We could do this just to prototype the feature, see if it's useful, etc.
myObject.isA( "Object" )
Could return true or false. This I think we could have up and running quickly to try it out. Perhaps then someone smarter than me would be interested in looking into making it so that it could be done without the quotes (i.e. as a class and not a string), which, I assume, would be safer.
Sure! Still, there are cases like STKInstrument where it would be very useful to know what type a certain object inherits from. In certain cases that might be even more interesting than the type of the object itself.
Anyway, I like this plan. It's based on stuff we already have and it will make things like the type casting we talked about a short while ago much safer and more practical. Actually I think that we should make info that's available in the system already available within the language as much as possible.
It will also be useful to be able to get the type of a object, like you sugest above, in adition to my idea because my proposal doesn't allow for comparing whether two objects are of the same type. I could imagine that making sure two objects are of the same type could come handy at times.
Would it be possible to have a type "type"? It seems that that is something we are heading towards here if we'd like to avoid strings in this situation. Would that cause terrible paradoxes that might destabilise the nature of the universe?
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
participants (5)
-
Graham Coleman
-
Kassen
-
mike clemow
-
Spencer Salazar
-
Tom Lieber