15

When using the SBT toolchain in Scala, is it possible to write a task that will read a special part of the project's source to generate scala-code at compile time.

Any ideas or even articles/tutorials on this? I am looking for something rather similar to Template Haskell.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Lanbo
  • 15,118
  • 16
  • 70
  • 147

3 Answers3

16

treehugger.scala is a library designed for code generation.

import treehugger.forest._
import definitions._
import treehuggerDSL._

val tree: Tree = Predef_println APPLY LIT("Hello, world!")

println(tree)
println(treeToString(tree))

The above code prints two lines:

Apply(Ident(println),List(Literal(Constant(Hello, world!))))
println("Hello, world!")

treehugger does generate an AST, but non-compliant to scalac's AST.

Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
7

Scala 2.10 has experimental support for macros which alike sophisticated compile-time code generation. See here for more detail.

There are some fun examples on Jason Zaugg's macrocosm git repository, and the SLICK library which is an evolution of the ScalaQuery SQL DSL enabling type-safe database (and collection) queries to be expressed in a LINQ-like way.

And this example, from the expecty assertion library:

import org.expecty.Expecty

case class Person(name: String = "Fred", age: Int = 42) {
  def say(words: String*) = words.mkString(" ")
}

val person = Person()
val expect = new Expecty()

...
val word1 = "ping"
val word2 = "pong"

expect {
  person.say(word1, word2) == "pong pong"
}

Yielding:

java.lang.AssertionError:

person.say(word1, word2) == "pong pong"
|      |   |      |      |
|      |   ping   pong   false
|      ping pong
Person(Fred,42)
Alex Wilson
  • 6,690
  • 27
  • 44
  • When are they expected to be a full feature? – Lanbo Jul 09 '12 at 18:21
  • 1
    I believe the compiler development team are trialling them in 2.10 to see how useful the community find them. The current thinking (as of the last time I was reading the internals mailing list, a few weeks ago) is that they are still leaving open the possibility of only ever having them as experimental. But if community support is very positive I imagine they'll be adopted. There are others on this site who may be able to give you a more definitive answer though. – Alex Wilson Jul 09 '12 at 18:26
  • 1
    They look very much like Template Haskell, and that is widely used. Though for many cases which Scala can serve well without this (like automatic extension for complex classes). But for my purpose, pre-processing assets on compile, it is fitting. – Lanbo Jul 09 '12 at 18:29
5

I did a bit of research recently. Pretty much there are 3 options available:

  1. String templates.
  2. treehugger
  3. Scala Macros

More details here: http://yefremov.net/blog/scala-code-generation/