2013-05-07

Proof of Concept: Cake Pattern Type Macros

I've been using spare cycles over the last six weeks to try to put together a proof of concept implementation of the type macros I described in my Taming the Cake Pattern blog post from three months ago. I'm happy to say I have a working implementation of the first six macros! It really needs at least one more to be at all useful, and there is plenty of stuff that needs to be fleshed out. But I was very happy to learn that it was actually possible to make this happen. I'm currently compiling three examples and 27 test cases.

Examples

The following three examples compile and produce the output shown. The first is the initial basic example from the blog post:
package congeal.examples.basic
import congeal._
case class U(uName: String)
trait URepository {
def getU(uName: String): Option[U] = Some(U(uName))
}
trait UService extends hasDependency[URepository] {
def getU(uName: String): Option[U] = uRepository.getU(uName)
}
trait Root extends hasPart[URepository] with hasPart[UService]
abstract class Application extends componentApi[Root] {
println(uRepository.getU("testUName"))
println(uService.getU("testUName"))
}
/* outputs
Some(U(testUName))
Some(U(testUName))
*/
object ApplicationTest extends App {
new Application with componentImpl[Root]
}
view raw basic.scala hosted with ❤ by GitHub


The third is one of the core examples from the CBDI blog post, demonstrating hierarchical component organization:

package congeal.examples.layered
import congeal._
case class S(sName: String)
case class T(tName: String)
case class U(uName: String)
trait SRepository {
def getS(sName: String): Option[S] = Some(S(sName))
}
trait TRepository {
def getT(tName: String): Option[T] = Some(T(tName))
}
trait URepository {
def getU(uName: String): Option[U] = Some(U(uName))
}
trait Repository extends
hasPart[SRepository] with
hasPart[TRepository] with
hasPart[URepository]
trait SService extends hasDependency[SRepository] {
def getS(sName: String): Option[S] = sRepository.getS(sName)
}
trait TService extends hasDependency[TRepository] {
def getT(tName: String): Option[T] = tRepository.getT(tName)
}
trait UService extends hasDependency[URepository] {
def getU(uName: String): Option[U] = uRepository.getU(uName)
}
trait Service extends
hasDependency[Repository] with
hasPart[SService] with
hasPart[TService] with
hasPart[UService]
trait Root extends
hasPart[Repository] with
hasPart[Service]
abstract class Application extends componentApi[Root] {
println(sRepository.getS("testSName"))
println(sService.getS("testSName"))
println(tRepository.getT("testTName"))
println(tService.getT("testTName"))
println(uRepository.getU("testUName"))
println(uService.getU("testUName"))
}
/* outputs
Some(S(testSName))
Some(S(testSName))
Some(T(testTName))
Some(T(testTName))
Some(U(testUName))
Some(U(testUName))
*/
object ApplicationTest extends App {
new Application with componentImpl[Root]
}
view raw layered.scala hosted with ❤ by GitHub
The second is a flatted version of that.

Scala Days 2013 Talk

I'm so excited to be going to Scala Days in NYC this June! If you see me there, please do say hello. I'll be presenting there on the Cake Pattern and type macros. And right after Eugene! So exciting. Thanks to all the people at Typesafe for putting this on!

More Monads

If you've been waiting for the next chapter on Monads in Scala, I'm sorry to disappoint! I've been sort of busy working on congeal. And I'm afraid I'll be busy preparing for my Scala Days talk over the next month or so. I do fully intend to get back to it when I get the chance.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.