10

This question already has an answer here:

Duck typing is deciding on the type of an object, based on the operations it supports and the attributes it owns. Structural typing is... the same thing?

What exactly is the difference?

marked as duplicate by gnat, GlenH7, user40980, Bart van Ingen Schenau, Dan Pichelman Oct 15 '14 at 15:30

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Sharing your research helps everyone. Tell us what you've tried and why it didn’t meet your needs. This demonstrates that you’ve taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask – gnat Oct 14 '14 at 9:23
10

The main difference is that structural typing is enforced during static analysis found in statically typed languages, while duck typing is a runtime phenomenon emerging from the object semantics of dynamically typed languages.

As an example, take the following Haxe code (runnable here) using structural typing:

class Test {     
  static function main() {         
    var duck = {             
      quack: function () trace('Quack!!!'),             
      fly: function () trace('So let me take ... these broken wings ...')         
    };         
    duck.quack();         
    duck.fly();        
    duck.bark();     
  } 
}

The above will fail to compile with saying

Test.hx:9: characters 8-17 : { quack : Void -> Void, fly : Void -> Void } has no field bark

The compiler rejects the code, because you are accessing an undefined field on a given structural type. Equivalent JavaScript code would throw the beloved runtime exception

TypeError: undefined is not a function


Because duck typing occurs at runtime, we can make another distinction when it comes to reflective programs. It is more about asking "does it?" instead of the normal "is it?" (with the usually ensuing cast). So in pseudocode:

  • "classical" approach:

    if (is(someObject, IDuck))
      cast(someObject, IDuck).quack()
    
  • duck typing:

    if (hasMethod(someObject, 'quack'))
      someObject.quack();
    
  • 2
    It seems that the comparison only makes sense at run-time. Am I correct in understanding that that is the purpose of the second part of the answer (though the first part is a useful introduction)? - - - I am not familiar with this is+cast construction which you seem to consider standard. You have a pointer to a description. Why does it need a cast to access the method if it is know to have the right type for it? – babou Oct 14 '14 at 10:35
  • 2
    Correct. In order for programs to be reflective, they must run, so the second distinction only makes sense at runtime. As for my example: you do not always know the type of an object, but want to manually dispatch on type. Assume the language is Java and the type of someObject is IBird (a super type of IDuck that doesn't necessarily quack), but you would want ducks to quack. Unless you use reflection for a dynamic invocation, you cannot call the quack method directly. You need to cast the IBird to some type that has said method and must first check if it is of that type. – back2dos Oct 14 '14 at 11:36
  • I don't really know that there is a name for it. That's what casts are largely about. The prior type inspection is just to avoid runtime type cast errors and such. You could also try { cast(someObject, IDuck).quack() } catch (CastError error) { log('not a duck, cannot quack!'); }, but that's rather awkward. – back2dos Oct 14 '14 at 11:40
  • 2
    This answer is mostly wrong. The relevant difference between static and dynamic typing isn't when types are checked, but what has types: expressions or values. Nominal vs. structural typing is orthogonal to static vs. dynamic typing. “Duck typed” is often used as a description for dynamically typed languages, but it's actually about types being defined by available operations on that type – a duck is anything that can quack, and not just any object explicitly implementing the IDuck interface. Looks like structural typing to me…. Very few languages reify duck typing, but e.g. Go does. – amon Oct 14 '14 at 15:43
  • 3
    @amon: I disagree. Your first distinction is non-sense. Expressions exist during static analysis, values during execution. The what and when are isomorphic. Duck typing is about checking whether the operation needed is supported, usually at runtime near the call site. Structural typing implies a given value must be compatible to a structure, regardless of which parts of that structure are accessed (the distinction is further clarified on wikipedia). To make such a check at runtime would defeat the whole purpose of having a dynamically typed language to start with. – back2dos Oct 15 '14 at 0:16
3

Duck typing is depending upon objects responding to operations (aka messages or method invocations) in a way that's appropriate to them. "If it quacks like a duck, it's sufficiently duck-like to ask it to do duck things."

For example, in Python a dict object has an update method. I can code other kinds of objects that also have an update method:

class Able(object):
    def update(self, data):
        self.data = data

class Count(object):
    def update(self, increment):
        self.count += increment
        self.times_updated += 1

Now dict, Able, and Count instances respond to update, but they do it in ways that are appropriate to themselves.

Some languages (e.g. Python, Ruby) are very duck-typing friendly, while others (e.g. Java) are not. @back2dos gave an excellent example of structural typing, the ways the compiler will flag calls that are not explicitly defined, and the common requirement for explicit type casting in duck-unfriendly languages. Duck languages like Python check method availability at runtime (dynamically) rather than at compile-time. More important, from a usability point of view, is that they do not require type-casting to use specific methods. Any method (or property) may be requested of any object at any time. More than just "syntactic sugar," this permissiveness is what makes duck typing easy and useful.

Final point: Duck typing is not just a language feature, it's also an idiom and style of use--a feature of the programming language community and ethos, not just the language specification and compiler.

Not the answer you're looking for? Browse other questions tagged or ask your own question.