Renaming "union type" to "custom type"

Hey, Elm 0.19 is out today!

As part of that, I did a bunch of rewrites on the official guide. I spent a while trying to make the presentation of types flow more naturally and emphasize important concepts more clearly. The finished result lives here. (I actually recommend folks reread the new version of the guide because I improved a lot of sections!)

Anyway, as I was writing, I started to find the name “union types” made the presentation less clear.


In general, people use type definitions less than I would expect.

The real point of a type is to model your situation very precisely. To make it impossible to represent invalid things. I wrote the Types as Sets appendix to try to say that in a way that I personally found helpful early on.

So my theory is that the term “union type” only emphasizes the fact that you can put different types together. That is true, but it is a really small part of what a type definition is about!

I am hoping that by saying “custom type” it will be clearer that it is for custom situations. You may not be putting anything together, but you can benefit from a custom type. Richard tested this out in a recent workshop and felt it helped a bit, so I am optimistic about this change.


If you have any stuff online that mentions union types, please update to the term custom types when you get the chance. It’s no huge rush. People have lives and all! And if you are writing something new, definitely use the revised term to match the official guide. That is the term any newcomers will be using, and it’d be best if they do not need a history lesson to know what’s up!


Using custom type instead of union type should avoid a rather common confusion newcomers have with trying to do type Blah = Int | String and being completely confused with the result.
Saying custom type may discourage people from guessing the type declaration syntax and instead encourage them to read the docs.


Maybe you can “enforce” this a bit by adding a keyword as in type custom like there is for type alias

While I’m actually a proponent of less keywords. It might add to the ‘ease and understanding’ of the use of the language.

(sorry for my bad English)

1 Like

I think this is a good change. Custom types definitely sounds less intimidating than union types. In case it’s helpful in choosing explanatory language: when I’m talking to beginners about Elm, I tend to talk about them as “sets of options” or “multiple choice” types or similar. Even though technically there doesn’t have to be more than one “option”, this is the best “make it feel not too technical or complicated” beginner explanation I’ve been able to think of that gives people a basic concept to build from.

1 Like

Granted I’m coming from a background of being comfortable with programming and reading documentation, and I have a cursory understanding of ML…

custom type feels like the ability to make a new basic type. I’m not sure the terminology is going to coerce people into using unions more and perhaps correctly. This feels more like a documentation / examples / guidance problem than a terminology problem.

One strong consideration to make is what people will find when they search for the term. A search for “union type” produces a lot of helpful information including what they look like in other languages, their history, and why you’d use them.

Searching “custom type” on the other hand produces essentially nothing useful or related.

I also see this phrase coming up a lot in the future:
“custom types in elm… they’re like union types in language x”


I also see this phrase coming up a lot in the future:
“custom types in elm… they’re like union types in language x”

“union type” often means something slightly different in other languages. Elm’s union types are “tagged unions” or “discriminated unions”.

When explaining Elm types, I’ve often found myself saying things like “union types in Elm, they’re not like union types in TypeScript”

1 Like

I think you’re going a little extreme with that. Union types in elm are like union types in type script. They’re not exactly like them, but they solve a similar problem and are both unambiguously union types. You can certainly garner a similarity in behavior and usage from knowing one and going to the other.

I think if we really want to help people learn, we should just call them tagged unions, and not simply unions or custom types. Then it’s unambiguous, searchable, and semantically correct.

That’s true but pretty much the most common misunderstanding for newcomers to try to do something like type MyType = Int | String, which you can in TypeScript.
Hence, I think it’s fair to say that it’s something that comes up when explaining Elm types. That’s still true even if, once you understand it better, you realise the TypeScript and Elm versions are achieving the same sort of thing but in different ways.

I guess my argument would be that changing the name to something more ambiguous doesn’t seem like the correct approach. I don’t see “tagged union” as a particularly scary phrase and “custom” doesn’t give me any tools to help myself learn.

Anyway, that’s all I really have to say about that so I probably wont be responding from here on out. I do very much appreciate the discussion though!


It seems to me that if we were going to actually use the technically correct term tagged union than we would have done so already. Elm programmers know the danger of conflating two nearly-identical ideas.

GraphQL has union types, and they are untagged, and you can match on the bare type. Elm types are not available for inspection at runtime.

As far back as C, union means storing different types in the same memory location, and differentiating at runtime.

Ultimately, Evan has more experience teaching Elm to newcomers than anyone (except maybe Richard) so he has some empirical evidence to go by. Most of the people in this thread, including me, are just speculating.


Having talked with many people through work and study, I am all for this change. Many people coming from imperative or object-oriented backgrounds have some difficulty grasping the difference between sum (union) types, product types and how they relate to concepts they know. I definitely think that there is nothing that is lost by calling types created by the type keyword custom types, and a lot of clarity to be gained.

I like this move. Having a shared language for talking about this stuff is important — especially when working across natural languages. I know feathers get ruffled when words like Monad and Functor get removed from our dialect; but it’s important to come to terms. :wink:

Unfortunately “Authorization” and “Authentication” get conflated; Even in code when abbreviated as “Auth”. “Access Control” and “Identity Assurance” would have been more helpful terms. More often “custom” is more helpful a term than “union”.

In the end, “A rose by any other name would smell as sweet”…

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.