记录 Scala 2.10 宏 [关闭]

Posted

技术标签:

【中文标题】记录 Scala 2.10 宏 [关闭]【英文标题】:Documenting Scala 2.10 macros [closed] 【发布时间】:2012-11-30 05:13:26 【问题描述】:

我将从一个例子开始。这是 Scala 2.10 中作为宏的元组的 List.fill 等价物:

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 返回类型is a lie——静态返回类型将包括由参数确定的具体元数和元素类型,如上所示。

那么我将如何记录这件事呢?在这一点上,我并不期待 Scaladoc 支持,但我想了解一些约定或最佳实践(不仅仅是确保编译时错误消息清晰),这将使运行到宏方法中——使用它的潜在的奇怪需求——对于 Scala 2.10 库的用户来说并不奇怪。

新宏系统最成熟的演示(例如,ScalaMock、Slick,其他列出的here)在方法级别上仍然相对没有记录。任何示例或指针都将不胜感激,包括来自具有类似宏系统的其他语言的示例或指针。

【问题讨论】:

关于 ScalaMock,作为作者,我非常感谢关于如何改进文档的建议。 ScalaMock 实际上是一种 DSL,因此记录单个方法并不一定意味着什么。我试图在这里记录整个 DSL:scalamock.org/api/index.html#org.scalamock.package 并且这里有入门文档:paulbutcher.com/2012/10/scalamock3-step-by-step 我可以添加什么会有帮助? @PaulButcher:我并不是要批评 ScalaMock,我已经编辑了答案以使其更清楚。我发现阅读您的代码非常有用,因为我一直在尝试理解 Scala 的宏,而且我认为高级文档非常清晰。 没有冒犯。但我绝对会感谢任何和所有关于我可以改进的方式的建议。 【参考方案1】:

我认为记录这些的最佳方式是使用示例代码,正如 Miles 在他的实验性 macro based branch of shapeless 中所做的那样。

【讨论】:

以上是关于记录 Scala 2.10 宏 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse 有宏记录器吗? [关闭]

在 Scala 中设计和并行化 Spark 应用程序的最佳方法 [关闭]

为啥 SBT 的 Scala (2.10) 不包含 Akka?

scala spark(2.10)读取kafka(2.10)示例

将文件记录拆分为修复编号记录[关闭]

Scala 2.10 中的具体泛型