LAMP
#define getmax(a,b) ((a)>(b)?(a):(b))
getmax(i, j) // ((i)>(j)?(i):(j))
getmax("a", 2) // (("a")>(2)?("a"):(2))inline def max(a: Int, b: Int): Int =
if (a > b) a else b
max(i, j) // if (x > y) x else y
max("a", 2) // error// Scala 3 macro
inline def power(x: D, n: D): Int =
${ powerCode('x, 'n) }
def powerCode(using Ctx)(x: Expr[D], n: Expr[I])(...): Expr[D] =
...// Scala 2 macro
def power(x: D, n: I): D =
macro impl
def impl(c: Ctx)(x: c.Expr[D], n: c.Expr[I]): c.Expr[D] =
...
inline def max(a: Int, b: Int): Int =
if (a > b) a else b
max(x, y)
// becomes
val a = x
val b = y
if (a > b) a else binline def max(a: => Int, inline b: Int): Int =
if (a > b) a else b
max(x, y)
// becomes
def a = x
if (a > y) a else yinline def power(x: Double, inline n: Int): Double =
inline if (n == 0) 1.0
else inline if (n > 0) x * power(x, n - 1)
else error("n was not a know positive integer")
power(f(5), 3)
// becomes
val x = f(5)
x * x * x * 1.0
def log(x: Int): Unit = println("Log Int: " + x)
def log[T](x: T): Unit = println("Log: " + x)
inline def ilog[T](inline x: T): Unit = log[T](x)
ilog(3) // log[Int](3)
class Num(a: Int) {
inline def max(b: Int): Int =
if (a > b) a else b
def a$inline: Int = a
}
num.max(4)
// becomes
val b = 3
if (num.a$inline > b) num.a$inline else bCan we implement or override a method?
trait Num {
def max(n: Int): Int
}
trait Nat extends Num {
inline def max(n: Int): Int = ...
}Can we override an inline method?
trait Num {
inline def max(n: Int): Int = ...
}
trait Nat extends Num {
override def max(n: Int): Int = ...
}Rules
val map1: TreeSet[Int] = setFor[Int]
val map2: HashSet[Int => Int] = setFor[Int => Int]
transparent inline def setFor[T]: Set[T] =
summonFrom {
case ord: Ordering[T] => new TreeSet[T](ord)
case _ => new HashSet[T]
}