Closed
Description
The following code is based of the dotty-staging.g8 project.
import scala.quoted._
import scala.quoted.staging.{run, withQuoteContext, Toolbox}
object Main {
given Toolbox = Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = {
val toTheEighth = stagedPower(8)
println("3^8 = " + toTheEighth(3))
}
def stagedPower(n: Int): Double => Double = {
def code(using QuoteContext) = '{ (x: Double) => ${ powerCode(n, 'x) } }
println("The following would not compile:")
println(withQuoteContext(code.show))
run(code)
}
def powerCode(n: Int, x: Expr[Double])(using ctx: QuoteContext): Expr[Double] =
if (n == 1) x
else if (n == 2) '{ $x * $x }
else if (n % 2 == 1) '{ $x * ${ powerCode(n - 1, x) } }
else '{ val y = $x * $x; ${ powerCode(n / 2, 'y) } }
}
It has been slightly trimmed and modified such that powerCode
recursively calls itself twice.
This results in generating two lines starting val y: scala.Double =
.
Output
Running this yields the following output:
The following would not compile:
((x: scala.Double) => {
val y: scala.Double = x.*(x)
val y: scala.Double = y.*(y)
y.*(y)
})
3^8 = 6561.0
Attempting to compile that source code yields an error:
[error] 4 | val y: scala.Double = y.*(y)
[error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error] | y is already defined as value y
Expectation
code.show
should produce a source code representation that compiles.
We can, however, see that the staging works and we get our answer 3^8 = 6561