CSC/ECE 517 Fall 2007/wiki1 5 sl: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(20 intermediate revisions by 2 users not shown)
Line 1: Line 1:
= Duck Typing =
= 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:
[[Image:Duck.png|frame]]


''If it walks like a duck and quacks like a duck, I would call it a duck.''[1]
The term “duck typing” comes from the common American analogy of the duck test, which can be summed up with the following phrase:


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.
''If it walks like a duck and quacks like a duck, I would call it a duck.'' [1]
 
That is to say that, if object A displays the behavior of another object B, object A can be treated as if it was the same as object B. In computer science, this concept can be applied to the virtual objects used in object-oriented languages like Smalltalk, Java, and C#. In this case, "duck typing" is also known as unbounded polymorphism.
 
rubylearning.com describes duck typing in this way:
 
''In Ruby, we rely less on the type (or class) of an object and more on its capabilities. Hence, Duck Typing means an object type is defined by what it can do, not by what it is. Duck Typing refers to the tendency of Ruby to be less concerned with the class of an object and more concerned with what methods can be called on it and what operations can be performed on it. In Ruby, we would use respond_to? or might simply pass an object to a method and know that an exception will be raised if it is used inappropriately. [4]''
 
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. [2]  This is in contrast to statically typed languages, such as Java. In these languages, if a parameter is passed to a method, that method my only use methods defined in that parameter or it's superclasses. If this rule is violated, an error is generated at compile time.


==Java Example==
==Java Example==
Take the following code snippet:
Let us examine the following code snippet:


<code><pre>
<code><pre>
Line 40: Line 48:
</pre></code>
</pre></code>


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.
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.
 
<code><pre>
class MyMath {
  public static boolean equals(ImaginaryNumber a, ImaginaryNumber b) { 
    return (a.getRealPart() == b.getRealPart());
  }
}
</pre></code>


==Ruby Example==
==Ruby Example==
Line 61: Line 77:
   
   
</pre></code>
</pre></code>
==Advantages & Disadvantages==
==Duck Typing vs. Interfaces and Inheritance==
 
The most obvious advantage of duck typing over interfaces and inheritance is conciseness of code. In a statically typed language that makes use of interfaces and inheritance, more code is often required to ensure type safety. Another major advantage is that duck typing is less restrictive since it allows the the end user to choose what type of object will be passed as parameters to any method at run time. As long as that argument has the required behavior, the method will function properly.
 
The disadvantage of duck typing is the potential for errors to occur at run time when the program is out of the control of the programmer. In a statically typed language, type safety errors 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. [3]
 
==See Also==
For another code example using Ruby, go to http://rubylearning.com/satishtalim/duck_typing.html


Duck Typing Static Typing
A Sun blog entry about duck typing: http://blogs.sun.com/bblfish/entry/duck_typing_done_right
Advantages Concise and elegant code


Less restrictive Safer (errors are caught at compile time)
Dave Thomas's entry about duck typing: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/78502


Interfaces can ensure that certain methods are always defined
Dr. Ed Gehringer's notes on duck typing can be found at http://courses.ncsu.edu/csc517/common/lectures/notes/lec6.doc.
Disadvantages Potential errors at runtime (code cannot be monitored at runtime)


No guarantee that required methods are implemented in subclasses More verbose code is required to check for errors
For a more detailed example using Boo, a language that uses both static typing and duck typing, see http://boo.codehaus.org/Duck+Typing.


==Other Examples and Discussion==
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.
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==
==References==


[1] http://en.wikipedia.org/wiki/Duck_test
[1] http://en.wikipedia.org/wiki/Duck_test
    http://en.wikipedia.org/wiki/Duck_typing
 
[2] http://en.wikipedia.org/wiki/Duck_typing
 
[3] http://courses.ncsu.edu/csc517/common/lectures/notes/lec6.doc
 
[4] http://rubylearning.com/satishtalim/duck_typing.html

Latest revision as of 18:52, 19 September 2007

Duck Typing

The term “duck typing” comes from the common American analogy of the duck test, which 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]

That is to say that, if object A displays the behavior of another object B, object A can be treated as if it was the same as object B. In computer science, this concept can be applied to the virtual objects used in object-oriented languages like Smalltalk, Java, and C#. In this case, "duck typing" is also known as unbounded polymorphism.

rubylearning.com describes duck typing in this way:

In Ruby, we rely less on the type (or class) of an object and more on its capabilities. Hence, Duck Typing means an object type is defined by what it can do, not by what it is. Duck Typing refers to the tendency of Ruby to be less concerned with the class of an object and more concerned with what methods can be called on it and what operations can be performed on it. In Ruby, we would use respond_to? or might simply pass an object to a method and know that an exception will be raised if it is used inappropriately. [4]

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. [2] This is in contrast to statically typed languages, such as Java. In these languages, if a parameter is passed to a method, that method my only use methods defined in that parameter or it's superclasses. If this rule is violated, an error is generated at compile time.

Java Example

Let us examine 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. Interfaces and Inheritance

The most obvious advantage of duck typing over interfaces and inheritance is conciseness of code. In a statically typed language that makes use of interfaces and inheritance, more code is often required to ensure type safety. Another major advantage is that duck typing is less restrictive since it allows the the end user to choose what type of object will be passed as parameters to any method at run time. As long as that argument has the required behavior, the method will function properly.

The disadvantage of duck typing is the potential for errors to occur at run time when the program is out of the control of the programmer. In a statically typed language, type safety errors 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. [3]

See Also

For another code example using Ruby, go to http://rubylearning.com/satishtalim/duck_typing.html

A Sun blog entry about duck typing: http://blogs.sun.com/bblfish/entry/duck_typing_done_right

Dave Thomas's entry about duck typing: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/78502

Dr. Ed Gehringer's notes on duck typing can be found at http://courses.ncsu.edu/csc517/common/lectures/notes/lec6.doc.

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

[2] http://en.wikipedia.org/wiki/Duck_typing

[3] http://courses.ncsu.edu/csc517/common/lectures/notes/lec6.doc

[4] http://rubylearning.com/satishtalim/duck_typing.html