2

Possible Duplicate:
Scala: Abstract Types vs Generics

Chapter 20.6 'Abstract types' of 'Programming in Scala' explains the use of an abstract type with an example that ends in the following resulting code:

class Food
abstract class Animal {
  type SuitableFood <: Food
  def eat(food: SuitableFood)
}

class Grass extends Food
class Cow extends Animal {
  type SuitableFood = Grass
  override def eat(food: Grass) {}
}

With these definitions, an object of Cow can not eat a fish:

class Fish extends Food
val bessy: Animal = new Cow
bessy eat (new Fish) // Error, type mismatch

After reading this good example about the use of an abstract type, I was wondering, why we do not just use a type parameter instead ?

class Food
abstract class Animal[T <: Food] { 
  def eat(food: T)
}

class Grass extends Food
class Cow extends Animal[Grass] {
  override def eat(food: Grass){}
}

class Fish extends Food
val bessy: Animal[Grass] = new Cow
bessy eat (new Fish) // Also ends in a type mismatch error !

Where is the difference using type parameter instead of an abstract type here ?

Community
  • 1
  • 1
John Threepwood
  • 15,593
  • 27
  • 93
  • 149

1 Answers1

2

Martin Odersky answered that question in this interview.

There have always been two notions of abstraction: parameterization and abstract members. In Java you also have both, but it depends on what you are abstracting over. In Java you have abstract methods, but you can't pass a method as a parameter. You don't have abstract fields, but you can pass a value as a parameter. And similarly you don't have abstract type members, but you can specify a type as a parameter. So in Java you also have all three of these, but there's a distinction about what abstraction principle you can use for what kinds of things. And you could argue that this distinction is fairly arbitrary.

What we did in Scala was try to be more complete and orthogonal. We decided to have the same construction principles for all three sorts of members. So you can have abstract fields as well as value parameters. You can pass methods (or "functions") as parameters, or you can abstract over them. You can specify types as parameters, or you can abstract over them. And what we get conceptually is that we can model one in terms of the other. At least in principle, we can express every sort of parameterization as a form of object-oriented abstraction. So in a sense you could say Scala is a more orthogonal and complete language.

That said, there are some subtle differences between the two, but I can't recall them off the top of my head.

You might also want to have a look at this thread.

Community
  • 1
  • 1
missingfaktor
  • 90,905
  • 62
  • 285
  • 365