Contact Us

Use the form on the right to contact us.

You can edit the text in this area, and change where the contact form on the right submits to, by entering edit mode using the modes on the bottom right. 

           

123 Street Avenue, City Town, 99999

(123) 555-6789

email@address.com

 

You can set your address, phone number, email and site description in the settings tab.
Link to read me page with more information.

Blog

Scala: Traits and Self Types

Mark Thomas

Scala has a few features that, for those who come from a Java or C# background, provide new ways of modelling components and services. I'm going to write a few posts on this, but begin by describing some of the language features that enable them. First up is traits.

What is a trait?

A trait is a collection of fields and methods. Traits can be mixed in to classes to add new features or to modify behaviour. Scala's Ordered trait is a good example of this:

trait Ordered[A] {
  def compare(that: A): Int

  def <  (that: A): Boolean = (this compare that) <  0
  def >  (that: A): Boolean = (this compare that) >  0
  def <= (that: A): Boolean = (this compare that) <= 0
  def >= (that: A): Boolean = (this compare that) >= 0
  def compareTo(that: A): Int = compare(that)
}

By mixing-in Ordered to a new class, then you can get four useful operators by just implementing compare. This is quite powerful, for example:

class Money extends Ordered[Money] with SomeOtherTrait {
  ...

  def compare(that: Money) = {
    ...
  }

As classes can be composed of many traits, this creates a powerful way of building richer classes from simpler ones by layering in capabilities.

Self Types

Ordered can be mixed in to any class; it doesn't depend on any methods or fields of the class that it is mixed in to. Sometimes it's useful for a trait to be able to use the fields or methods of a class it is mixed in to, this can be done by specifying a self type for the trait. A self type can be specified for a class or a trait as follows:

trait SpellChecker { self =>
  ...
}

self within the context of this trait will refer to this. Aliasing this is useful for nested classes or traits where it would otherwise be difficult to access a particular this. The syntax can be extended to specify a lower-bounds on this, when this is done the trait or class can use the features of this lower-bound class, so it can extend or modify its behaviour.

trait SpellChecker { self: RandomAccessSeq[char] =>
  ...
}

The compiler will check that any class in a hierarchy including SpellChecker is or extends RandomAccessSeq[char], so SpellChecker can now use the fields or methods of RandomAccessSeq[char]