"dynamicznie" Tworzenie klas case z makrami

Chciałbym stworzyć makro wygenerowaną hierarchię zamkniętych klas abstrakcyjnych i case. Był przykład podobny do tego z http://docs.scala-lang.org/overviews/macros/typemacros.html ale jest już przestarzałe. Czy to wciąż możliwe?

Myślę, że byłoby niesamowicie potężne wygenerowanie bezpiecznego typu AST dla określonej gramatyki. Najlepiej z IDE zdolnym rozwiązać wszystkie klasy.

Author: Eugene Burmako, 2014-04-04

1 answers

Najpierw dla jakiejś bezwstydnej autopromocji: Eugene Burmako i wygłaszam wykład na type providers , ściśle powiązany temat, na Scalar 2014 jutro, i zachęcam do spojrzenia na przykładowy projekt , który przygotowaliśmy dla rozmowy, jeśli jesteś zainteresowany tego rodzaju rzeczami.

Podczas gdy makra typu nie są już obsługiwane, można osiągnąć zasadniczo to samo z adnotacje makr z makro paradise (który jest dostępny jako plugin dla Scali 2.10 i 2.11):

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.Context

// Add constructor arguments here.
class expand extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro Expander.expand_impl
}

object Expander {
  def expand_impl(c: Context)(annottees: c.Expr[Any]*) = {
    import c.universe._

    annottees.map(_.tree) match {
      case List(q"trait $name") => c.Expr[Any](
        // Add your own logic here, possibly using arguments on the annotation.
        q"""
          sealed trait $name
          case class Foo(i: Int) extends $name
          case class Bar(s: String) extends $name
          case object Baz extends $name
        """
      )
      // Add validation and error handling here.
    }
  }
}

A następnie:

scala> @expand trait MyADT
defined trait MyADT
defined class Foo
defined class Bar
defined module Baz

Możesz dodać argumenty do adnotacji, które będą dostępne w czasie kompilacji, umożliwiając na przykład analizę zewnętrznego zasobu, którego możesz użyć do wygenerowania implementacji ADT.

Adnotacje Makro są bardzo eksperymentalne, a ich status wciąż wisi w powietrzu-nie ma gwarancji, że będą wysyłane np. ze Scali 2.12. Coś podobnego (choć nie całkiem tak czyste) jest możliwe przy użyciu zwykłych starych makr def i typów strukturalnych-Zobacz przykładowy projekt, podlinkowany powyżej, aby uzyskać więcej szczegółów i niektóre demonstracje. W każdym razie, tego rodzaju mechanizm jest interesujący dla wielu osób, w tym twórców systemu makr Scali, więc nawet jeśli adnotacje makr znikną w pewnym momencie drogi, prawdopodobnie istnieje jakiś sposób, aby osiągnąć to, co tutaj opisałeś.

 22
Author: Travis Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-04 08:27:06