Dokumentation von Scala 2.10-Makros [geschlossen]

72

Ich werde mit einem Beispiel beginnen. Hier ist ein Äquivalent List.fillfür Tupel als Makro in Scala 2.10:

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

object TupleExample {
  def fill[A](arity: Int)(a: A): Product = macro fill_impl[A]

  def fill_impl[A](c: Context)(arity: c.Expr[Int])(a: c.Expr[A]) = {
    import c.universe._

    arity.tree match {
      case Literal(Constant(n: Int)) if n < 23 => c.Expr(
        Apply(
          Select(Ident("Tuple" + n.toString), "apply"),
          List.fill(n)(a.tree)
        )
      )
      case _ => c.abort(
        c.enclosingPosition,
        "Desired arity must be a compile-time constant less than 23!"
      )
    }
  }
}

Wir können diese Methode wie folgt verwenden:

scala> TupleExample.fill(3)("hello")
res0: (String, String, String) = (hello,hello,hello)

Dieser Typ ist in vielerlei Hinsicht ein seltsamer Vogel. Erstens muss das arityArgument eine Literal-Ganzzahl sein, da wir es zur Kompilierungszeit verwenden müssen. In früheren Versionen von Scala gab es (soweit ich weiß) keine Möglichkeit für eine Methode, auch nur festzustellen, ob eines ihrer Argumente ein Literal zur Kompilierungszeit war oder nicht.

Zweitens ist der ProductRückgabetyp eine Lüge - der statische Rückgabetyp enthält die spezifische Arität und den Elementtyp, die durch die Argumente bestimmt werden, wie oben gezeigt.

Wie würde ich dieses Ding dokumentieren? Ich erwarte derzeit keine Scaladoc-Unterstützung, möchte aber ein Gefühl für Konventionen oder Best Practices haben (abgesehen davon, dass nur die Fehlermeldungen zur Kompilierungszeit klar sind), die das Ausführen einer Makromethode - mit ihrer potenziell bizarre Anforderungen - weniger überraschend für Benutzer einer Scala 2.10-Bibliothek.

Die ausgereiftesten Demonstrationen des neuen Makrosystems (z. B. ScalaMock , Slick , die anderen hier aufgeführten ) sind auf Methodenebene noch relativ undokumentiert. Alle Beispiele oder Hinweise wären willkommen, auch solche aus anderen Sprachen mit ähnlichen Makrosystemen.

Travis Brown
quelle
12
In Bezug auf ScalaMock als Autor wäre ich sehr dankbar für Vorschläge, wie ich die Dokumentation verbessern könnte. ScalaMock ist praktisch ein DSL, daher bedeutet die Dokumentation einzelner Methoden nicht unbedingt viel. Ich habe versucht, das DSL als Ganzes hier zu dokumentieren: scalamock.org/api/index.html#org.scalamock.package und hier wird mit der Dokumentation begonnen: paulbutcher.com/2012/10/scalamock3-step-by-step Was könnte ich hinzufügen, das helfen würde?
Paul Butcher
2
@PaulButcher: Ich möchte ScalaMock nicht kritisieren, und ich habe die Antwort bearbeitet, um dies klarer zu machen. Ich fand das Lesen Ihres Codes äußerst nützlich, da ich versucht habe, die Makros von Scala zu verstehen, und ich denke, dass die Dokumentation auf hoher Ebene sehr klar ist.
Travis Brown
8
Keine Beleidigung genommen. Aber ich würde mich auf jeden Fall über alle Vorschläge freuen, wie ich Verbesserungen vornehmen könnte.
Paul Butcher

Antworten:

1

Ich denke, der beste Weg, diese zu dokumentieren, ist mit Beispielcode, wie es Miles in seinem experimentellen makrobasierten Zweig von Shapeless getan hat .

Retronym
quelle