> the only solution is to minimize usage of datastructures that have choices in them ("ADTs")
And then what? This only works if you can eliminate the "choice" altogether. Otherwise the "choice" still will be encoded if your system, be it much less obvious.
Think using null/nil instead of an optional type. Now everywhere you use the value (including when passed to other functions) you have to test the value for not being null. With a proper ADT (Maybe, Optional, what you prefer) it is obvious when you have a value and when you don't know.
If you follow a separate-tables approach, you can process the choices separately, and independently, in most cases, simply by iterating over the individual tables. So the choice is indeed largely eliminated. In the majority of cases you're only interested in one of the choices, or are following links that point to instances of a specific known choice. So, no switching code there.
> you have to test the value for not being null
Don't assume possibility of null if it's not a valid value in your data schema. There are so many codebases rotten by never ending null checks. There are no benefits from them, and only drawbacks: They confuse the reader by checking for a situation that should never happen, giving the impression it could be a valid situation. (This is actually a point the OP makes).
Let me exaggerate a little bit. Superfluous null checks are similar to something like
def add(int x, int y) -> int:
return x + y
int z = add(1, 2)
if z != 3:
return 0
else:
return 3
Just because it's "possible" that z is not 3 because there are other values that are also integers, that doesn't mean you have to cover them. Type systems are much less helpful than many FP advocates want you to think, and if you depend too much on them you get a bad, bad codebase (and you deserve it).
The main benefits that type systems bring: 1) they catch your typos early, 2) they support compilation to efficient machine code.
If you use tables and indexes, there are no pointers and no null anyway. Then again, I've used -1 as a sentinel in the past, and there are many more unused negative values available if you need them :-)
How do you reconcile the fact you say type systems aren't useful but also that data schemas are useful. SQL is a typed language and it would probably be insane if it wasn't
I didn't say that! I even said where I think they are useful. I only said that just because a type system might have no facility of expressing that null is not possible (for better or worse) it does not mean you should write a terrible program!
Having structure in your programs is of utmost importance. I just don't think type systems can capture all of the programs' finer points. And if they could, why would we write any program code at all?
Why are relational data schemas a good idea? Because they are simple. They bring clear benefits and rarely any problems for implementation. (I mean, if we constrict ourselves to simply record definitions: They are basically a physical description of your data, so can hardly be a constraint).
And then what? This only works if you can eliminate the "choice" altogether. Otherwise the "choice" still will be encoded if your system, be it much less obvious.
Think using null/nil instead of an optional type. Now everywhere you use the value (including when passed to other functions) you have to test the value for not being null. With a proper ADT (Maybe, Optional, what you prefer) it is obvious when you have a value and when you don't know.