Collection of Scala Macro goodies (BSD-licensed)
-
Streams (MIGRATED TO ITS OWN REPO) provide a macro and a compiler plugin that optimize streamed collection operations / for comprehensions by rewriting them to equivalent while loops (Scala 2.11.x):
for (i <- 0 to n; ii = i * i; j <- i to n; jj = j * j; if (ii - jj) % 2 == 0; k <- (i + j) to n) yield { (ii, jj, k) }
-
Loops provide a macro that optimizes simple foreach loops on Ranges by rewriting them to equivalent while loops (Scala 2.10.x):
import scalaxy.loops._ for (i <- 0 until 100000000 optimized) { ... }
(special case of / superseeded by Streams below)
-
JSON (ScalaDoc) provides macro-based
json
string interpolation with smart error reporting, compile-time renormalization, deconstruction and more. -
Parano (MIGRATED TO ITS OWN REPO) provides compile-time checks to avoid common naming mistakes (ambiguous or swapped case class field extractor names, ambiguous unnamed param names with same type...)
-
Privacy changes the default member visibily from public to private (unless the
@public
annotation is used) -
Beans (ScalaDoc) are a nifty combination of Dynamics and macros that provide a type-safe eye-candy syntax to set fields of regular Java Beans in a Scala way (without any runtime dependency at all!):
import scalaxy.beans._ new MyBean().set(foo = 10, bar = 12)
-
Fx (ScalaDoc) contains an experimental JavaFX DSL (with no runtime dependency) that makes it easy to build objects and define event handlers:
new Button().set( text = bind { s"Hello, ${textField.getText}" }, onAction = { println("Hello World!") } )
-
Reified (MIGRATED TO ITS OWN REPO) provides a powerful reified values mechanism that deals well with composition and captures of runtime values, allowing for complex ASTs to be generated during runtime for re-compilation or transformation purposes. It preserves the original value that was reified, allowing for flexible mixed usage of runtime value and compile-time AST.
import scalaxy.reified._ def comp(capture1: Int): ReifiedFunction1[Int, Int] = { val capture2 = Seq(10, 20, 30) val f = reified((x: Int) => capture1 + capture2(x)) val g = reified((x: Int) => x * x) g.compose(f) } println("AST: " + comp(10).expr.tree)
-
Obsolete experiments (mostly because of quasiquotes):
-
MacroExtensions provides an extremely simple (and experimental) syntax to define extensions methods as macros:
@scalaxy.extension[Any] def quoted(quote: String): String = quote + self + quote @scalaxy.extension[Int] def copiesOf[T : ClassTag](generator: => T): Array[T] = Array.fill[T](self)(generator) ... println(10.quoted("'")) // macro-expanded to `"'" + 10 + "'"` println(3 copiesOf new Entity) // macro-expanded to `Array.fill(3)(new Entity)`
-
Compilets provide an easy way to express AST rewrites, backed by a compiler plugin and an sbt plugin.
-
Debug (ScalaDoc) provides
assert
,require
andassume
macros that automatically add a useful message to the regular Predef calls. Please prefer Assertions and DiagrammedAssertions from ScalaTest.
-
Discuss
If you have suggestions / questions:
You can also file bugs and enhancement requests here.
Any help (testing, patches, bug reports) will be greatly appreciated!
Hacking
-
Pushing the site with each sub-project's Scaladoc at http://ochafik.github.io/Scalaxy/:
sbt clean sbt "project scalaxy-doc" ghpages-push-site
(you can preview the site with
sbt "project scalaxy-doc" preview-site
) -
Publishing projects on Sonatype OSS Repository + advertise on ls.implicit.ly (assuming correct credentials in
~/.sbt/0.13/sonatype.sbt
):sbt "+ assembly" "+ publish" sbt "project scalaxy" ls-write-version lsync