8 ms·
I think there's a bigger issue with the narrative here. Sure, types (and tests) help avoiding bugs, and they are definitely useful in large projects like Airbnb
by franciscop 8y ago
I think there's a bigger issue with the narrative here. Sure, types (and tests) help avoiding bugs, and they are definitely useful in large projects like Airbnb. However, they also add a cost that is always ignored, and it's even taboo to talk about it. You don't want to be labeled as an "anti-good-practice" person.
But for some cases, this cost is tremendously important IMHO:
- Startups: being X% faster at launching your product might mean the difference between life or death for the company. This includes Airbnb back in the day!
- Early libraries: not being forced to use a specific type makes it easier to change your mind midway and experiment. Later when the library API is more stable, sure, feel free to add types. Thinking too structured is dangerous when trying to innovate.
- Personal projects: where it just doesn't matter if it breaks in some situations and having to build a whole babel tower might discourage you from getting started for fun.
As an example, doing "horrible" things I could launch a fullstack prototype in a couple of days, or a decently working prototype in a week. Granted, I would not want to work with that code after 1 month and there would be some bugs, but the ability to get something quick-and-dirty is also very important and something categorically ignored. As an added benefit, this also allows you to iterate quickly, and throw whole pieces of code altogether because you avoid the "sunk cost fallacy" both from yourself and 3rd parties.
Please use types, and tests, and other good practices in principle. But also learn when it's good to break those! I get the chills when I think on someone who blindly believes on only using X for everything and anything.
- bandushrew 8y ago" not being forced to use a specific type makes it easier to change your mind midway and experiment." Is that really true? whether the original declaration is strongly typed or not, its likely that changes to the type will result in code changes needed wherever the value is being used. The only thing that no typings does is make it impossible for the compiler to help you find where it is being used.
- franciscop 8y agoYes, through duck typing. At some parts of my code near the entry point I might not care about what the input "file" is, but later (or the underlying library) for instance might accept both a path or an object for instance. This is specially useful for options that are not used near the entry point, but instead are passed down. If the later implementation changes, you'd have to change the middle implementation as well to accept the new/different types.
- int_19h 8y agoDuck typing is completely orthogonal to dynamic typing - you can have static duck typing. C++ templates are one well-known example, but OCaml's intersection of its OO system with type inference also makes it kinda duck typed - e.g. if you define a function that calls a method on an argument, the type of argument is inferred as "some object that has a method with such-and-such name and types". If you call another method, that also gets added etc. But it's still statically typed - at call site, the actual type of the argument must have those methods, or it won't compile. Or, getting back to C++, we have polymorphic lambdas there now (which are implemented in terms of templates, but with syntactic sugar that makes it all much cleaner): auto f = [&](auto x, auto y) { return x + y; }; cout << f(1, 2); // 3 cout << f("a"s, "b"s); // "ab" cout << f("abcd", 2); // "cd" cout << f(main, true); // compile-time error Again, all statically typed, although the type checking basically consists of substituting the types in the body and checking if the result makes sense. Which is to say, the error messages from such code are very similar to the ones you get in e.g. Python if you have the types wrong, except here the errors are compile-time, not runtime.
- jimbo1qaz 8y agoThe Agg C++ library defines every class as a template, taking duck-typed parameters: - type of Agg object passed into object - type of "algorithm" used (or similar) I read matplotlib's Agg C++ backend. Guessing which Class A could be passed into various template parameters in Class B was miserable because of duck typing. And it also broke "jump to definition". ``` Class B<A> { A a; } this->a.foo(), but you don't know what type a is. ```
- machiaweliczny 8y agoAll languages with structural typing support duck typing out of the box.
- DenisM 8y agoCan you provide an example where static typing slows you down compared to dynamic typing? I've been using static typing for decades and the only problem I can imagine is having to add an object property definition instead of just using it. And I can't imagine this extra operation being a significant drag. Is it for you?
- shabbyrobe 8y agoIt could just be that the devs on a team don't know how to use those tools yet. Having to learn how to use TypeScript effectively while establishing the patterns that underpin a new project would definitely slow you down. Maybe that's a cost you can bear early on, but maybe it isn't.
- franciscop 8y agoFor example, having a compiling system. That is a drag for everyone, but especially for newcomers and people getting started. Edit: can you really not imagine any situation where typescript slows down some team in some situations? :)
- tom_ 8y agoThese people reap the greatest benefit, because they are least familiar with the codebase and get the most out of having the computer check their changes make sense.
- franciscop 8y agoTotally agreed. I'm not saying that they would not get benefits! I'm just saying there's also a cost and that might be the difference from someone continuing learning or giving up.
- tom_ 8y agoI was assuming professional programmers with at least some experience - the article is about the toolchain in use by Airbnb.
- trixie_ 8y agoThere is a cost to not using types - Dealing with bugs at runtime that would of easily been caught by a compiler. Difficulty in understanding your own code base - functions available, parameters on those functions, the properties on the objects passed into those functions. Refactoring - some of the most refactoring you'll do is when quickly iterating on a small application. Refactoring is super error prone, and typing minimizes those errors. As always the typing is optional. So if it is slowing you down or some library doesn't have types, or you just don't need it in a particular case - then just use 'any'. I've experienced typings increase my productivity in even the smallest projects. The compiler is your friend, the typings you need are often minimal and mostly inferred.
- franciscop 8y agoAgreed, I never said the opposite. But you'll agree that the costs of using types are mainly upfront, while the costs of not using them are mainly in the form of debt.
- skohan 8y agoExcept the costs of using types are usually in the form of a learning curve: i.e. when you are learning the type system it's relatively expensive, but once you've mastered it it's just part of your coding practice. When you do run into the rare issue, it's usually east to solve it. By contrast, dynamic typing problems never go away. They're usually because of a faulty assumption, or due to a typo, or they're the cumulative hours you spend trying to figure out what exactly has to be passed into a function since it's not explicitly part of the signature, and the maintainer of the library you're using didn't document it well. In the long term, static typing is much less expensive, and it's not accident that people tend to prefer more types over the course of their career rather than less types.
- tom_ 8y agoThere are endless articles written about this. If it's a taboo, nobody seems to be paying any attention to it.
- fnordsensei 8y agoThe sweet spot would be to not have an all or nothing proposition, but to be able to work with fluidity in the beginning, and then to harden the result later on by adding in various layers of sanity checks, of which typing could be one. It's unsurprising that Airbnb—after having succeeded—find that they could have eliminated some of their current problems by making a trade-off earlier on. A parable: a baker has a shelf of many different flours that she uses to make different kinds of bread. Being the only person in her small bakery, she relies purely on muscle memory and habit to know which flour goes where. She experiments a lot with different mixtures and kinds bread. Later, some breads have turned out to be more popular than others, and she's doing well. She hires a couple more bakers, and now finds that she needs to label the flours, write down recipes for the successful breads, and has to establish procedures and guidelines for restocking. Different people have different habits, and muscle memory transfers poorly from person to person. When she was starting out, she benefited from short feedback loops. The shorter, the better. Later on, the benefits of short feedback loops wouldn't be any diminished, but the need for reproducibility has become much larger than it was at first.
- _the_inflator 8y agoThere is some truth to your point. And now think about using TypeScript, that gives you the edge right from the beginning. :) I can assure you, that you want a somewhat stable software basis when the traction hits your software product. It is extremly hard to fix (dumb) bugs during those times. Certain edge case bugs suddenly become not so edgy bugs due to more customers using your product. For me it is an anti-pattern nowadays not using TypeScript or even React/Angular.
- fergie 8y agoIf HN gold was a thing, I would gild you.
- franciscop 8y agoThanks! I'm considering writing a blog post about rapid prototyping and aggressive refactoring, which sometimes contradicts some of these best practices.
- Vinnl 8y agoI think you're generally right. One thing I can really appreciate from TypeScript, though, is that is strikes a really nice balance in compensating for point 2. If something turns out to be really hard to type, or simply too much work, the `any` type makes it really easy to opt out of typing in a specific location. Once you've settled on the API and code that works, you can introduce the typings anyway. (Although I must say: exactly for those uses where I am expecting to be refactoring soon, I find I feel much safer to experiment knowing that TypeScript will help me with that.) Furthermore, with TypeScript's current popularity, point 3 is starting to be less and less relevant too. When I start a React project, I just run `npx create-react-app --typescript`, and I'm up and running. TypeScript support by default is getting more widespread, which can make it a no-brainer to use in personal projects as well.
- openfuture 8y agoThis is why I'm so bullish on clojurescript! The 'type system' is called spec - so the idea is that you can move fast but once you know some invariants you'd like to keep you can put them in the specification. Having the spec as your type system maintains sanity and gives programmers that are new to the code a high level overview. It just makes so much sense, really feels like having & eating the typing cake.
- krzat 8y agoI'm sure for many people this cost is reversed and they are wasting time in dynamic language for looking up methods or fixing bugs that would not exist in typed code.
- mattmanser 8y agoIf I could give this comment a year's worth of up-votes I would. Dynamic languages slow me down. I have a terrible memory when it comes to method syntax, for example I would still have to look up Javascript's substring syntax every single time even though I have worked with JS for like 12 years. Static typing's ability to supercharge autocomplete is a massive time boost for me.
- skohan 8y agoYes JS is probably the most egregious. After having transitioned mostly to statically-typed languages, it seems positively backwards not to have the types, or even number of arguments specified as part of the signature to a function. I have even had to dig through the source of a library when the author has neglected to document an API well.
- pjmlp 8y ago> Startups: being X% faster at launching your product might mean the difference between life or death for the company. This includes Airbnb back in the day! Developing software since the mid-80's, worked in a couple of startups, never saw a case where using strong typing would be the cause of business failure. > - Personal projects: where it just doesn't matter if it breaks in some situations and having to build a whole babel tower might discourage you from getting started for fun. It is no fun to go back to something that was left hanging 6 months ago and reverse engineer what the code actually does.
- franciscop 8y agoI've seen too many projects fail because they are way over-engineered. A complex pipeline, build system, developers not familiar with the practices, etc. all adds up. Now I do not know how much typescript might add in cost to all of this, but it's definitely part of what I'd consider an over-engineered MVP.
- pjmlp 8y agoYou can equally over-engineer in dynamic languages, don't see how a type system is to blame.
- deleted 8y ago[deleted]
- empath75 8y agoI just switched from python to go, and I’m the most productive I’ve ever been as a programmer, honestly. I don’t think types slow you down, personally.
- hopler 8y agoAirBnB is a copy of ages-old vrbo with modifications. It wasn't a breakneck race to see who could launch code first. Coders overestimate the criticality of code to the success of a non tech business that operates on the web/apps. Airbnb isn't high tech, it's a business with modern business process of automation software.
- woah 8y agoBizarre attitude. Types help you work faster. They eliminate the entire class of “undefined <something>” errors that you usually have wade through when writing js. I’m guessing that you don’t have a lot of experience with modern typed languages.
- skohan 8y agoAs you say I think that perception is largely due to lack of experience with statically typed languages in general, and also maybe lack of experience with projects of non-trivial complexity and/or managing production code. Compile-time errors feel like an unnecessary hindrance when you're not familiar with them, but when you understand that they are replacing much more vexing and difficult runtime errors, you never want to go back.
- asdffdsa 8y agoRight, some compile-time errors for me are like; wow, thank god that didn't happen in a runtime environment
- regularfry 8y ago> You don't want to be labeled as an "anti-good-practice" person. Oh god, so much this. Engineering theatre is a menace.