What is it? It's a very flexible and powerful technique that allows functions to operate on any arbitrary component that implements the methods needed by that function.
Isn't that what interfaces are for? Well, interfaces (in other languages) can provide a specification of a set of methods that must be implemented by concrete classes. The (static) type system of those languages then only allows objects whose type explicitly implements the given interface to be passed into a function that specifies that interface as its argument type.
Duck typing allows any object to be passed into a function and, as long as the object provides the right method signatures, the function can use it. That means that it only has to implement methods that particular function actually calls and only needs to provide compatible function signatures.
For example, java.lang.Collection is an interface that specifies a lot of methods with very specific signatures. Suppose you had a function that just needs to call add() and remove() on an object passed in (that is assumed to behave like a collection). In the Java world your object would need to implement all of the methods in the collection interface if your function specified that as its argument type. That's a lot of work if your object is only collection-like rather than being an actual collection. Duck typing would allow you to specify the function could take any object and by documented convention only calls the add/remove methods on it. Then you could pass any object that implements those methods - even if it wasn't a full-blown collection.
It's a powerful technique and one that is more idiomatic for ColdFusion than extending the language to include full-blown interfaces. My Concurrency for CFMX library uses that technique for callable objects (release 1.0 had a Callable CFC base class that I deprecated in release 1.1).
In code, it's as simple as:
That's why I've stumped for tagging interfaces (i.e. Java-like interfaces with zero member methods) in CF. You'd rely on duck typing for the actual functionality, but you'd have a little bit of self documentation (and some runtime security) that you're at least passing around something reasonable.
So scrap the compile-time signature checks that interfaces typically imply, because they don't make any sense with CF, but leave the tagging benefits, and you've got something that could be really useful. As long as assigning types happens as dynamically as assigning methods, of course.
If you say type="any", no checking at all is done. (I think that's the answer to what you're asking)
(But, yes, in general folks tend to mean CFCs as objects)
And, yes, methods can return an object or a non-object (but I would stick to just returning "" or an object to simulate 'null' and then use isObject() on the returned value). I don't think it's good practice to, say, return an error message or a live object - I think for errors, you should throw an exception...


