w/ proper union types, you just chuck another type, user defined or not, in the method signature and type cast via whatever syntax you have available in the implementation
So you live in a world where there's a fixed number of built-in types hard-coded into your library?
I'm afraid that doesn't cut it in a modern programming context.
that only works if the method knows about all the types that might exist. The reason overloading is necessary is that the person that writes + for your programming language doesn't know all the types that people will want to call + on. As such, you need a way to define new implementations of + when people add new types in the future. This forces you to have some form of overloading.