Earlier quoted context omitted.
PL designer here with extensive experience writing compilers in C#, Java, and Scala. Pattern matching is nice but OO will get you most of the way and filling the matching gap is simple. The expression problem is much safer solved using virtual classes (using traits and type members) in scala than with case matching. There are so many OO solutions to this problem it's not funny; I think I had a small argument with Wad…
I've written compilers in C, C++, C#, Delphi, Java, ML and Lisp; targeting x86, x64, JVM and MSIL. I was maintainer of the Delphi front end at Borland / Embarcadero. Pattern matching isn't just nice; you end up with substantially better typechecking, and doesn't need ugly patterns like visitors with their inverted callback control flow, if you want to decouple e.g. type checking or code generation from your AST class…
I'd love to hear more detail about your experience on this point.