2012-07-09 22 views
12

Al usar la cadena de herramientas SBT en Scala, es posible escribir una tarea que leerá una parte especial de la fuente del proyecto para generar scala-code en tiempo de compilación.Generación de código con Scala

¿Alguna idea o incluso artículos/tutoriales sobre esto? Estoy buscando algo bastante similar a Template Haskell.

+0

Sí, es posible. Estoy bastante seguro de que hay complementos que lo hacen. ¿Has buscado en la lista de complementos existentes? –

Respuesta

13

treehugger.scala es una biblioteca diseñada para la generación de código.

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

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

println(tree) 
println(treeToString(tree)) 

El código anterior imprime dos líneas:

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

treehugger sí genera un AST, pero no conformes a AST de scalac.

+5

Solo para aclarar: treehugger = generación de código fuente; macros = generación AST. El primero es de baja tecnología, lo que de hecho puede ser una ventaja :) – retronym

+0

@EugeneYokota, ¿está previsto un lanzamiento cercano para Scala 2.10? – jeslg

7

Scala 2.10 tiene soporte experimental para macros que genera generación de código sofisticado en tiempo de compilación. Ver here para más detalles.

Hay algunos ejemplos de la diversión en repositorio git de Jason Zaugg macrocosm, y la biblioteca SLICK que es una evolución del DSL ScalaQuery SQL que permite consultas con seguridad de tipos de base de datos (y la colección) que se expresa de una manera LINQ similares.

Y este ejemplo, de la biblioteca expecty afirmación:

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" 
} 

Rendimiento:

java.lang.AssertionError: 

person.say(word1, word2) == "pong pong" 
|  | |  |  | 
|  | ping pong false 
|  ping pong 
Person(Fred,42) 
+0

¿Cuándo se espera que sean una función completa? – Lanbo

+1

Creo que el equipo de desarrollo del compilador los está probando en 2.10 para ver qué tan útil los encuentra la comunidad. El pensamiento actual (desde la última vez que leí la lista de correo interno, hace algunas semanas) es que todavía están dejando abierta la posibilidad de que solo los tengan como experimentales. Pero si el apoyo de la comunidad es muy positivo, imagino que serán adoptados. Sin embargo, hay otros en este sitio que quizás puedan darle una respuesta más definitiva. –

+1

Se parecen mucho a Template Haskell, y eso es ampliamente usado. Aunque para muchos casos Scala puede funcionar bien sin esto (como la extensión automática para clases complejas). Pero para mi propósito, preprocesar activos en compilación, es apropiado. – Lanbo