Java 17 came with a preview of JEP 406. This makes it possible to pattern match based on the type of the scrutinee expression. Looking at the javap -c output of these new type-based switches, I see that they work using a new indy typeSwitch bootstrap method followed by a tableswitch. I suspect this is more efficient than the nested if strategy used by the Scala compiler.
Given that type-based match is quite a bit more widespread in Scala (especially on sealed types), is there any interest/proposal for adopting the (presumably more efficient) compilation strategy that Java uses? Obviously, we’d need to create our own bootstrap method, but I don’t see any reason this wouldn’t be possible…
It could be the case that the bootstrap method actually is generating a while loop underneath that checks the cases
e.g.
static String formatterPatternSwitch(Object o) {
return switch (o) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> o.toString();
};
}
gets translated to the equivalent of
def lookup(obj: Any, cases: Array[Class[_]]): Int = {
val dynCls = obj.getClass
var i = 0
while (i < cases.length) {
if (cases(i).isAssignableFrom(dynCls))
return i
i += 1
}
return cases.length
}
lookup(foo, Array(classOf[jl.Integer], classOf[jl.Long], classOf[jl.Double], classOf[jl.String])) match {
case 0 => String.format("int %d", foo.asInstanceOf[jl.Integer])
case 1 => String.format("long %d", foo.asInstanceOf[jl.Long])
case 2 => String.format("double %f", foo.asInstanceOf[jl.Double])
case 3 => String.format("String %s", foo.asInstanceOf[jl.String])
case _ => foo.toString
}
but maybe that could be made an intrinsic of the vm
I think the current implementation does effectively translate into a while loop, but that’s a hopefully temporary implementation detail. This seems quite similar to the whole indy-fing of string concatenation: by moving the code for handling a high-level construct (match in this case) to the runtime you get
ability to improve the bootstrap method in future Scala releases without breaking binary compatibility