Author of Moshi.jl here, I came back 2 years later and I’m surprised how users of Moshi become a lot more than 2 years ago 
I think @ChrisRackauckas and @Mason already cover a wide range of answers, just to clarify a few things
When I wrote Moshi, I was trying to re-architect how MLStyle generates pattern-matching code into a more streamlined, proper compiler instead of ad hoc macros. This naturally leads to many fixes in the edge cases that I have already forgotten. There were some cases that we occasionally hit in MLStyle when we were trying to generate certain patterns or extend the pattern matching system. I don’t really remember the details anymore two years later, but overall, this is just trying to clean up the codebase that MLStyle was written on, which was making it hard to fix.
We kind of explored many different options in Julia, and union splitting seems to be the most reliable and performant solution to this. There were other packages back in the day, like LightSumtypes, Sumtypes, etc., that tried to tackle this problem from different angles. Looking back, I think we kind of have both.
The reason why Moshi’s ADT is in the same package with pattern matching is that our pattern matcher has first-class support for Moshi’s algebraic data type, which is why we don’t always rely on the compiler. That gives us the flexibility to fix certain performance issues across Julia versions when the compiler does not work as expected, or when you just want some more guarantee of how it works.
What I originally was planning for Moshi is something more ambitious.
Because in a static language like Rust, you can only pattern match in a very well-defined pattern; you cannot extend the pattern. But in Julia, it’s possible to extend the pattern dynamically in other packages.
So Moshi can just serve as a framework of pattern matching, instead of a single pattern matching package.
But TLDR: union is the only stable way to get the desired memory layout in Julia. This is why we generate the data type in a union, but we don’t always have to rely on union splitting if you’re using Moshi’s pattern matcher (just to clarify that).