Type systems (strong & static) are the best!
I used to be into dynamic languages, and they still have their place.
But for a huge, dozens-of-people project, catching an error at compile time saves hours or even days compared to catching it at runtime. Especially if maintenance overtakes new development.
So use a language with a proper type system, and use it properly!
- Non-nullable types.
- Immutable references and collections separate from mutable ones (or no mutable ones).
- Don't put everything in naked strings, ints and floats. Use Name, Currency, Id<Person>
- If you validate something, change it's type (e.g. SafeString), so that all your downstream code knows it can be trusted. Or/and put anything unsafe in a special type.
- Obviously generics, but I guess every serious static language has that now?
- Tagged union types (enums where each option can take different values of any type) and exhaustivity checks on switch/when/match/... statement. (if you only know Java enums, it's not that).
- Type inference; it's 2018.
There's a lot more like lifetimes or dependent types, but this is not a book (and I'm still learning myself).