Mark Thomas

Deceptively random thoughts

Scala: Type safe duck typing

with 5 comments

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

Duck typing uses the set of methods and properties of an object, rather than its position in a type hierarchy to decide what you can do with it.

Scala’s structural typing feature provides something close to duck typing in a type safe way. A structural type is close to a .NET anonymous type; a type with a set of methods and properties but with no name. An example in Scala based on one of Wikipedia’s examples of duck typing:

class Duck {
  def quack = println("Quaaaaaack !")
  def feathers = println("The duck has white and gray feathers.")
}
 
class Person {
  def quack = println("The person imitates a duck.")
  def feathers = println("The person takes a feather from the ground and shows it.")
}
 
def inTheForest(duck: { def quack; def feathers }) = {
  duck.quack
  duck.feathers
}

The inTheForest function declares that it will accept any object that has a quack and feathers method, both of which take no parameters and return Unit (like void in Java/C#). When executed, the code works as expected:

scala> inTheForest(new Person)
The person imitates a duck.
The person takes a feather from the ground and shows it.

scala> inTheForest(new Duck)
Quaaaaaack !
The duck has white and gray feathers.

To demonstrate the type safety, lets try using a string:

scala> inTheForest("Duck")
:6: error: type mismatch;
 found   : java.lang.String("Duck")
 required: AnyRef{def quack: Unit; def feathers: Unit}
       inTheForest("Duck")
                   ^

When is this useful? Mostly in situations where you are consuming classes that follow common conventions but have no shared interface, in this case you can define the parts you are interested in by using the structural type as an implicit interface.

Finally, if you find that you are using a structural type a lot, it can define it in one place:

object UsefulTypes {
  type Duck = { def quack; def feathers }
}

inTheForest can then be declared as:

import UsefulTypes.Duck
 
def inTheForest(duck: Duck) = {
  duck.quack
  duck.feathers
}
Share

Written by Mark Thomas

August 27th, 2008 at 6:40 pm

5 Responses to 'Scala: Type safe duck typing'

Subscribe to comments with RSS or TrackBack to 'Scala: Type safe duck typing'.

  1. [...] public links >> scala Revised Scala Exercises First saved by netzach2 | 6 days ago Type safe duck typing with Scala First saved by lax | 21 days ago Scala office screens First saved by macaroon02 | 26 days ago [...]

  2. Nice art.
    I see that Scala compared to Ruby (which i currently use) is more type save for the price of writing some additional code, but still in an elegant way.

    In Ruby duck typing is comparable. Ruby does not have the obligation and the ability to declare which methods must the method argument have.

    Something like this:

    def inTheForest(duck: Object) = { /* I mean Object as a wildcard */
    duck.quack
    duck.feathers
    }

    will work?

    In Ruby it would look like this:

    def inTheForest(duck)
    duck.quack
    duck.feathers
    end

    Szymon Je?

    18 Aug 09 at 6:22 am

  3. [...] Java and I’ve discovered it doesn’t have to.  Functions being first class citizens and structural typing (think duck typing on steroids) remove not only a ton of boilerplate but also the need to rely on [...]

  4. Thanks, pretty clear explanation!

    Alex

    27 Dec 12 at 4:25 pm

  5. Excellent example. Easy to read and understand.

    Lars Støttrup

    11 Feb 13 at 10:54 am

Leave a Reply