Документирование макросов Scala 2.10

Я начну с примера. Вот эквивалент List.fill для кортежей в качестве макроса в 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!"
      )
    }
  }
}

Мы можем использовать этот метод следующим образом:

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

Этот парень странная птица в нескольких отношениях. Во-первых, аргумент arity должен быть целым числом, так как нам нужно использовать его во время компиляции. В предыдущих версиях Scala у метода не было возможности (насколько мне известно) даже определить, является ли один из его аргументов литералом времени компиляции или нет.

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

Итак, как мне задокументировать это? На данный момент я не ожидаю поддержки Scaladoc, но я хотел бы иметь представление о соглашениях или передовых практиках (помимо того, чтобы убедиться, что сообщения об ошибках во время компиляции ясны), которые позволили бы запустить метод макроса — с его потенциально странные требования — менее удивительные для пользователей библиотеки Scala 2.10.

Наиболее зрелые демонстрации новой системы макросов (например, ScalaMock, Slick, остальные перечислены здесь) все еще относительно недокументированы на уровне метода. Будем признательны за любые примеры или указатели, в том числе из других языков с похожими системами макросов.


person Travis Brown    schedule 12.12.2012    source источник
comment
Что касается ScalaMock, как автор, я был бы очень признателен за предложения о том, как я мог бы улучшить документацию. ScalaMock фактически является DSL, поэтому документирование отдельных методов не обязательно имеет большое значение. Я попытался задокументировать DSL в целом здесь: scalamock.org/api /index.html#org.scalamock.package и здесь есть документация по началу работы: paulbutcher.com/2012/10/scalamock3-step-by-step Что я могу добавить, чтобы помочь?   -  person Paul Butcher    schedule 12.12.2012
comment
@PaulButcher: я не хочу критиковать ScalaMock, и я отредактировал ответ, чтобы сделать это более понятным. Я нашел чтение вашего кода чрезвычайно полезным, так как пытался понять макросы Scala, и я думаю, что документация высокого уровня очень понятна.   -  person Travis Brown    schedule 12.12.2012
comment
Без обид. Но я определенно был бы признателен за любые предложения о том, как я мог бы внести улучшения.   -  person Paul Butcher    schedule 12.12.2012


Ответы (1)


Я думаю, что лучший способ задокументировать это — использовать пример кода, как это делал Майлз в своем экспериментальном ветка на основе макросов shapeless.

person retronym    schedule 04.02.2013