是否可以对Scala Native进行零成本抽象?

时间:2016-10-31 13:33:22

标签: scala-native

我正在阅读Rust language的文档,我立即对Scala Native感兴趣,思考成熟的库和疯狂优化的算法。我在这里有两个问题

  1. 是否可以在Scala Native中使用零成本抽象(类似于Rust)?
  2. 我们可以取消所有Scala Native安装中仍然存在的BOEHM GC,因此可以在嵌入式系统上使用吗?

1 个答案:

答案 0 :(得分:1)

对于Q1:如果通过"零成本抽象"你指的是smth analogue to type classes和compile time dispatch,我会回答这个问题:是的,Scala确实提供了类型类,使用隐式参数和类型类函数的编译时调度来实现(即,识别保存类型类函数的隐式对象)在编译时并使用类型类自动传递给所有函数),并且只是大声推理,因为scala-native它从与标准scalac编译器相同的内部表示中发出llvm,运行时机制应该非常相似,类型也可能像在JVM目标中一样被删除(除非LLVM是超级智能的并且设法重新推断类型并进行自己的调度,但我对此表示怀疑)。

object Main extends App {

  // the typeclass
  trait M[A] {
    def zero: A
    def add(a1: A, a2: A): A
  }

  // the typeclass instance for Boolean
  implicit object BooleanM extends M[Boolean] {
    def zero: Boolean = false
    def add(a1: Boolean, a2: Boolean): Boolean = a1 || a2
  }
  // the typeclass instance for Int
  implicit object IntM extends M[Int] {
    def zero: Int = 0
    def add(a1: Int, a2: Int): Int = {
      require(a1 >= 0 && a2 >=0)
      a1 + a2
    }
  }
  // the typeclass instance for String
  implicit object StringM extends M[String] {
    def zero: String = ""
    def add(a1: String, a2: String): String = a1 + a2
  }

  // a generic method that uses the typeclass
  def justDoingMyThang[A: M](a1: A, a2:A): A = {
    val tc = implicitly[M[A]]
    tc.add(tc.zero, tc.add(a1, a2))
  }

  // the generic method used on types for which it is defined
  println( justDoingMyThang(false, true).toString )
  println( justDoingMyThang(1, 2).toString )
  println( justDoingMyThang("foo", "bar").toString )
}

仍然,使用类型类的泛型方法根本不是专门的,并且在任一类型上调用它都涉及首先使用"隐含地"来获取隐式对象。 (方法调用),然后在隐式对象上调用类型类方法(因此可能会进行一些V表检查?)。

所以,这里没有硬连线函数调用,有一定程度的间接因此成本可能接近于零但不完全为零。

我想我们可以使用@specialized如下来获得更多的编译时间专业化

 def justDoingMyThang[@specialized(Boolean,Int) A: M](a1: A, a2:A): A = {
    val tc = implicitly[M[A]]
    tc.add(tc.zero, tc.add(a1, a2))
  }

但是对非值类型的任何调用都会以某种方式使用该方法的泛型版本。我应该看看生成的代码,但我今晚太懒了......

  • for Q2:我在scala-native的文档中看到了GC配置标记" none"计划包含在v.0.2.x中,所以我们可能希望静态分配和更多嵌入式友好性。