我正在阅读Rust language的文档,我立即对Scala Native感兴趣,思考成熟的库和疯狂优化的算法。我在这里有两个问题
答案 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))
}
但是对非值类型的任何调用都会以某种方式使用该方法的泛型版本。我应该看看生成的代码,但我今晚太懒了......