5 ms·
The author is basically wrong on all the points. I used to think like that for decades, but in recent years changed my mind completely. Types lead to less bugs
by beders 3y ago
The author is basically wrong on all the points.
I used to think like that for decades, but in recent years changed my mind completely.
Types lead to less bugs - nope, maybe marginally, but not significantly (see research on that)
Types lead to a better development experience - nope, I have all the definitions and vars in my REPL and so has my IDE. I get completion on all symbols, I can look at call trees, usages, refactor things with confidence, run functions in isolation, replace them, wrap them, all from the REPL and inside my application.
We encode everything in the type system - you can't. You need to do runtime validation.
And good luck untangling your type definitions when your requirements change.
That one is the killer. Static types are premature concretions on the domain data model as you understand them now. They will change and if you are unlucky you will have to support multiple different variations of domain models in the same runtime. Good luck with that. Especially if you use inheritance.
Granted, static types give compilers great leverage to optimize code, but, wouldn't you believe: there are dynamically typed languages that have static types as a la card add-on.
But for many, many use-cases, especially enterprise development, a dynamically typed, immutability-first, functional language pays off dividends in the long run.
The categorical error that is made by many strong typing fans is that they assume you would write the same code - just without types.
Well, you don't.
- jjnoakes 3y ago> I have all the definitions and vars in my REPL and so has my IDE. I get completion on all symbols, I can look at call trees, usages, refactor things with confidence, run functions in isolation, replace them, wrap them, all from the REPL and inside my application This is great, but it only works if you are executing the code that you want to inspect/complete/refactor. In my experience, that just doesn't scale well. > You need to do runtime validation. Type systems don't eliminate this, sure, but when used correctly, they _drastically_ reduce it, which is extremely useful. > And good luck untangling your type definitions when your requirements change. That's the best part - the compiler tells me exactly what I have to fix to get things working again. If I do the same thing in a dynamic language, I have to track things down myself, wait for unit tests to fail (hopefully I have 100% coverage...), and pray that there isn't an escape.
- sanderjd 3y agoIt's an inevitably frustrating debate because everyone has just drawn totally different conclusions from their experiences. For pretty much all your points, my conclusions are the exact opposite. (Except for "You need to do runtime validation" - of course that's true; but you absolutely can avoid doing most runtime validation.) Just to take one somewhat at random: > And good luck untangling your type definitions when your requirements change. I think it is exactly the opposite of the case that static types make it harder to adapt to changing requirements. In every dynamically typed system I've ever worked on, there have been important assumptions about data structures - sometimes checked dynamically in pre- or post- conditions, sometimes only checked in tests, and often simply not checked at all - scattered all around, such that changing requirements necessitated reasoning through the impact of the change on all these implicit assumptions. It was terrifying to make changes. Sure, easy to make a change and start up the application with the new code without a fuss. But to know whether the change broke some obscure codepath I hadn't considered or been aware of? Very difficult! I much prefer a static analysis pass saying, "hey, you changed this interface, did you know this codepath over here relied on that thing you changed?". Static type systems are not the only way to accomplish this, but in my view, they are a much less burdensome way to accomplish it than the level of dynamic validation and testing necessary to do so otherwise. But again, it's just a frustrating debate, because clearly you have the exact opposite experience! So where does it get us? Nowhere really...
- yAak 3y agoI’m half convinced it’s a difference in how people’s brains work. Dynamic typing adds just so much cognitive overhead for me. Well, that and PTSD from digging through so many horrors created with Python and JavaScript.
- mecha_ghidorah 3y ago> And good luck untangling your type definitions when your requirements change. That one is the killer. Static types are premature concretions on the domain data model as you understand them now. They will change and if you are unlucky you will have to support multiple different variations of domain models in the same runtime. Good luck with that. Especially if you use inheritance. I actually found this way easier with static types because with static types I could be significantly more confident about every single place one of those types was used, and look at it and see if it needed changes. This was way fiddlier to do in a dynamically typed environment
- deterministic 3y agoThat might be your experience but not mine. I believe there is no right choice for everybody. So pick what works for you and move on.