12 ms·
The only thing that really frustrates me in this discussion is that it's all about how people "feel" and without empiric evidence. The research out there found
by Draiken 3y ago
The only thing that really frustrates me in this discussion is that it's all about how people "feel" and without empiric evidence.
The research out there found no meaningful difference between both styles (unless there's newer research I haven't seen?) and people keep taunting around how their preferred side is undoubtedly the right one.
That's just like, your opinion man.
Personally I like typed languages but the type systems in languages like TypeScript are simply insufficient. You still end up with runtime bugs because you can't actually use those types at runtime. You can't encode a lot of the runtime logic into the type system so you're still manually checking impossibilities everywhere. I find myself even having to create local variables just to make typescript detect an obvious condition.
If a type system could basically remove the need for me to think about runtime bugs, then that's an absolute killer feature that I doubt anyone would argue against. But most languages don't provide that, so you're stuck in this halfway point where you have all this overhead, some benefits, but you still can't 100% trust your types.
As for why there are no meaningful differences in bugs, speed, etc my guess is that it all evens out. Without the type system safety net you are much more likely to test your code and as a result less bugs go in. On the other side people rely too much on the type system that's not good enough and then still end up with the same amount of runtime bugs. On one side you write code faster, but you have to test more, so it also evens out with writing more boilerplate, but with less tests.
I really wanted some hard research on this, but I know it's a hard one.
- dgb23 3y agoExactly my thoughts! The article and many commenters here all talk about programmer ergonomics, productivity and "correctness". The current research shows that these things are neither improved nor weakened by static typing. There are (even recent) papers on comparing typed vs dynamic language with no meaningful results. So basically it's entirely subjective. However there _is_ an actual effect of static typing that can be trivially proven: It enables a programmer to write more efficient code. That should be at the forefront of every discussion around typing discipline, because everything else is just _hot air_ at this point. TypeScript (used in the article) is an example that is _not_ actually strongly typed (it's statically typed but weak) and it doesn't even provide performance and memory layout guarantees, because the types are just comments. So you pay all of the cost of static typing without _any_ of the tangible benefits except documentation. To me it is surprising that we as a technical community completely ignore actual evidence and take our cultural and personal preferences as fact.
- lolinder 3y agoAs other commenters have noted, the evidence here is really weak either way. The controlled studies are all done on college students, and therefore on pretty small short-lived projects. My instincts tell me that while static types may be optional at that scale, they are essential on large commercial projects that last for years, and projects like that are nearly impossible to properly study. Other studies try to compare bug rates between open source projects, but it's hard to be confident in answers gleaned from that kind of observational study. As long as the evidence is so weak, the industry will continue to ignore the research and go with our instincts.
- berkes 3y agoAlso, many of these controlled studies must be taken with a grain of salt. Where the "grain" and the "salt" are the actual details, variables and boundaries of the study. Aside from what you mention -longevity- many other variables will or can influence the outcome. Some extremes: Juniors vs seniors vs mixed teams. Teams with many on-boarding and flying around between projects vs solo devs chugging along for decades on a single codebase. Using frameworks/architectures/design-principles vs yolo-architecture. No tech debt vs responsible tech debt vs crippling tech debt. Agencies who only deliver (i.e. the throw-it-over-the-wall business) vs teams that must maintain; for decades. I'm quite certain that if you are an agency that builds websites for small businesses, wordpress (PHP) and/or react (JS) with bazillion libs just glued together in a "works here" manner will give the highest ROI: you don't have to maintain, upgrade, scale, secure, etc it anyway. Statically typed languages will harm their business (but, I'm convinced, will benefit their customers and our industry at large) because that's: deliver fast&cheap at the cost of all else. I'm certain, because I helped such agencies improve their ROI. "YOLO" turned out to be the most important factor to increase revenue (on short term!). I'm certain that if you are a startup who must onboard new hires because your are rapidly growing, having solid and enforced guidelines and guardrails in place helps a lot. One such guardrail is a typing system. (I'm certain because I've been there, we didn't have any: it took new hires month(s) to have their first PR merged) I'm certain that if you have mixed teams where the seniors can get juniors unstuck, and where seniors can design and build the type systems (bounded domains, value-objects) the architecture (e.g. outside layers/adapters that ensure everything within is guaranteed typed) the juniors are far more productive too. I'm certain because I've been in this role and we saw productivity improve drastically. etc. Such controlled studies are not only hard to do, they need to be read with even more care: did they study a situation or control for my cases at all?
- tasn 3y agoI think most people would agree that types prevent a lot of bugs (and others posted research to support it in the thread), so the question is less about that and more about the subjective reasoning people have to decide the investment is not worth it.
- Draiken 3y ago>I think most people would agree that types prevent a lot of bugs Again, that's not what research shows. Type checking bugs are most definitely not the most common ones and typing doesn't really help with runtime bugs unless it's a strongly typed language. I'm all for types, but after using TypeScript and seeing everyone (including the article) touting it as the solution, it simply isn't all that better than vanilla JS. I did spend countless hours having to wrangle typescript when integrating with third party libraries, searching for types that were not always there, manually extending/creating library types and so on. So no, it's not as clear cut as some say it is. If we want to argue for types, then we should use strongly typed languages that prevent these bugs (if you can manage to create the right types, of course). Examples in TypeScript are simply not going to cut it because that's a horrible example of a typed language. I mean, it's not even a language. Edit: above all, hard research. If there's research for this, why isn't that in the article?
- marwis 3y ago> Again, that's not what research shows. Type checking bugs are most definitely not the most common ones and typing doesn't really help with runtime bugs unless it's a strongly typed language. Can you point to that research?
- patrickthebold 3y agoPerhaps the issue is how people like to solve problems. I'm a huge typescript fan, and I say a lot of the hard work is designing the types. Then the code becomes 'the only thing that makes sense given the types'. There may be some duality at play, where otherwise designing the code is the hard work. And the types become, 'anything that makes sense given the code' And note the switch from 'only' to 'any'. Anyway just hypothesising.
- Draiken 3y agoI had to learn TS because that's the hype today, and went into it after seeing some amazing F# talks on typing. I was amazed at the way they used types to ensure your code was actually correct. I was excited to be able to do that with TS. Then I found out the hard way that none of that works. Basically it's all a lie. You can't use the types in runtime so all that effort you put into the types doesn't actually translate when you want to use the type system to full effect. That was absolutely demoralizing. For me, the white elephant in the room is that the language doesn't really matter all that much. Good developers will write good code and bad developers will write bad code. Good developers might use meaningful types and bad developers will use strings, records and numbers everywhere. Guaranteeing a string is passed and not a number is not gonna prevent many bugs. Guaranteeing a `PhoneNumber` is passed can truly prevent bugs. But that's never the code that you actually see in the wild (even in the article). In the real world, most people can't even use half the type system they claim is so great.
- patrickthebold 3y agoOh, you definitely need something like io-ts, runtypes, zod, there's a few more, to do runtime validation of data. Zod I think is quite popular. Typescript isn't perfect (sound?) So you can still get errors even if things type check, but if you are disciplined using those libraries instead of `as`, the problems are minimal.
- DanielHB 3y agotype MyPolymorphicType = { type: 'A', value: number } | { type: 'B', value: string } There you have types at runtime. If you really want to be pedantic about it you can use classes and instanceof as well In fact even Java removes types at runtime for code that uses generics, so often you need to do something like that as well Types as a static analysis tool is great, types tied to the underlying hardware and memory structures have their values (usually performance benefits). Conflating both together usually leaves you with a very weak (unsafe) type system.
- joekrill 3y ago> The research out there found no meaningful difference between both styles (unless there's newer research I haven't seen?) and people keep taunting around how their preferred side is undoubtedly the right one. Does it, though? I'm not sure the research shows any strong evidence one way or the other. There's a decent review of various studies here, for example: https://danluu.com/empirical-pl/ https://danluu.com/empirical-pl/, that seem to indicate no real conclusion.
- Draiken 3y agoThat was my bad. I meant to say it didn't lean either way because the research is lacking.
- ryandv 3y agoA 2018 study [0] found the following: > Language design does have a significant, but modest effect on software quality. Most notably, it does appear that disallowing type confusion is modestly better than allowing it, and among functional languages, static typing is also somewhat better than dynamic typing. We also find that functional languages are somewhat better than procedural languages. > The languages with the strongest positive coefficients - meaning associated with a greater number of defect fixes are C++, C, and Objective-C, also PHP and Python. On the other hand, Clojure, Haskell, Ruby and Scala all have significant negative coefficients implying that these languages are less likely than average to result in defect fixing commits. > The data indicates that functional languages are better than procedural languages; it suggests that disallowing implicit type conversion is better than allowing it; that static typing is better than dynamic; and that managed memory usage is better than unmanaged. Regarding your comments: > Personally I like typed languages but the type systems in languages like TypeScript are simply insufficient. You still end up with runtime bugs because you can't actually use those types at runtime. That's because TypeScript is not actually strongly typed, it is gradually typed; throw in a single "any" type into your TS and all static guarantees are now off. I agree that TypeScript is insufficient, and point to languages like Rust or Haskell (one of the languages with the lowest defect rate in the study [0]) that actually do offer static guarantees, and where use of untyped "escape hatches" is far less common and/or is far more judiciously applied. > If a type system could basically remove the need for me to think about runtime bugs, then that's an absolute killer feature that I doubt anyone would argue against. But most languages don't provide that Isn't this basically the promise of Haskell, Rust, et al? "If it compiles, it works;" "guaranteed memory safety," etc? [0] https://developers.slashdot.org/story/18/01/01/0242218/which-programming-languages-are-most-prone-to-bugs https://developers.slashdot.org/story/18/01/01/0242218/which...
- dang 3y agoThat study dates from 2014 and was discussed here: A Large-Scale Study of Programming Languages and Code Quality in GitHub (2014) - https://news.ycombinator.com/item?id=15378800 https://news.ycombinator.com/item?id=15378800 - Oct 2017 (66 comments) It's also discussed prominently in Dan Luu's survey, linked to here: https://news.ycombinator.com/item?id=37770719 https://news.ycombinator.com/item?id=37770719
- Hermitian909 3y ago> I really wanted some hard research on this, but I know it's a hard one. I think we'll have to settle for judgment calls. I tried going through some of the research we have on developer productivity a few years back and it's almost all garbage or is only truly applicable to juniors (e.g. when you're new you really benefit from quick feedback time on static errors). The entire space suffers from the fact that good experimental design is impossible to implement with anyone who's not a college student (good luck getting professionals to follow your rules for months) and the curse of dimensionality from the need to disentangle individual variations, type of software development, management style, and a thousand other things to try and draw out a signal. Sadly, many things and life can't be effectively measured.
- d0mine 3y agoIt looks like you think writing your program in the language used to express types will magically remove "runtime bugs" If the language is powerful enough to be able to write ordinary programs, it is powerful enough to produce bugs. Static typing can be effective at catching certain types of bug, not all. It can improve readability sometimes (as a DSL for static unit tests/executable docs). In general, dynamic languages are more agile and you can write more tests easier. Some of the tests you wouldn't need to write in a statically typed language, therefore typing is still useful though not as universally effective as one might believe.
- the_af 3y ago> In general, dynamic languages are more agile and you can write more tests easier. Where's the evidence of this? Be wary of speaking from "common sense", this kind of assertions are deceptive. Maybe statically typed languages are better prototyping languages? (E.g. there's evidence from an early experiment by Paul Hudak that Haskell is actually a good and fast language for prototyping, beating other languages in the experiment!).
- tipiirai 3y agoSomeone here commented that it takes 2.39s for tsc to check types for `console.log('Hello, world!')` [1] (esbuild does not check types). [1]: https://news.ycombinator.com/item?id=37765713 https://news.ycombinator.com/item?id=37765713
- richbell 3y agoThat seems like more of a tooling issue than a reflection of static vs dynamic typing.
- sensanaty 3y agoWhy do people keep using hello world as good examples of anything? I'm not a TS zealot at all, but my work project which is around 2000 TS/Vue files (some of them hundreds of lines long and even breaking into the thousands for a lot of them) manages to get checked in around 3 seconds if there's a cache, and no-cache runs take 10s or so (which also involves actually transpiling the files)
- gmfawcett 3y agoA good resource for research on topics like this is It Will Never Work in Theory: https://neverworkintheory.org/category/#programming-languages https://neverworkintheory.org/category/#programming-language..., https://neverworkintheory.org/category/#types https://neverworkintheory.org/category/#types
- lolinder 3y agoStatic typing is just one slice of Swiss cheese in the pursuit of more reliable software. Yes, it will leave holes like any other technique, which is why you should mix and match them for maximum reliability. But throwing out static typing because it doesn't catch everything is like choosing to leave the door unlocked because the thief could always break a window. If security is really important to you, then you should have bars on the windows in addition to locking the door, not instead.
- littlestymaar 3y ago> The research out there found no meaningful difference between both styles I don't know which research you're thinking about, but if it's the one I've seen, it was empirical analysis and it's worthless because it's subject to survivor bias: whatever the tool you're using to make a program, it's going to be polished just as much as needed for it to fit its market, or it will die, simple as that. If one paradigm lead to much more bugs per written line of code, but you're using it anyway for mission critical stuff, then you'll fix those bugs or fail. On the other hand, if one other paradigm leads to very little bugs compared to others, but you're using it somewhere where reliability doesn't matter, then the few bugs that are there from the beginning will stay there. We can even call that the iron rule of bugs: No matter what tools you use, your code will contain roughly as many bugs as your business can tolerate. The real question is how much effort does it take to achieve the same level, but it's obviously harder to study.
- leecommamichael 3y agoImplicit conversions and multiple “nil” values are the root of your complaints of TypeScript. Dart improves on this, but adds OOP heft. Alas.
- tlavoie 3y agoWould Elm be better there? It's compiling to JS, but not trying to interact with most JS except through specific interfaces.
- nyssos 3y agoElm is better, but I would still recommend against it. - The dictator for life is ambiguously benevolent at best - JS interop is deliberately heavily locked down (good) with no escape hatches (bad) - the compiler release cycle is extremely long: there hasn't even been a minor version released since 2019. - Elm generally picks good defaults, but often makes them impossible to opt out of. For example: it stops you from having implicit effects in your render code by making it impossible to do effectful rendering at all. - It's optimized for making people with no functional programming experience into competent beginners, but the ceiling is low. You will eventually want to jump to something more powerful (Purescript if you need a production-ready compiler, or GHCJS-Haskell if you don't and are feeling adventurous), and when you do the process of swapping out all your libraries is not going to be trivial.
- tlavoie 3y agoGood points, thanks for that. I'm more the old-school, server-side web guy from CGI and servlet days, who happens to like Haskell and related languages now. To that end, I haven't really been doing anything front-end at all, but would like to explore some of that. I'm not even sure that HTMX isn't enough for my needs, so smaller and lighter is my definite preference. I suppose I should try more Elm now, and tinker with Purescript and GHCJS later. If it's all side projects, then I'm not really swapping anything unless it's a choice I'm making to explore new-to-me tech.
- myaccountonhn 3y agoI don’t think you need a “study” for example when Elm has no runtime exceptions. That’s an entire class of bugs plain impossible to express (bar a few contrived examples)
- pharmakom 3y agoElm does have runtime errors. It doesn’t statically analyze division by zero, for example.
- myaccountonhn 3y agoI know that, its what I meant with bar a few contrived examples. In practice you dont really run into them like youd run into runtime issues in Javascript.
- Rapzid 3y agoSome might call divide by zero a classic runtime error.
- insanitybit 3y agoResearch is... complicated. I've seen a lot of research, some shows that types prevent bugs, some doesn't. It's all over the place. If you really want me to I can find you some papers. I've read perhaps two dozen, total, maybe 15+, dunno. The methodologies range from "we scanned github" to "we went to a company and had them solve a problem twice" to "we took a curated group of developers, trained them in two made up languages (one with and one without a type system) and let them attempt to solve a complex business problem" - and the results vary, although my recollection is that they are largely "pro types". The thing is, not everything is going to show up in research results. There are an insane number of variables. How do you account for developer experience? How do you account for experience within a domain? Experience with a language? How do you account for different type systems? Training with type systems? Complexity of the domain? How do you account for one developer being better than another? How do you account for development methodologies? How do you account for people's moods that day? How do you account for effort? It's just not something you can easily research. It's extremely expensive just to generate a small study that tries to control for some of these things. In the meantime, we can use our experience as engineers. We have to make a judgment. We have to form opinions that are biased and subjective.
- deterministic 3y agoIt is pretty much impossible to prove this one way or another. I also believe it varies from person to person. I am personally way more productive using typed languages. However others claim the opposite. And we might all be right.
- fennecfoxy 3y agoThat's because there's no recorded metric for every time a dev working in plaint JS mis-spells a property, or accesses one at the wrong level, calls a function that doesn't exist on that particular version of the library, etc, etc. For the most part, the resistance to Typescript from devs who prefer to write plain Javascript is purely borne out of adding the types being "too much effort to be worth it". Sure you gotta wrestle with the type system now and then but there's often a reason you have to + once it works it usually works very well. Which I find kind of funny bc those devs don't mind putting the effort into writing unit tests, but adding types (think of them as just lower level tests) is somehow an insult to the way they do things. But nah they'll still just rawdog their JS and just make mistakes/misspell stuff now & then as we all do. Let's just hope tests/CI pipeline is enough to pick it up before it gets to prod.