3 ms·
There's a reason I used the word "problem" and not "bug" in my original post. In fact every time I found myself writing "bug", I deleted it and wrote "problem"
by feoren 3y ago
There's a reason I used the word "problem" and not "bug" in my original post. In fact every time I found myself writing "bug", I deleted it and wrote "problem" instead. You're thinking very specifically about "bugs": clear spots a codebase that are clearly causing some clear error. That's actually a small percentage of the scope of "problems" that I'm talking about. Problems can be: your idea is bad, your architecture doesn't fit together, your performance is bad, your calculations are wrong, etc. Static typing, when done well, can help prevent many more of these issues than that narrow definition of "bug". Static typing helps you think clearly about your code.
> the marginal cost [of fixing a red squiggly] is approaching zero. But how many percentage of all bugs is that? And what is the cost?
The marginal cost of fixing a red squiggly underline is indeed basically zero for typos, and typos are a class of bugs I'd like my static type system to help me catch; and it does, and dynamic type systems generally don't. So the percentage of typos that become bugs is basically zero, but that's partly because of static typing! When you say "the percentage of all bugs", your definition of "bug" is a-priori excluding things that were caught before they became bugs!
But you can also get a red squiggly underline because you thought some variable was in scope when it's actually not -- that bug could have been caught earlier. The cost of fixing that bug is not near zero: the structure of your program is different between your brain and your code. The easiest bug to fix is the one you never write in the first place.
Or you get a red squiggly because you thought you could pass an object of type X into a method you're relying on, but you actually can't. Dynamic typing will not help you with this, and the cost of fixing that bug is not zero: again, your assumptions about how your program is fitting together are incorrect. I'd much rather realize that I can't use a method in exactly the way I thought right at the moment of typing it than later during test time. The latter requires writing and maintaining a test in order to catch a problem late that I could have caught early with no test.
> And why stop at static typing? Why don't you run ALL your code through Property Based Testing AND Mutation Testing 100% before shipping?
I directly addressed the subject of testing in my original post. Static typing allows me to write many fewer tests than dynamic typing.
> If the cost is a trillion dollars in programmer time to find a bug that takes 1 second to fix in production at a cost of a few dollars of programmer time, by definition it was NOT worth it.
I just don't understand this hypothetical. Why would it ever take a trillion dollars to prevent a bug that takes 1 second to fix in production? This just doesn't jive with any developer experience I've ever heard about, any example I've ever read about, or anything I can even imagine.
You seem to be operating under the assumption that introducing static typing makes you slower at programming, but we're claiming it's worth it. No, that's not my claim. My claim is that above some level of program complexity, static typing makes you strictly faster at programming, full stop. That level of program complexity may not be your internal server or whatever, but it definitely is most production-grade software out there.
> It's ALWAYS a tradeoff. Of course it is. Everything is. It's maddening to me that people refuse to see this when it's so blatantly obvious.
This is generally true in engineering, but not always. It is actually possible to simply advance the discipline. When you're building a suspension bridge, there's a tradeoff between Stainless Steel and High-Carbon Steel, but there's not a tradeoff between Steel and Popsicle Sticks. Unless, of course, you're building a toy or a proof of concept. Dynamic typing is fine for toys and proofs of concepts; nobody is disputing that. Professional engineers don't spend most of their time discussing the best way to build toys.
- boxed 3y ago> Problems can be: your idea is bad, your architecture doesn't fit together, your performance is bad, your calculations are wrong, etc. Static typing, when done well, can help prevent many more of these issues than that narrow definition of "bug". I don't see how static typing helps with "solving the wrong problem" kind of issues at all. That's what asking deep questions about the business is for. Maaaaybe DDD can do something here, but that's hardly "static typing". > I directly addressed the subject of testing in my original post. Static typing allows me to write many fewer tests than dynamic typing. I noticed here that you didn't make any difference between testing, PBT, MT and proof systems. That's pretty bad. I won't conflate Haskell-style good type systems with C-style horrible type systems, so you shouldn't do the same with testing.
- feoren 3y ago> I don't see how static typing helps with "solving the wrong problem" kind of issues at all. One example is F#'s unit of measure system, which can statically verify dimensional agreement of arithmetic. Another example would be differentiating between "Safe Strings" and "Unsafe Strings" (say, untrusted user input) and statically enforcing which are allowed in which method. They won't tell you that "Facebook for Dogs" is a bad idea, but they may reveal subject-matter errors in the actual requirements themselves. Most test suites wouldn't even catch these errors, because test assertions are generally based on requirements. You could write your own unit-verifier that you run in tests, but then you're just reinventing static typing. In fact it's a common criticism of test suites in dynamically typed languages that they end up poorly reinventing checkers for the guarantees already provided by a decent static type checker. > I noticed here that you didn't make any difference between testing, PBT, MT and proof systems I also didn't differentiate between the Late Middle Ages and the Early Renaissance, because it was off topic. But if you insist: "Property-Based Testing" is a testing pattern, not a different kind of test. Write tests and assertions as appropriate for the thing you're testing. It seems to me that you should have enough understanding of the likely failure scenarios and edge cases of your code that you don't need to be randomly generating inputs, but I can see how it'd be useful. I test all sorts of invariants in my tests. This just doesn't seem like a novel thing to me. "Mutation Testing" is basically testing your testing methodology. Okay. You could also test your bus factor by randomly shutting out one developer for a day each month and seeing how you get on. Maybe good ideas for some companies? If you find yourself trying to develop a completely airtight testing process that will catch 100% of bugs, it's probably because too many bugs are passing your tests. Before you kill yourselves trying to develop an airtight, mathematically-guaranteed strong test system, may I suggest strong static type systems instead? Just let the compiler do it. "Proof systems" are strong static type systems.