We have two variants of the question:
- can we actually move the implementation of pattern matching to libraries? I still think the answer is (very likely to be) no.
- can we pretend that at least
x.matchlooks like a normal method call? Yes if Dotty can be patched for your variant of the syntax — whether you turn it into a match call or just bring the grammars closer…
First, the spec on meta is outdated. And I don’t think pattern matching could be implemented in a Dotty library (macros or not) — if it is, I feel it’s likely a bug.
That’s because pattern matching is supported both in the typechecker, a compiler phase for translation relying on some lower-level nodes (our version of labeled defs — labeled blocks by @sjrd, but the difference shouldn’t concern us), and handling in the phases after translation for the new generated constructs.
While I’m still the youngest Dotty contributor inside EPFL, here’s (part of) the rationale for the new metaprogramming designs as far as I can tell:
- The Dotty typechecker is more robust than Scalac’s, but a few things are still subtle. Among those, preventing cycles is still delicate business — and that’s complexity essential to the Scala spec. To remove it, you’d just have to limit mutual recursion, but that would be a different language.
- Scala 2 whitebox macros are very expressive, but they allow any library to extend the typechecker — which has frozen all its internals. People at Lightbend aren’t maintaining Scalac, they’re maintaining Scalac, macros-paradise, all macros in the community build, and probably more ones. They have to, lest the ecosystem stops working. That’s not sustainable, and has prevented many bigger changes in Scalac. The strong feeling is that we don’t want to repeat that mistake.
- Limiting access to the typechecker has been an explicit design goal for the whole time — the new macros will run after typechecking is done and types are set in stone. More controlled mechanisms are possible (see match types and all that), but nothing like whitebox macros. Even usual compiler plugins are more limited — “research plugins” have fewer limitations but are currently disabled on stable builds.
- There is an in-progress lower-level macro API, but that’s run after typechecking and cannot affect types, and the current design gives you a snapshot of Tasty trees, so I’d even expect no access to labeled blocks. Even then, you don’t have full access to the internals, just restricted access to a controlled subset.
- Since people can be determined, I suspect you could maybe break some of the restrictions of the lower-level macro API by linking against the compiler (unsafely) and using enough reflection, but there’s no support and no binary compatibility guarantees for internal compiler APIs. No scala-reflect with stronger guarantees for half of the internals.
EDIT: To conclude: does that prove you can’t implement pattern matching in a library somehow? Not quite — I haven’t checked if there’s some clever way to encode parts of it via match types and whatnot. But it’s not pattern matching as we have it today.
EDIT2: what has not been discussed are macros before Namer and Typer, that is, simple desugarings. They’d be extremely limited