I have a macro impl in which I have a function I want to call recursively for nested behavior. I've simplified a trivial count-down example to show the desired effect:
import scala.quoted.*
import quoted.Quotes
// Desired recursive effect:
//
// println(Boo.miBoo(3)) produces:
//
// Number 3 is added.
// Number 2 is added.
// Number 1 is added.
object Boo:
given StringBuilderToExpr: ToExpr[StringBuilder] with {
def apply(x: StringBuilder)(using Quotes): Expr[StringBuilder] =
'{ new StringBuilder( { ${Expr(x.toString)} } ) }
}
inline def miBoo(n: Int): String = ${ miBooImpl('n) }
def miBooImpl(n: Expr[Int])(using quotes:Quotes): Expr[String] = {
import quotes.reflect.*
def recursiveFn(): Expr[(Int,StringBuilder)=>StringBuilder] = {
'{(i:Int, sb:StringBuilder) =>
val b = sb.append(s"Number $i is added.\n")
if i > 0 then
val fn:(Int,StringBuilder)=>StringBuilder = ??? // How can I make this a recursive call to recursiveFn?
fn(i-1,b)
b
}
}
val fn = recursiveFn()
val sb = Expr(new StringBuilder())
'{
$fn(5, $sb).toString
}
}
recursiveFn() actually builds a function accepting an int and a StringBuilder. I want nested/recursive calls to recursiveFn() inside the '{}.
(I know I can get this output in far easier way--I't the recursive behavior I want to solve. In the real app recursiveFn() does very dynamic/nested things...not just simple output.)