Is this what people mean by Enums? I must not have used languages where Enums have those powers. I have often been very confused by statements people make about Enums so that would make some sense.
How do sum types address the problem that the underlying type (int or string or whatever) is totally capable of describing values other than those your code was compiled with? I'm mostly thinking of version skew with something like a dynamic library or plugin, although casting would probably also have the same effect.
Yes, this is generally what people mean when they talk about enums in modern languages.
The in memory and ABI representation of enums/sum types is language dependent.
In Rust, an enum is equivalent to a C union where there's a discriminant value which is an integer of sufficient size to cover all variants (u8 is sufficient for 255 different variants), followed by as many bytes as the largest variant (a tagged union). Mucking around with the underlying bytes to change the discriminant and cause type confusion is UB. All the same strategies you'd take in C for versioning and ensure binary backwards compatibility would apply. When exposing these you would likely want a higher level abstraction/self-describing wire format, if you don't have control over both sides of the ABI boundary.
Other higher level languages do this for you already. I believe Swift is one of those, where it has a COM-like ABI layer that the compiler makes injects transparently to correctly interact with a dynamic library, handling versioning for you.
I am of the opinion that we need a new attempt at a multi-platform, language-agnostic, self-describing ABI, "COM for the modern world". I think some people have talked about using WASM for this.
Keep in mind that the concept (pattern matching, sum types) is not tied to how they are represented (Scala has both, but they are represented different to what I described earlier; IIRC it uses inheritance to represent the variants).
How do sum types address the problem that the underlying type (int or string or whatever) is totally capable of describing values other than those your code was compiled with? I'm mostly thinking of version skew with something like a dynamic library or plugin, although casting would probably also have the same effect.