235 karma · joined April 5, 2016
If there's an important property you want your program to have, and you can express it using the type system, then your compiler can prove it for you. For example, if you have an Employee record with a jobTitle field of type String, then it's hard to be certain you'll never get an invalid jobTitle. If you change that to a type hierarchy with subtypes like Manager, Developer, etc. then once the program compiles, you can be certain that particular error can't happen at run time. As type systems grow more sophisticated, more program properties can be represented as types.
If you want to experience it, perhaps try a language with a really top-notch type system like OCaml or Haskell. Maybe try implementing some kind of transpiler from json to json that uses the type system to describe the valid input. You'll have a collection of parsing functions that detect all the errors, and then the rest of the system can rest assured that the parsed representation is error-free, and you can be certain that you never forgot to handle one of the possible cases. (OCaml, in particular, is very good at this.)
If you try this, and you're human, I think you'll make a few mistakes that get caught by the type checker.
The only difference, really, is that floating point can lull you into believing they have unlimited precision. With integer math, the problem would have been more obvious in the first place.
Ultimately, what I wanted was a way to declare the variants in one place. I didn't want to repeat myself. The only way I could think of declaring them once, and still being able to both produce and consume values of those types, was with a generic visitor interface.
You've done it with a C++ class hierarchy, which has the following properties that the OCaml solution does not:
First, it needs to repeat the components of each variant type three times: once as field declarations, once as constructor arguments, and once as initialization statements in the constructors. The OCaml one (and my Java one) lets you declare the types, fields, and constructors in one line of code.
Second, your code is arranged into classes, which means that adding a new function (say `toString`) requires adding new code in N places, for N types. In OCaml, you'd just write one new function with N variants. (Of course, your code is better if you want to add a new type.)
(Unless, of course, it's written in Java, in which case it's a painstaking tour of the entire programming language, requiring you to learn the concepts behind "class", "public", "static", "void", "main", and arrays, despite never actually using any of those things.)