8 ms·
Articles like this bug me. You've given me a list of why types are awesome. Great. Now, tell me what the tradeoff is. Nothing is free in engineering. To get som
by PainfullyNormal 4y ago
Articles like this bug me. You've given me a list of why types are awesome. Great. Now, tell me what the tradeoff is. Nothing is free in engineering. To get something, you have to give up something else. Even grug[0] understands this.
[0]: https://grugbrain.dev/#grug-on-type-systems https://grugbrain.dev/#grug-on-type-systems
- bigyikes 4y agogrug miss big brain benefit for types. Grug says the main benefit is auto completion, I think the real benefit is to making code changes. If I update a type, the compiler will tell me every single location where I need to make a corresponding code change. For grug: change type give red squiggle, make change code good Also, grug makes a good point about the temptations of generics, but I think they’re exaggerating the impact to the speed of development.
- SaltyBackendGuy 4y ago> big brain type system shaman often say type correctness main point type system, but grug note some big brain type system shaman not often ship code. grug suppose code never shipped is correct, in some sense, but not really what grug mean when say correct I forgot about this, thanks for the morning laugh. No such thing as a free lunch.
- marcus_cemes 4y agoThis is brilliant. Just made my day
- arwhatever 4y agoUnderstanding existing code is a big benefit of static types as well. I’m sure one could argue that member names should obviate the need for type annotations. There’s also the distinct possibility that my preceding ~15 years of statically-typed software development have affected how I think about software development in some way. (wink) But I am finding type annotations internet useful while working on a huge application that is about 2 years into adding a gradual typing system, enough so that I usually take time whenever I enter a new code area to add annotations to everything, just to understand what’s going on. My perception is that I invest time to build understanding of the types, and then document what I’ve learned in the form of these type annotations so that future maintainers then gain a quicker understanding without having to do the initial research. At least my non-statistically-significantly-sized team agrees.
- Izkata 4y ago> Understanding existing code is a big benefit of static types as well. At a syntax level perhaps, but not necessarily at a semantic level. This won't apply to everyone, but I've noticed that the more types are relied on, the less my co-workers really understand the code. They're relying on the compiler so much they don't slow down and think through the changes they're making. In one extreme case I saw a guess-change-compile workflow that relied entirely on the compiler doing the work for them.
- floppydisc 4y agoI usually run into issues at the boundaries in the system. Usually moving from primitives into complex types does not account for serialization and deserialization between db and the client. This can be very annoying to work with in something like C#. Usually it ends up resulting in alot more types and a lot more mapping between types. However this has its own benefits, but is very boilerplate-y and is sluggish to work with when your domain changes. Luckily, for C#, https://github.com/SteveDunn/Vogen https://github.com/SteveDunn/Vogen now exists thanks to source code generators which soothes some of the issues.
- hardwaregeek 4y agoSure there are tradeoffs, but I disagree that it’s always so balanced. When people moved from assembly to high level languages presumably there were tradeoffs but in retrospect it’s a pretty clear cut choice. I’m not saying typed languages are as big of a shift as high level languages but it’s possible they are the unequivocal right choice.
- deleted 4y ago[deleted]
- c7b 4y agoDoes that also hold for people doing data science in Jupyter notebooks? They're also programmers, arguably. At this point in the trajectory of software engineering, it's fair to assume that most of the low-hanging fruits have been picked, and solutions that are unequivocally better would have to bring something fundamentally new to the table (which types are not at all). Most solutions will be picking a particular point on a trade-off isocurve. Apart from that, it's always fair to ask someone who's strongly proposing something what the downsides are.
- jolux 4y ago> Does that also hold for people doing data science in Jupyter notebooks? They're also programmers, arguably. Yeah they’re definitely programmers, but anyone who’s had to maintain and deploy what a data scientist came up with in a notebook will question whether they should really be using types.
- hardwaregeek 4y agoWhy are you sure that all of the low hanging fruits have been picked? The origins of software development are pretty much still within living memory. We’re still extremely new to programming. I wouldn’t be surprised if the field looks completely different in 50 years. As for types, I’m not saying they’re flawless. I’m pointing out that in the transition from assembly to high level languages there were flaws and criticisms that came out. But looking back fifty years, were these flaws and criticisms genuine tradeoffs that kept assembly as a reasonable option for most developers? No, they were not. Now we look back on programmers who insisted on writing assembly as oddities, as niche figures. I cannot say if this will be the case for types, but I won’t rule it out.
- tinyspacewizard 4y agoIf you are happy to use "obj", "System.Object", "Any" etc. in any place where the type-system breaks down then the downsides are very few.
- deleted 4y ago[deleted]
- dkarl 4y agoI don't think every article has to "teach the controversy." This is an article for programmers who don't know the upsides of types. What's more, for a programmer who doesn't get the value of types, the major downsides are already apparent, at least at a basic level. Doesn't this make my code more verbose? Doesn't this get super confusing sometimes? It's an article design to help certain programmers learn a particular thing, not an article meant to satisfy more experienced programmers' desire to see all sides of an argument acknowledged.
- PainfullyNormal 4y ago> What's more, for a programmer who doesn't get the value of types, the major downsides are already apparent, at least at a basic level. How could the downsides possibly be apparent if the upsides are so mysterious they need an article to spell them out? > It's an article design to help certain programmers learn a particular thing Have they actually learned that particular thing if they don't know the tradeoffs they're making? I would argue they haven't. You need to know what you're getting and what you're giving up before you can decide whether something is worth using at all. There are too many articles hyping the upsides of technology X, but nobody asking what the downsides are.
- saagarjha 4y agoHow can the downsides of having to wear a seatbelt possibly be apparent if the upsides are so mysterious they need an article to spell them out? People have a quick aversion to things all the time. Sometimes the actual benefits need to be carefully explained. (“You are statically likely to be in a car crash. Wearing a seatbelt multiplies your chance of living through it.”)
- lapcat 4y agoI think almost everyone understands the benefits of both types and seat belts. The fact that a seat belt keeps you restrained during a crash is pretty intuitively obvious. The idiots who don't wear seat belts either (1) believe they'll beat the statistics, and thus no statistical argument will convince them or (2) value their "freedom" a lot more than they value their own lives. In any case, though, wearing a seat belt or not is a choice one can make independently of all other factors. The cars come with seat belts, it's the same car either way. You click or not, nothing else changes about the car. With types, however, that's not how it works. The tradeoff is... you may have to change your entire programming language, change your IDE, change your frameworks, rewrite existing code, etc. It's not analogous to seat belts at all. Do programmers want the compiler to catch mistakes? Of course they do, in an ideal world. Why wouldn't they? But there are a lot of tradeoffs here that don't exist in the case of seat belts.
- BiteCode_dev 4y agoI must be grug. Just forgot I wrote because dumb brain.
- ironSkillet 4y agoThat grugbrain post was so funny and enjoyable to read, thanks for sharing.
- rowanG077 4y agoOf course there are thing that are free. Assembly is free over machine code which is free over punch cards.
- thefourthchime 4y agoHow have I not seen Grug before, wonderful! Thank you!
- maxbond 4y agoEver so slightly longer compile times. It's pretty close to a free lunch. There are only tradeoffs when we are at the frontier of what's possible with a set of technologies, and so must trade off on something in order to move along that frontier[1]. Many languages aren't operating at that frontier, and adding static typing is free (in the marginal case, ignoring the substantial effort to implement the type system). If you start a greenfield Python project, and you start typing right away and incorporate MyPy into your CI and IDE - it's as close to free as you can get, and the benefit is substantial. [1] Eg, like in this diagram, http://image1.slideserve.com/2488675/production-possibilities-frontier-graphical-form7-n.jpg http://image1.slideserve.com/2488675/production-possibilitie... - we only need to trade off on guns & butter if we're along the frontier (the blue line), if we find ourselves somewhere in the middle we can just make more stuff until we reach the frontier.
- closeparen 4y agoPeople using dynamic languages deeply, especially library and framework authors, regularly write abstract/generic code for which a suitable type declaration would be mind-bendingly difficult in a very sophisticated type system and impossible in a weak one. You can argue that this is ill-advised! But static typing with normally-powered type systems leads to more voluminous and more purpose-specific code. Very powerful type systems are possible, but treated as academic and too difficult to use in the real world. A way this often gets worked around is code generation. Anywhere you have or reach for codegen in a static language, you probably could have used a plain old function in a dynamic language.
- maxbond 4y agoThank you for the thoughtful response; this is something I had failed to consider (since, as you anticipated, I try to avoid creating deep or highly dynamic abstractions), and I do regularly throw in the towel on complex or deeply nested types (either by just omitting them out using a "close enough" type in Python, or by using trait objects in Rust - looking at you, `Map<Chain<RangeInclusive<...>>>`).
- throwaway2037 4y ago
- AnimalMuppet 4y agoThe tradeoff is that I have to explicitly say (and know) what type I'm dealing with at every point in the program. But I'm not sure that's much of a tradeoff. If I don't know what type this thing is, how do I know what operations I can safely do on it? How do I know that I can make it do what I'm trying to do? Or will it blow up at runtime when I do that? I consider "I coded it, it's done, but it might blow up at runtime" to be highly unprofessional. "We covered that with unit tests" is theoretically OK, if you've got 100% test coverage. But you don't, and you never will. Having to say everywhere what the type is gets tedious. Autocomplete (and "auto", for those languages that have it) help a bit here, but only a bit.
- pca006132 4y agoMost modern languages can do type inference and doesn't require explicit type annotation for variables. Hack, even C++ gots auto! For declarations, I think it does make sense to ask for the annotation because it can also serve as documentation. Have you ever tried scala, rust, haskell or typescript?
- zbentley 4y ago> Nothing is free in engineering. To get something, you have to give up something I think this is a dangerous position to take to extremes/as an axiom. Not talking about type systems at all here. The assumption that, given two tools/techniques for accomplishing the same goal, there are always equivalent tradeoffs simply isn't true. Some tools are better than others. That statement usually provokes misinterpretation. It should not be taken to mean: - That some tools are always better than others, in every context. There are situations in 2022 where COBOL is the best choice for new code, and other situations where rewrite-it-in-Rust is the best choice. Problems occur when "tradeoffs of tool A (even if we don't know what they are yet) make it equivalent to tool B" is a core tenet of decision making. - That some tools always have been and/or always will be better than others. Context, expectations, tool capabilities, and available programmer talent pools all change massively over time. - That one tool is better than all the others. Plenty of times there are multiple ways to deliver optimal-given-constraints outcomes, and it comes down to a matter of taste or "just pick something, anything, and let us get to work". Chasing hype and cargo culting leads to poor outcomes; "we should build our two-core app on Kubernetes/write our 2TPS app in Rust" are often justified with "because it's the future" or "because the cool kids are doing it". That's a major bummer. But the opposite extreme is just as bad: assuming that all choices are fundamentally a wash because "to get something, you have to give up something else" is just as methodologically irresponsible as following the hype cycle. Programming isn't alchemy. This kind of bad decisionmaking can lead to dependence on obsolete (unsupported/insecure) tools, difficulty hiring, and, at worst, a culture of "don't talk about Python to me; if you can't freehand it in C you just need to get gud" gatekeeping cruelty. Everything has tradeoffs. That doesn't mean they're equivalent.
- hbrn 4y agoNoone ever claimed they are equivalent. The issue is that people from one side will always downplay the tradeoffs (or pretend they don't exist, like the current author). This exactly how hype and cargo culting happens.
- samatman 4y agoI found this blog post on HN some time this year, and refer to it frequently: https://hirrolot.github.io/posts/why-static-languages-suffer-from-complexity.html https://hirrolot.github.io/posts/why-static-languages-suffer... The key thing the author identifies is the two languages problem. Static types are a second program about the program, and that's great when the second program is simple declarations that keep you from passing one struct when another is expected. But a flexible language needs more than that, and generics end up either Turing Complete or bad in some other way. I'll be mulling this one over in years to come.
- plasticeagle 4y agoFor a while in the codebase I was working on, we had a set of distinct types for different units. You know, a type for meters, another for centimetres, etc etc. We had types for radians, types for degrees. We had conversion functions between them, and type inference when you performed certain operations. The result was a disaster. Not an enormous disaster, but enough of a problem to rip the entire thing out and replace it with plain double-prevision floating points, and sensible variable names, everywhere. Why was this? It was a combination of there being nothing sensible to infer when you, say, multiply an angle and a distance (which happens when you're doing algebra), and everything in the whole codebase needing to be aware of these types. The downside of all these brilliant ideas is dependency. If you define an "EmailAddress" type, as the article suggests, you've got to write the code for it somewhere. Now all your projects are dependent on this library, with all the pain and anguish that versioning and linking/including/whatever the library brings. Before, you depended on nothing but the String type, which is very likely built into your language. When all your code needed to do was pull that email address out of some persistent store (say), and send to some other piece of code, your dependency list was just the Persistence library. But with your fancy EmailAddress type, your dependencies are now much worse. Keep things as simple as they can be. An EmailAddress type is not useful.
- _dain_ 4y ago>The result was a disaster. wtf? metres and centimetres are not different types! they are just different ways of writing same type: Length. radians and degrees are just ways of writing a dimensionless Angle quantity. you made the absolutely elementary mistake of conflating a physical quantity with the unit used to measure it, of course it was a disaster. >nothing sensible to infer when you, say, multiply an angle and a distance angles are dimensionless so they should just be a distinct type of float. there is literally no problem here.
- sixstringtheory 4y agoI can see how it could cause problems if they weren’t using the type system correctly. typedef float cm; typedef float meter: cm a = 1; meter b = 1; if (a == b) { // launch rockets } I’ve done something similar (not including rockets, don’t worry!) in Swift with its typealias feature. Thankfully there is a way to actually force compiler errors in such situations with something like https://github.com/pointfreeco/swift-tagged https://github.com/pointfreeco/swift-tagged