February 19th, 2013

glider

Презентация по макросам для BASE (Сан-Франциско, 13 июня 2013)

http://www.meetup.com/Bay-Area-Scala-Enthusiasts/events/105314372/

Пока еще не придумал, о чем именно буду рассказывать. Может, о чем-нибудь философском, может о том, что наколбасим в ближайшее время. Я потом еще планировал на день-два остаться в Bay Area - буду рад развиртуализироваться с уважаемыми френдами!

upd. К сожалению, BASE остался без организатора, который ушел с поста, чтобы заняться другими делами. Поэтому презентация скорее всего не состоится.
glider

макро аннотации

Да, это именно то, о чем вы подумали. На выходных наконец-то пришло озарение на тему того, как отрефакторить текущую архитектуру тайпчекера, чтобы он позволял менять произвольные классы в процессе компиляции. Это означает, что теперь становится возможным тотальное безрассудство вроде следующего:
13:29 ~/Projects/Kepler_introduce-member/sandbox$ cat Macros.scala
import scala.reflect.macros.Context
import language.experimental.macros

object Macros {
  def impl(c: Context)(target: c.Tree, name: c.Tree, code: c.Tree) = {
    import c.universe._
    val Literal(Constant(targetType: Type)) = c.typeCheck(target)
    val Literal(Constant(methodName: String)) = name
    val Function(methodParams, methodBody) = code
    val method = DefDef(NoMods, TermName(methodName), Nil, List(methodParams), TypeTree(), methodBody)
    c.introduceMember(targetType.typeSymbol, method)
    c.literalUnit
  }
  def addMethod(target: _, name: String, code: _) = macro impl
}
13:29 ~/Projects/Kepler_introduce-member/sandbox$ cat Test.scala
class C
object Test extends App {
  Macros.addMethod(classOf[C], "foo", (x: Int) => x + 2)
  println(new C().foo(2))
}
13:29 ~/Projects/Kepler_introduce-member/sandbox$ scalac Macros.scala && scalac Test.scala && scala Test
4
Если вкратце, в scala.reflect.macros.Context я добавил метод introduceMember, который может в любой компилируемый в текущий момент класс (а также трейт или объект) добавить любой мембер (метод, поле, вложенный класс и т.д.). То, что уже скомпилировано в байткод, менять, конечно, не получится - мы ж тут не магией занимаемся, в конце концов. Впрочем, это еще цветочки. В принципе, субботнее озарение позволяет реализовать не только скромное добавление новых мемберов, но и изменение и удаление старых, переколбас компаньонов и так далее.

А теперь вопрос. Вот есть полная свобода метапрограммирования, описанная выше. Если честно, я немного в растерянности. Вообще-то, с этой недели я планировал забить на время на девелопмент и сесть за написание паперы, а оно на выходных само взяло и наколбасилось. Что теперь с этой свободой делать? Что бы вы реализовали в первую очередь?