Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code generation with Scala

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.

like image 896
Lanbo Avatar asked Jul 09 '12 18:07

Lanbo


People also ask

What is code generation technique?

In computing, code generation is part of the process chain of a compiler and converts intermediate representation of source code into a form (e.g., machine code) that can be readily executed by the target system. Sophisticated compilers typically perform multiple passes over various intermediate forms.

What is a code generation tool?

A code generator is a tool or resource that generates a particular sort of code or computer programming language.

What is source code Generation?

Source code generation is the process of creating programming code from a UML model. There are great benefits in taking this approach as the source code Packages, Classes and Interfaces are automatically created and elaborated with variables and methods.


2 Answers

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.

like image 72
Eugene Yokota Avatar answered Nov 06 '22 13:11

Eugene Yokota


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)
like image 7
Alex Wilson Avatar answered Nov 06 '22 11:11

Alex Wilson