tohle je asi ústřední filosofie silně typového funkcionálního programování "make invalid state unrepresentable"
Tak ono furt platí, že
1) Jak dostanu z vnějšku nějakou hodnot, musím ji validovat -> validátor / parser tam stejně bude
2) Chybu mám zachytit a ošetřit co nejdřív.
3) Věci by měly být řešeny na jednom místě (SRP)
4) Když vím, že tam bude UserID jako int16, nepotřebuju v hloubi aplikace řešit, co se stane, když tam náhodou bude string nebo float
5) Nemusím ukládat a zpracovávat, co nepotřebuju
6) Defenzivní programování - lepší nezkompilovat / dostat warning, než doufat, že je to OK a nic se nerozbije, pokud tam přijde nějaká "podivná" hodnota
7) Stejně dřív nebo pozděj finální typ potřebuju - při prvním výpočtu s daty (Error: Multiply is not defined with strings), při první operaci se stringem nad polem intů,...
Za sebe, pokud si mám vybrat mezi
int fn( int a, str b) {
assert(a > 0);
}
nebo
fn(a, b) {
assert(isInt(a));
assert(isString(b));
assert(a > 0);
}
,
volím první možnost - nejenom že je s tím míň práce, ale 2/3 testů tam zůstanou a po vypnutí asserce v release.
9) Implicitní typy můžou člověku pěkně zavařit.
10) Pokud jde o specifický data, je tady typedef. Pokud ho (zase to SRP) na jednom místě změním, kompilátor vybleje dobrý checklist, co je nekompatibilní a mám to změnit.
11) Pokud člověk potřebuje, netypovaný data protáhne vždycky. Jako string, jako variant, jako obecný pointer, zabalený do třídy, jako union,...
12) Nějak furt nevidím smysl v preferenci stavu, když mám data a nevím, v jakým formátu