project kepler compile time metaprogramming for scala

17
Scala Macros London, 2012 Eugene Burmako Jan Christopher Vogt

Upload: skills-matter-talks

Post on 22-Nov-2014

1.244 views

Category:

Technology


3 download

DESCRIPTION

Scala Days, Project Kepler: Compile-Time Metaprogramming for Scala

TRANSCRIPT

Page 1: Project kepler compile time metaprogramming for scala

Scala Macros

London, 2012

Eugene Burmako Jan Christopher Vogt

Page 2: Project kepler compile time metaprogramming for scala

Scala Macros

Empower developers to extend the compiler and stay sane!

This enables compile-time: – checks

– processing

– AST transformations

– code generation

– shipping of ASTs to runtime

Page 3: Project kepler compile time metaprogramming for scala

Implementation

Compile-time metaprogramming has long existed in Lisp, so it should be easy to implement, right?

Page 4: Project kepler compile time metaprogramming for scala

Trickiness

Homoiconicity for a language with syntax and types is hard.

Being non-hygienic is evil, being hygienic imposes a complexity tax on the spec.

Need quasiquotations to make AST manipulations bearable. Yet another concept.

Page 5: Project kepler compile time metaprogramming for scala

Beauty

Martin Odersky was suspicious:

“And, we'd need to be convinced that it is beautifully simple, or it won't go into Scala”.

Here is what convinced Martin:

Page 6: Project kepler compile time metaprogramming for scala

Cats

Page 7: Project kepler compile time metaprogramming for scala

The essence

Scala reflection provides a slice of the compiler’s cake. The infrastructure is already there.

Macros are (Tree*, Type*) => Tree functions. Just as simple as that.

Hygiene itself is implemented by a macro. Hence we stay minimalistic and flexible.

Page 8: Project kepler compile time metaprogramming for scala

USE CASE: SLICK

Page 9: Project kepler compile time metaprogramming for scala

SLICK overview

val coffees = Queryable[Coffee]( /* db connection */ )

coffees .filter( c => c.id == 101 )

9

SLICK Queryable frontend

SLICK Query ASTs

SQL

NoSQL

Web services

Scala ASTs

compile time

handed over to runtime (reification) runtime

implemented using macros

Page 10: Project kepler compile time metaprogramming for scala

Macros in SLICK

implemented as a macro that works on argument AST at compile time

val coffees = Queryable[Coffee]( /* db connection */ )

coffees .filter( c => c.id == 101 )

def filter[T]( predicate: T => Boolean ) : Queryable[T] =

macro QueryableMacros.filter[T]

object QueryableMacros{

def filter[T:c.TypeTag] (c: scala.reflect.makro.Context)

(predicate : c.mirror.Expr[T => Boolean]) = …

}

Page 11: Project kepler compile time metaprogramming for scala

A macro body

object QueryableMacros{

def filter[T:c.TypeTag] (c: scala.reflect.makro.Context)

(predicate: c.mirror.Expr[T => Boolean]) = {

val reifiedPredicate =

c.mirror.Expr[ reflect.mirror.Expr[T => Boolean] ](

c.reifyTree( c.reflectMirrorPrefix, projection.tree ) )

c.reify{ translate("filter", ) }

}}

// macro implementation signature

// reify tree (ship to runtime)

// splice into runtime call

splicing

inlined at the call site (macro expansion), translates queries further at runtime, e.g. to SQL

c.prefix.eval, reifiedPredicate.eval

Page 12: Project kepler compile time metaprogramming for scala

Resulting macro expansion

Scala AST

That are macros in SLICK

coffees .filter( c => c.id == 101 )

translate(

"filter",

coffees,

Function( List("c"),

Apply( Select("c", "id"), "==", List(

Literal(Constant(101)))))

)

Page 13: Project kepler compile time metaprogramming for scala

Applications in the compiler

• Removed a compiler phase (LiftCode)

• Made a 80% solution (manifests) a 99% solution (type tags)

• Manifests à la carte – no longer hardcoded in Implicits.scala, it‘s just several macros (you can write your own implementations!)

• Ideas: SourceLocations, SourceContexts, static requirements on the compiler and the compilation environment

Page 14: Project kepler compile time metaprogramming for scala

Applications in the wild

• SLICK

• Macrocosm

• Scalatex

• Expecty

• Scalaxy

• Ideas: procedure typing with arrows, lens generation, ACP DSL, zero-overhead mocks

Page 15: Project kepler compile time metaprogramming for scala

Future work

• Debugging generated code

• Untyped macros

• Type macros

• Macro annotations

• Replacing the compiler with a macro

Page 16: Project kepler compile time metaprogramming for scala

Future work

• Debugging generated code

• Untyped macros

• Type macros

• Macro annotations

• Replacing the compiler with a macro

Come on, just kidding about the last one!

Page 17: Project kepler compile time metaprogramming for scala

Thank you!

Questions and answers

www.scalamacros.org