Union Types and Option Types

12 points by nutmeg


interlandi

I have nothing of significance to add other than that I really like this:

var file = File.open(filename)...

it just picks the first type of an union, Error|File in the example above.

I wish Zig had gone with it instead of a special case magic integer machine.

andyferris

Yes. I think union types work OK for option and maybe result types, with some built-in language features (syntax sugar).

Sum types with separate names (tags) and payloads seem to work better for anything more complex or programmable by the user. There's a nice duality between structs (products) with named fields and sum types with named variants, and programming with bare unions never works out quite so nicely.

You then need to know whether you invest in subtyping (and the (A | B) | C == A | B | C question) or not. For a language that wants to be as small as possible I can see just supporting options and maybe result/error values might be pragmatic.

(Zig seems to have language features for options (or null pointers at least) and for errors, as well as proper sum types with payloads. I tend to agree with Richard Feldman that Roc's error model using sum types and automated union merging/subtyping is simpler to reason about, and that tag literals are what make all this ergonomic).

foonathan

If you don't have nested unions and option types are sugar for | Nothing, do yon also not have options of options?

heavyrain266

Odin has a built-in Maybe(T) that’s a polymorphic union ( nil or T). It’s used rather rarely across the core packages, sometimes in vendor bindings for optional fields etc. Instead of Maybe(T), procedures are utilising multiple returns like (T, bool)