scala3
scala3 copied to clipboard
Poly functions are not beta reduced
Compiler version
3.2.0
Minimized code
//file a.scala
object betaReduceTest {
inline def macroPolyFun[A](inline arg: A, inline f: [Z] => Z => String): String =
${ macroPolyFunImpl[A]('arg, 'f) }
def macroPolyFunImpl[A: Type](arg: Expr[A], f: Expr[[Z] => Z => String])(using Quotes): Expr[String] =
Expr.betaReduce('{ $f($arg) })
inline def macroFun[A](inline arg: A, inline f: A => String): String =
${ macroFunImpl[A]('arg, 'f) }
def macroFunImpl[A: Type](arg: Expr[A], f: Expr[A => String])(using Quotes): Expr[String] =
Expr.betaReduce('{ $f($arg) })
}
//file b.scala
object betaReduceTest2 {
def test: Unit = {
betaReduceTest.macroPolyFun("foo", [Z] => (arg: Z) => arg.toString)
betaReduceTest.macroFun("foo", arg => arg.toString)
}
}
Decompiled code (with Fernflower)
public void test() {
String var10000 = (String)((Function1)(new 1())).apply("foo");
"foo".toString();
}
Expectation
That both the normal and poly function both beta reduce
You mean, the reducer should do type inference on the argument? That would be a lot to ask!
Not sure I understand. Are you saying it does work in some cases already, and I just did it wrong?
No, not at all. Just that it would be a rather big jump from what we have to this, and something that would tear down some important modularity barriers we have in the implementation.
Managed to work around this for now using value classes and dependent function types instead of poly times. Seems these beta reduce just fine.