10 ms·
You're not "moving faster" if a typo is a runtime error and you're not "more productive" if you can't change a function signature without having to grep your co
by alexvitkov 3y ago
You're not "moving faster" if a typo is a runtime error and you're not "more productive" if you can't change a function signature without having to grep your codebase to find all callsites and pray you fixed them all.
Types are good, but as with anything else people take it too far. Making it your life goal to encode all business logic in the type system results in an even more incomprehensible mess than not having types at all. If the type name can't fit on one line in the error message, you've gone too far.
- ranting-moth 3y agoI've seen some insane Typescript type definitions. To be fair, they were defined to work with historic vanilla JS code where so many things could have been stuffed in the poor variable. I'm forever grateful for Typescript, but I wouldn't be surprised to see some of that code in a future research paper titled "The era when types went too far".
- alexvitkov 3y agoI'm mostly fine with bad TS definitions since the types are cosmetic and you can always 'as unknown as whatever' your way out of an insane type definition. If someone nests 5 generics in Rust/C++ you'll have a much worse time.
- sonusario 3y agoDo you still find this true when taking type aliases into account?
- alexvitkov 3y agoIf you're using type aliases or type inference you don't have to type out the long type, but when you get the error that you need `Foo<Bar<Baz<...<&Whatever>>>` but you have `Foo<Bar<Baz<...<&&Whatever>>`, you'll still have to spend 20 minutes dealing with it. I think TS is a special case, since you can "just say no", but in languages with a statically typed runtime/no runtime I try to minimize the amount of <> in a type, even if they're hidden behind a type alias or inference.
- david422 3y ago> I've seen some insane Typescript type definitions. That's just because the code is bad, not because the type is bad. That's literally just the definition of, this code is so bad, let's just not type it.
- digging 3y agoAgreed. I've left a few `any`s or `as unknown as X` in place before and typically leave a comment alongside it. Something to the effect of: "This code is bad and will take too long to refactor. Every time you trace a bug back to this code, please adjust the logic and typing a little bit to prevent the kind of bug you encountered. Eventually we can replace this bad code with good code."
- globular-toast 3y agoThe first time I saw this pattern play out was with CSS vs table layouts. A lot of web devs these days don't remember a time before CSS but, back then, we used to use tables for page layout. This was really an abuse of the `table` element of HTML, which was designed to display tabular data, but it was basically the only way to achieve many layouts like having a side menu bar, for example. Abusing `table` was bad for many reasons, including accessibility. People started to care about the semantic web and remembered that HTML is a markup language for content, not a style language for layout. So people advocated for using CSS for layout and reserving `table` for actual table data. But gradually this rule became both simpler and more ridiculously followed. People started talking about "using divs instead of table". They would look at a page source and if they saw `div` it would get a nod, but if they saw `table` the developer would be relentlessly abused because `table` is old-fashioned. Eventually, of course, someone reinvented tables using divs and CSS. And then people realised the pendulum had swung too far.
- Double_a_92 3y ago> you can't change a function signature without having to grep your codebase to find all callsited and pray you fixed them all. I really wonder how people can actually work like that. Is there some overarching methodology like super strict tests with 100% code coverage or so?
- JonChesterfield 3y agoRegex find and replace across a codebase works fine, especially if the functions aren't overload sets.
- thfuran 3y agoIf you have a tiny codebase maybe, but if there are a couple million lines, it's likely that a pretty significant number of functions are sharing names.
- JonChesterfield 3y agoThose would be the overload sets
- alexvitkov 3y agoThe "pray you fixed them all" refers to the fact that you can't really for sure since someone can do foo[`asdf{some expression returning string}`](args) and then good luck catching that call when searching for say `asdf123`. This looks insane when I describe it like that, but you actually see it more often in JS than you'd imagine, and sometimes it may even look justifiable.
- emerongi 3y agoTools like https://comby.dev/ https://comby.dev/ help with the refactoring itself, but I'm never really 100% confident.
- globular-toast 3y ago> You're not "moving faster" if a typo is a runtime error and you're not "more productive" if you can't change a function signature without having to grep your codebase to find all callsites and pray you fixed them all. I don't see how either of these things relate to type discussions. A typo can certainly lead to incorrect code in the most strongly typed, staticest language there is (otherwise, what the hell is writing code even for?) What's worse: a runtime error or no error that produces the wrong result? Running a Python project might be quicker than compiling a C++ project. Dynamically typed languages can do better than grepping for function calls.
- alexvitkov 3y ago> A typo can certainly lead to incorrect code in the most strongly typed, staticest language there is Yes but the >99% of possible typos (and nearly 100% of typos in identifier names) will be caught by the compiler. That's good enough for me to say "static typing helps with typos". > What's worse: a runtime error or no error that produces the wrong result From most bad to least bad: 1. No error, wrong behavior 2. Runtime error 3. Compile error 4. Red squiggly line telling you "this is bad" before you even compile > Running a Python project might be quicker than compiling a C++ project Yes, C++ is an insane language. You can have large C++ projects that compile fast, but you have to spend a non-zero amount of engineering effort. Generally "avoid templates" and "write the code in .cpp files, not headers" will ensure that you won't have hour-long compiles. This is a problem with C++, not with type-checking in general. > Dynamically typed languages can do better than grepping for function calls. I'd love to hear how, I was doing quite a bit of JS at my previous job (not TypeScript, couldn't convince them :) and I never found a more reliable way to find callsites/variable usages, than grepping for the function name. And even that is not 100% guarentee, since you can call a function in some pretty insane ways, anObject[`asdf${some string}`] and then good luck finding this callsite when searching for anObject.asdf123
- ReflectedImage 3y agoWhat you are complaining about is completely solved via microservices.
- vonwoodson 3y agoYou know, I‘d always been like “`from pdb import set_trace: set_trace()` and you can interactively edit. I don’t care what the type is because I can interact with my running program better than a compiler” (followed by intense nerd chortling). You know, until the program is non-trivial: passing data between systems on a queue; using async, threading, and/or multiprocessing; compiled binary critical-performance libraries… and I’m left wishing I’d written the whole thing in Erlang.
- duped 3y ago> if you can't change a function signature without having to grep your codebase to find all callsites Every time I see a developer make this complaint about static typing I wonder what the hell they're doing with their type definitions and architecture where this is actually a problem. > and pray you fixed them all. If this isn't detected for you at compile/build time you're not using static typing
- _dain_ 3y agoThe comment you're replying to is criticizing dynamic typing here, not static typing.
- deleted 3y ago[deleted]