Scala Goodness: Compound Types

Scala is ideally suited for programming in roles because it does features traits. Think of Traits like interfaces in Java with implementation code. Say you have a dog:

class Dog {
   def call() { println("Comes to you") }
   def feed() { println("Feeds") }
}

then this dog has two roles, Callable and Feedable. You can extract those into traits:

trait Callable {
  def call() { println("Comes to you") }
}

trait Feedable {
   def feed() { println("Feeds") }
}

and combine them with your Dog:

class Dog extends Callable with Feedable

This is the first Scala goodness. But you can also extend your Dog at calltime:

scala> class Dog
defined class Dog

scala> val d = new Dog
d: Dog = Dog@1f808e6

scala> d.call
:7: error: value call is not a member of Dog
       d.call
         ^
scala> val d = new Dog with Callable with Feedable
d: Dog with Callable with Feedable = $anon$1@1bca486

scala> d
res5: Dog with Callable with Feedable = $anon$1@1bca486

scala> d.call
Comes to you

When you've developed Java for some time and adhere to the usage of interfaces for roles, you surely have tripped over the problem that one of your methods expects a parameter object to implement two interfaces (sometimes this is a sign that the method does too much) and you resorted to adding an object twice to the method signature:

public void callAndFeed(Callable c, Feedable f) { 
   c.call();
   f.feed();
}

callAndFeed(dog,dog);

The call with twice the dog really does look ugly. And you get into shallow water semantically. Does the method call the two methods on two objects? Shouldn't it call them on one method after each other?

Update: As Daniel pointed out, in Java one can write:

public  void callAndFeed(T cf) {
  cf.call();  
  cf.feed();
}

In Scala the method can be expressed nicer with a compound type as the parameter type:

scala> def callAndFeed(d:Callable with Feedable) { 
  d.call(); 
  d.feed(); 
}
callAndFeed: (Callable with Feedable)Unit

scala> callAndFeed(d)
Comes to you
Feeds

Scala glory!