CSC/ECE 517 Fall 2007/wiki1 5 sl

From Expertiza_Wiki
Revision as of 17:15, 14 September 2007 by Srmunill (talk | contribs) (→‎Duck Typing)
Jump to navigation Jump to search

Duck Typing

The term “duck typing” comes from the common American analogy of the duck test. This test can be summed up with the following phrase:

If it walks like a duck and quacks like a duck, I would call it a duck.[1]

In dynamically typed languages, such as Ruby, the parameters of a given method do not need to have a pre-specified type. At run time, if the argument passed to the parameter has the necessary methods, the code will run.

Duck typing is also known as Unbounded Polymorphism.

Java Example

Take the following code snippet:

class ImaginaryNumber extends Object {
  public int realPart;
  public int imaginaryPart;

  public ImaginaryNumber(int realPart, int imaginaryPart) {
	  this.realPart = realPart;
	  this.imaginaryPart = imaginaryPart;
  }
  
  public int getRealPart() {
    return realPart;
  }

  public int getImaginaryPart() {
    return imaginaryPart;
  }
}

class MyMath {
  public static boolean equals(Object a, Object b) {   
    // this will create a compile-time error in Java
    return (a.getRealPart() == b.getRealPart());
  }
}

In a non-duck typed language, such as Java, the Equals() method above has two parameters a and b. It is required that these parameters have a specific type, in this case “Object”. A compile-time error will be generated even if two ImaginaryNumber objects are passed to the method. This occurs in spite of the fact that ImaginaryNumber has definitions for all of the methods called in Equals() and that ImaginaryNumber is a subclass of Object. In order to correct this error, Equals() would have to be changed to take two ImaginaryNumber objects as parameters. The corrected, functional version of the MyMath class is shown below.

class MyMath {
  public static boolean equals(ImaginaryNumber a, ImaginaryNumber b) {   
    return (a.getRealPart() == b.getRealPart());
  }
}

Ruby Example

In a duck typed language, such as Ruby, the Equals() method below would require parameters to have a defined type. A runtime error would be generated only if a non-ImaginaryNumber object was passed to the Equals() method. As long as only objects of type ImaginaryNumber are passed to the Equals() method, no error will ever be generated. The equivalent Ruby code is shown below.

class ImaginaryNumber
  def initialize(realPart, imaginaryPart)
    @realPart = realPart
    @imaginaryPart = imaginaryPart
  end
  attr_reader :realPart, :imaginaryPart
end 

class MyMath
  def self.equals(a, b)
    a.realPart == b.realPart
  end
end 
 

Duck Typing vs. Static Typing

The most obvious advantage of duck typing over static typing is conciseness of code. In a statically typed language, more code is often required to ensure type safety. Duck typing is less restrictive as it allows the user to choose what type of object will passed as parameters to any method. As long as that argument has that behavior, the method will function properly.

The disadvantage of duck typing is that potential errors will occur at run time, when the program is out of the control of the programmer. In a statically typed language, type safety error can be caught and corrected at compile time, before product release. As a result, statically typed languages are more suited for safety critical software, such as control systems.

See Also

For a more detailed example using Boo, a language that uses both static typing and duck typing, see http://boo.codehaus.org/Duck+Typing. For a real-world example of duck-typing in C#, visit http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx

References

[1] http://en.wikipedia.org/wiki/Duck_test

    http://en.wikipedia.org/wiki/Duck_typing