Usefulness of explicitly-typed self references in the Cake Pattern

Viewed 1147

It seems that the most common use of Scala's explicitly-typed self references is in the "Cake pattern," in which a module's dependencies are declared like:

class Foo { this: A with B with C =>
  // ...
}

In general, ignoring the cake pattern for a moment, A, B and C can refer to any type-level thing, such as a type parameter:

class Outer[A, B, C] {
  class Inner { this: A with B with C =>
    // ...
  }
}

... or an abstract type member:

class Outer {
  type A
  type B
  type C
  class Inner { this: A with B with C =>
    // ...
  }
}

In neither of these cases could we have written abstract class Inner extends A with B with C, because A, B and C are not known to be traits. The explicitly-typed self references are necessary here. However, I've only ever seen the cake pattern done with traits:

trait A { def a }
trait B { def b }
trait C { def c }
class Foo { this: A with B with C =>
  // ...
}

In this case, we can instead write abstract class Foo extends A with B with C directly, which if I'm not mistaken has the same meaning. Am I correct? If not, then how do they differ; and if so, why does everybody seem to use the explicitly-typed self reference regardless?

2 Answers
Related