4 ms·
There's a correlation between lines of code in a file and bug count. Does the typing outweigh this? If all the time spent writing all those types was spent deb
by hajile 6y ago
There's a correlation between lines of code in a file and bug count. Does the typing outweigh this?
If all the time spent writing all those types was spent debugging, would TS win in actual development time?
If you're writing good unit tests already, why are you running into so many type issues?
If you already have to spend time writing tests, why spend more writing types?
TS types aren't really documentation. For other devs to use your stuff, you need JS Docs to actually explain things. Why write all those types too?
If I'm writing a quick and dirty project, it feels like TS types help a little, but if I'm following best practices on an important project, TS seems like pointless ceremony that slows things even more.
- Vinnl 6y agoI don't have numbers on that, though I think a sibling comment did refer to some. I do have my intuition though. (One day I'm going to keep track of the mistakes TS catchers early for me in a week.) So yes: I think the typing lowers the correlation between lines of code and bug count, and that that outweighs the bugs introduced by the additional lines. (It is similar in that regard to many unit tests, I'd say.) As for unit tests: it's not that I write unit tests first and add types later. The types are written as I code, and they allow me to not write some of the unit tests I'd written otherwise. The upside is that they're easier to write and easier to keep aligned with the code than unit tests. So yes, I still have to spend time writing tests, but less of it than without types, and I save more time than the writing of types costs me. > TS types aren't really documentation. For other devs to use your stuff, you need JS Docs to actually explain things. Why write all those types too? I don't understand what you mean by "write all those types too"? Yes, I still have to write documentation, but just iterating the types is not documentation?
- hajile 6y ago> I don't have numbers on that, though I think a sibling comment did refer to some. I've read that paper in the past and it doesn't actually answer most of the questions I asked above. It only says that X bug existed in some prior git commit. Maybe the dev caught that bug and fixed it before the PR with the commit was merged. Maybe it was caught in code review. Maybe it was theoretically possible within the function, but not within the actual program's use of that function. Maybe the time spent catching those bugs was less than the time it would take to add types. > they allow me to not write some of the unit tests I'd written otherwise A `typeof` assertion or similar is hardly more work and continues to function once the TS types have been stripped. If you expect to interact with the outside world, then you must test against unexpected types. If not, then good docs are still better (see below). Meanwhile, in every real-world TS project I've worked on, you wind up with tons of "template soup" where devs spend tons of time trying to find out which variant makes the type checker happy (or just giving up and slipping in an `any` type) > Yes, I still have to write documentation, but just iterating the types is not documentation? I have a function that takes a string and returns a boolean. What does it do? It's likely that I can pass it any string, but there's a strong possibility that the function can't handle any random string. Does that boolean mean it's a test, that something was successful, or something else? What about side effects? By the time you're done documenting this, when someone glances at the docs, they'll probably not worry very much about the types because they'll be obvious. Why write up a bunch of complex types when a simple, human-readable doc string does types and so much more?
- Vinnl 6y ago> I've read that paper in the past and it doesn't actually answer most of the questions I asked above. OK, well I still don't have the numbers, so we have nothing better than intuition to go on regarding whether it saves time/improves quality or not. > A `typeof` assertion or similar is hardly more work and continues to function once the TS types have been stripped. Yes, and if a typeof assertion is enough, than you don't need any additional syntax in TypeScript either. But a `typeof val === "object"` doesn't tell me a whole lot though. > If you expect to interact with the outside world, then you must test against unexpected types. Agreed. That said, with TypeScript, you only have to do it once, at the point where you interact with the outside world. Once I've verified that e.g. my API response contains all the properties I expect, then I can pass it on to any other function in my code safely. Whereas without TypeScript, I have to be aware at the points where I access those properties that the original source of that value might have been the outside world, and to explicitly verify that it looks as expected. (Or alternatively, I need to still verify the object at the boundary, but have to manually know what properties of it are accessed in the rest of my codebase.) > Meanwhile, in every real-world TS project I've worked on, you wind up with tons of "template soup" where devs spend tons of time trying to find out which variant makes the type checker happy (or just giving up and slipping in an `any` type) Yes, I've seen that happen to. I will not argue that you don't have to learn TypeScript, and that if you do not (want to) put in the effort (or are unable) to do that, it might be counter-productive. In fact, I advised another team in my company to move off of TypeScript for that very reason. > By the time you're done documenting this, when someone glances at the docs, they'll probably not worry very much about the types because they'll be obvious. Why write up a bunch of complex types when a simple, human-readable doc string does types and so much more? Yes, type annotations are not a replacement for documentation. They help your tooling help you. So the reason to write up a bunch of complex types (well, preferably simple types most of the time, of course) is that your tooling can help catch mistakes early - I'm not working off of documentation most of the time. I read it once, refer back to it every now and again, but more than that would be a massive waste of time. My memory is a major asset in being able to quickly type out a bunch of code, but my tooling helps me by removing the need to memorise some things.
- eternalban 6y ago> There's a correlation between lines of code in a file and bug count. Does the typing outweigh this? This is where the famous 'compiler' steps in and catches your typos and errors with "types" at compile time. > If you're writing good unit tests already Compilers are not fragile. Unit tests are fragile. IMO, a significant factor contributing to relation between N (lines of code) and B (expected number of bugs) is human error. Humans write unit-tests. For a fun spin, consider the fact that "more unit-tests" means "more lines of code" and thus "more bugs", but now in your "test suite". [p.s. fragility above refers to the inevitable drifts between the original test-subject (and associated test code) and subsequent changes to the codebase that require updates to the test codebase.]
- hajile 6y ago> This is where the famous 'compiler' steps in and catches your typos and errors with "types" at compile time. The worst bugs aren't types * Syntax errors -- caught by JS runtime * Math errors -- caught by unit tests * Logic errors -- caught by unit tests * Resource errors -- caught by profiling tools and unit tests * Interface errors -- caught by integration tests, documentation, profiling and/or types Of all the major types of programming errors, types only help with the least impactful one, the most obvious one, and the one for which there are other tools available. In the end, the dynamic vs static typing argument has likely been going on since before most HN user's were born (since at least the 50s). I suspect we aren't going to reach a definite conclusion today either.
- eternalban 6y ago> In the end, the dynamic vs static typing argument has likely been going on since before most HN user's were born (since at least the 50s). I suspect we aren't going to reach a definite conclusion today either. Sure thing, but wanted to insert a few facts informing your assertive OP regarding "lines of code" and "unit-tests". p.s. "worst bugs" The worst bugs in my 3 decades career have involved reliance on a broken test-base "verifying" widely shared code in an evolving codebase.
- Vinnl 6y ago> caught by JS runtime This is a major point: "caught by JS runtime" means you're only able to see it when you actually run your application and exercise that code path - or worse, that your user does so. Where the alternative is your editor literally indicating the error the moment you write it, the fix costing you so little time that you can fix them practically subconsciously.
- dahauns 6y ago>If you're writing good unit tests already, why are you running into so many type issues? >If you already have to spend time writing tests, why spend more writing types? Because unit tests and types solve different problems and if you use one as a substitute for the other, you're doing it wrong.
- hajile 6y agoWhat problem is types solving that aren't solved by the combination of function documentation, sanitizing external input, and unit testing?
- root_axis 6y agoTypes define explicit boundaries for application data structures, tests verify software behavior at run-time, they both provide unique benefits that cannot be achieved with either alone, and they in-fact greatly compliment each-other. Types exponentially reduce the set of possible inputs a function can receive, thus greatly reducing the number of tests that need to be written to achieve the same level of safety. Types are also much more precise and less brittle than tests, they establish clear contracts that reflect the actual structure of the program whereas tests provide assurance that some minimum subset of behavior is correct enough for the software to meet the expectations of users. Ultimately, a lack of types is a form of technical debt because the data structures do exist whether you spend the time to formally acknowledge them or not.