If it walks, talks, and quacks like a duck, then it must be a duck.
For example:
if([someObj respondsToSelector:@selector(addObject:)]) [someObj addObject:otherObject];
In the first line we ask if we can send it an addObject: message, and if we can, conclude that we are dealing with an array, and adds the object.
Why is this any different than:
if([someObj isKindOfClass:[NSMutableArray class]]) [someObj addObject:otherObject];
It is because objects not inheriting from NSMutableArray might behave exactly like a mutable array, and so should be allowed to be substituted for one.
Careful, Just because an object “responds” to addObject:, you can not blindly conclude that you are dealing with an array, nor assume it behaves like one.
Better would be to use conformsToProtocol:
Array here is really an abstract concept and does not refer to NSMutableArray. The library writer e.g. says: I will add the results one at a time as objects using addObject: assuming the user will hand in an NSMutableArray, but he can actually hand in anything which responds to that method. The object he passes would not need to store the objects in an array, it could write them to standard out or throw them away, the implementor of the library should not care…
DuckTyping reminds me of languages with prototype based inheritance, like JavaScript and IoLanguage. There are no classes, only prototype objects. Methods can be added at any time, and you inherit by cloning the state of another object. It’s another way of thinking.
In the good ol’ days of JavaScript hacking, the wise birds always used to say “object detection, not version detection”. What they did was encouraging DuckTyping, since that was safer than checking for a browser version and then assuming things (i.e check if there is a document.getElementsById method before using it instead of checking for Mozilla).
Being so dynamic, how hard could it be to implement prototype based inheritance in ObjC?
– TheoHultberg/Iconara
Basically, ObjC already supports it. You can enumerate all aspects of the class internals, pull them apart, modify them, add/remove methods, etc. The runtime headers (/usr/include/objc) have some good stuff in them. I suspect you could put a class together on the fly, nearly from scratch sans method implementations.
Yes, this is sort of already happening with bindings. I.e. a new class is created with new implementations for set
Well technically, Carbon’s universal function pointer is just that, a C function pointer; it’s just wrapped up in a opaque type. Either way, you still have to supply the entry point. —- Okay, I didn’t do Carbon, so I do not know the details, just read it was designed so that it allowed various calling conventions (i.e. binding to different languages).
To clarify, what I wanted was just something like this:
struct function_ptr { id(function)(void user_data, …); void* user_data; };
So when registering a function (method) I would hand in a structure like above, i.e. both a C-function pointer and some opaque user data which is given to the function.
I think you may be thinking of transition vectors, which were used in PEF/CFM to implement function pointers. These could have assosiated data. However, Mach-O uses “raw” function pointers without this capacity.