Scott Hanselman recently posted a blog entry linking here. Thanks Scott!
He mentioned an interesting question about how this duck typing library fits in with the new C# "var" style declarations and the new dynamic language support of .NET. I thought I might briefly give my take on this.
"Var" style declarations have a similar but different purpose than duck typing. When you declare a "var" variable, you are basically saying to the compiler, "You figure out what type it is." The type is inferred at compile time based on the value that it is assigned. Then, the variable can be used as if it were that type. It basically amounts to syntactic sugar. Duck typing is quite different. When you cast an object using duck typing, you are instead saying, "It doesn't matter what type this object is, as long as I can interact with it in this way." It has the advantage of decoupling from the actual type of the object. This doesn't even have to be known at compile time.
The original problem that prompted my investigation into duck typing is the problem of versioning in a plug-in system. Say plug-in A was compiled to be used by version 1.0 of a program. The program is then updated to version 1.1 and plug-in B is compiled for use with this version. What about plug-in A? When its reference to the program library is resolved, version 1.0 will be loaded, whereas the program will load version 1.1. According to the .NET runtime, these are entirely different assemblies. Plug-in A implements an interface from version 1.0 and thus cannot be casted to an interface from version 1.1, even if these interfaces are identical. With duck typing, however, it doesn't matter what interface a plug-in implements, if any. It can be casted to the current version of an interface as long as it implements all its members. So problem solved. Both plug-in A and plug-in B can be interacted with in the same way without having to update plug-in A.
This is similar to dynamic typing in other languages in that certain behavior is performed on an object without knowing it's type, and as long as that object supports that behavior, the code succeeds. An advantage of duck typing, however, is that it must be known that the object's type implements all of the needed functionality at the time the object is casted. It does not wait until the functionality is actually used. Although this does not mean that more problems will be found at compile time, it does mean that problems will surface sooner when the program is executed, even if the code that uses certain functionality is never executed.