Another tour of Scala

 
 
 
 

Abstract Types

Abstract Types attempts to explain the feature of the same name. This is not about abstract classes.

My Interpretation

There are two uses for this construct. The first, which is more commonly used, is to alias types. The second is to provide an alternative way of parameterizing some of the types of your class

Type Aliasing

Suppose you are creating a hierarchy of domain objects you will persist in a database. These objects will typically provide modification times as java.sql.Date, as that is what one is usually given from a database abstraction layer. This class has two fundamental problems: 1) it clashes with java.util.Date and 2) it doesn’t make clear if you are storing a “day of the year” or a full-on timestamp.

  abstract class AbstractEntity {
    type TimeStamp = java.sql.Date
    type DateStamp = java.sql.Date
    var modified:TimeStamp = _
    var created:TimeStamp = _
  }
  class Person extends AbstractEntity {
    var birthday:DateStamp
  }

Yes, this is typedef. But, notice how clear it can make your code? Also notice how you could decide that you want to use java.util.Date everywhere instead of java.sql.Date and have minimal impact on your code:

  abstract class AbstractEntity {
    type TimeStamp = java.util.Date
    type DateStamp = java.util.Date
    var modified:TimeStamp = _
    var created:TimeStamp = _
  }

Type Parameterization

Along the lines of our database entity domain, a common pattern in Java enterprise applications is:

 /** something that holds only data and gets persisted
   * in a database using a primary key of unknown type.
   * T is the type of primary key */
  abstract class DatabaseEntity[T] {
    var id:T = _
  }
  class Person extends DatabaseEntity[Int]
  class Website extends DatabaseEntity[String]

Here, we have a root type that is parameterized based upon the type of the database primary key. This plays well with systems like Hibernate, which take a Object (or AnyRef) as an id type, but also allows us typed-access.

The problem here is in the design of these classes. The only reason we know what the type parameter is for is due to the comment. Further, the definition of Person is quite puzzling if you haven’t familiarized yourself with the base class DatabaseEntity.

So, we can use abstract types:

 abstract class DatabaseEntity {
    type ID_TYPE
    var id:ID_TYPE = _
  }
  class Person extends DatabaseEntity {
    type ID_TYPE = Int
  }
  class Website extends DatabaseEntity {
    type ID_TYPE = String
  }

Now, it is very clear what is actually going on. The parameterized type is very obviously allowing us to declare the type of the entity’s identifier.

My Thoughts on this Feature

While there are some “it won’t compile” type problems that this feature may solve, this feature to me seems one clearly aimed at designing more readable code. I don’t know if this would be commonly used in most applications, but it’s certainly handy to have.


Last Updated 08/18/2009 at 11:10:23 PM by davec

blog comments powered by Disqus