in scala.util.control.TailCalls.scala (see details below) there is something that looks to my untrained eyes like the introduction of generic type parameters within a match-expression .
The specifiers a1 and b1 are neither mentioned at the enclosing level (which is TailRec[+A]) nor at the method (flatMap[B]) itself.
{Note: The expression c.f(x) becomes a TailRec[b1] and a1 is used as type for x.}
The case, so one can play with it, is extracted to:
My questions: What is the magic behind this ~local type-parameters~? Is this documented and what must the compiler infer about this type-parameters behind the scenes?
Addition: A similar code being 10 years old now tried to solve this without ~local type-parameters~ but solely the type Any for x instead, but that does not compile today (found: (x: Any) required A$1):
It is not matching but rather extracting them, it basically says that c is a Cont[a1, a2] for some types a1 & a2 that are not known. Is just like Foo[_] as a type means Foo[x] forSome { type x }, is “just” an existential type.
I agree regarding the ‘extraction’. What I’ve learned in the meantime due to the documents referenced by @SetTissue: It’s not type-parameters but type-variables.
By the way: the original line from the Scala-library …
I reimplemented something like TailCalls, with the type variables, as an example for a book I wrote (using the original paper by Bjarnason as a starting point). I was pleasantly surprised when switching to Scala 3 that the types variables in the pattern were not needed anymore. If you haven’t, I suggest you try the same code with Scala 3.
Yep, it’s pretty neat without any types at all. The flip side (if there even is one): It’s almost impossible to port this kind of ‘super slick’ code to other statically typed languages. Even if you could express it in the target language, - without tooling in non-trivial cases one would seldomly draw the same conclusions about the involved types as the compiler does. Combine that with additional given and using for added complexity and even a rather experienced developer could get lost pretty quick trying to figure out what is going on.
As often: Pleasure and curse lay close together.
The way I see it, type systems are getting better and inference is getting better. Some languages are ahead and others are catching up, but it’s all moving in the right direction.