
38% of bugs at Airbnb could have been prevented by using types - mbrodersen
https://www.reddit.com/r/typescript/comments/aofcik/38_of_bugs_at_airbnb_could_have_been_prevented_by/
======
hardwaresofton
Relatively recently I've adopted the stance that JS (via V8+NodeJS) has the
best feature set of the "scripting language" tier of interpreted programming
languages, assuming ecosystems for your problem are comparable. The
combination of compile time type-checking support (via Typescript),
parallelism support (recently in v11 w/ worker threads), and built in async IO
paradigms give Node a huge leg up over ruby, python, and perl.

Weirdly enough, JS is the best in my opinion precisely because it does so much
to _not_ be itself. The crazy iteration speed of the JS ecosystem means that
people have done crazy things, but the good stuff has remained. Python
relatively recently added typing[0], and Matz has mentioned that ruby has no
plans to include types in the language proper (though people are working on
it). Perl might be the closest in terms of features since it has thread
support but...

If you enjoyed this hot take, here are a few others you might enjoy:

\- "extensive" unit testing is a poor man's type checker

\- developers that don't think specifying types is helpful are still early in
their careers (those who suffered in the dungeons of Java get some slack)

[0]:
[https://docs.python.org/3/library/typing.html](https://docs.python.org/3/library/typing.html)

~~~
wutbrodo
> developers that don't think specifying types is helpful are still early in
> their careers (those who suffered in the dungeons of Java get some slack)

I'm not high-confidence about this heuristic because 1) the "class label" is a
bit subjective and 2) I don't have a massive sample size, but attitudes toward
typing is one of the best filters for engineer quality I've come across.

(No, I haven't put this in practice in interviews, and I don't ask any related
question. It's just a correlation whose strength I've found really striking)

It's part of a broader class of heuristic I've been noticing recently (again,
still a very preliminary, low-confidence model): things like "lack of
reliable, quality devtools" and "inability to customize interfaces" bother
highly-productive engineers more than less-productive ones, which is what
you'd expect given that inefficient interfaces to their work has a far greater
cost to the former. Along these same lines, if (eg) you're already pretty bad
at understanding complex systems by reading code, you're much less likely to
notice or care about how much more difficult dynamic typing makes this.

I should be clear: this isn't a general-purpose argument against dynamic
typing, and I'm not suggesting that the situation is as simple as "dynamic
typing bad, static good". They both have their strengths and weaknesses, which
make each appropriate for different situations; I ended up picking Python for
a company whose tech org I was responsible for building, and as much as I
personally find engineering in Python to be horribly unpleasant, it was the
right choice for the company given the environment it was in, and I would make
the same choice in the same situation.

I don't think my theory above is particularly novel, and I understand the
self-serving bias that it aligns with, which is part of why it's still such a
low-confidence model. But I've been unable to wrap my head around the number
of nonsensical defenses of dynamic typing I've seen over the last few years,
and this model is the first to offer an explanation: if you can't tap into the
benefits of static typing, of course the accessibility and flexibility of
dynamic typing is going to seem like it far outweighs the foofy, theoretical
benefits that static typing brings to stability and comprehensibility.

~~~
Mirioron
I've never really understood the advantage of dynamic typing. Not having to
specify type to me seems like it's barely an advantage and immediately gets
outweighed by the fact that you don't have compile time type checking (or have
to jump through hoops to get it).

Typing out code tends to be a minor part of writing software, so you don't
gain much there. Furthermore, you don't want to mix types in the same
variables either, because this comes at a cost of performance and complexity.

So, what kind of flexibility do you get from dynamic typing?

~~~
mattmanser
As someone who is very pro-static typing, the big annoyance for me is that
sometimes you have to write a load of boilerplate purely because of the type
system.

It's got a lot better in the last decade, but with the more advanced features
of a language you can find yourself slowed down in a few ways. Maybe by having
to explicitly declare types where you'd normally implicitly declare them. Or
you might have a load of methods that actually throw 'Not Implemented' errors
because you are forced to match a massive interface but it only has to do one
thing (yes, C# has an actual NotImplemented exception because this is so
common).

It's annoying and can interrupt your flow, mean you have to spend a bit of
time searching for the right voodoo code to make it work or you sometimes feel
like you're doing a rain dance just because of the type system.

The other thing is that you're sometimes forced to cast a variable to a type
that you know is already that type, but a method has returned it as an
'object'. It feels really clunky, e.g. event listeners.

~~~
koyote
I'm playing a bit of devil's advocate here, but:

> Or you might have a load of methods that actually throw 'Not Implemented'
> errors because you are forced to match a massive interface but it only has
> to do one thing (yes, C# has an actual NotImplemented exception because this
> is so common).

I would heavily argue that if you encounter such a scenario you are probably
Doing It Wrong® or you were unfortunate enough to inherit/have to work with
some badly designed code.

~~~
dorgo
Yes, but even Java standard libraries throw UnsupportedOperationExceptions. It
is so sad.

Edit: This is exactly the point where a type system betrayes its promises.

~~~
twic
So try and avoid it, like Scala - you have now found yourselves trapped in an
incomprehensible maze of GenTraversable and the like.

------
franciscop
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.

~~~
DenisM
Can 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?

~~~
franciscop
For 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_
These 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
Totally 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_
I was assuming professional programmers with at least some experience - the
article is about the toolchain in use by Airbnb.

------
ajxs
There's been some discussion regarding what these Javascript devs are calling
"The Typescript Tax" ( Presumably the perceived increased cost of development
in a statically typed language ). What greater 'tax' could you possibly
conceive of than a whopping 38% of your development time on an enterprise
product being spent debugging problems caused by type inference/coercion? You
can directly quantify the costs, and it'd probably make management's heads
spin. Surely Node.js is going to be looked back upon as one of the worst
mistakes in the history of 21st century programming.

~~~
josephg
> What greater 'tax' could you possibly conceive of than a whopping 38%

I always find it fascinating looking at the number of lines of code which do
the same thing in different languages. Foundationdb maintains official
bindings in Java, Go, Ruby and Python. The implementations have almost
complete feature parity. They're all maintained by the same team, and as far
as I can tell they all follow best practices in their respective languages.

The sizes (minus comments and blank lines) are[1]:

Python: 4053

Ruby: 2397

Go: 3968

Java: 10077

38% seems like a lot but language expressiveness dominates that. If ruby and
java code were equally difficult to write, you'd be paying a 320% tax moving
from ruby to java for an equivalent program.

I'd love to see a "programming language benchmark game" that only allowed
idiomatic code and compared languages based on code length.

I have no idea what the equivalent size ratio is for javascript and
typescript, but having worked with both, I find typescript projects end up
bigger. I write more typescript because the type system and the tooling
encourages verbose and explicit over terse and clever. (In typescript I end up
with more classes, longer function names and fewer polymorphic higher order
functions).

The typescript tax is real. That said, I believe the defect rate increases by
38% too. Depending on what you're doing the tax might be worth it.

[1] Measured from commit 48d84faa3 using tokei "code lines". Includes JNI
binding code and makefiles, but not documentation

~~~
voidhorse
Is LOC really a significant measurement? Sure you have to type more characters
when working with a strictly typed language, but that takes a couple of
seconds opposed to however long it might take to track down a bug in a massive
enterprise system. Not to mention the type system often forces you to consider
cases you might otherwise overlook when writing dynamic code, hopefully
resulting in better code to begin with—it imposes a bit of discipline.

In my opinion whatever perceived tax a type system entails is
superficial—sure, coming from a dynamic language, having to specify types for
everything seems like taking on an extra chore—but this is just the surface
experience of using a type system—once you’ve used one for a while and
furthermore, had the benefit of _reading_ typed code, you really start to
appreciate having types around and any so called “tax” involved quickly
becomes negligible.

While it might be a “tax” when writing code it’s defintely a boon when reading
code—it’s much faster to look at types to get a handle on an api than it is to
have to dig through and read the actual implementation to try and decipher
what exactly a function expects and returns. When using a Haskell library, for
example, I rarely ever have to read documentation extensively or read
implementations—looking at the types of functions and a brief description (one
sentence) is often sufficient. It takes a couple of seconds. This is the norm
with Haskell code. Contrarily, this is an exceptional case for dynamic
languages—if the documentation isn’t superb you always wind up having to peek
at the implementations at some point—this typically takes longer than glancing
at types and a one sentence description.

Dynamic languages might be more “expressive” from a writers perspective (since
you can leave out types) but they’re far from expressive from a _readers_
perspective—since the writer convenience often puts the onus of sussing thing
out on the reader. In enterprise systems, reader convenience is arguably more
important.

~~~
dmitriid
> Is LOC really a significant measurement?

It is. Number of bugs per line of code is nearly the same across languages. So
the best way to reduce bugs is to reduce LoC

~~~
kurtisc
>Number of bugs per line of code is nearly the same across languages.

Has this been studied?

~~~
dmitriid
I can't give a more complete answer than this SO answer:
[https://softwareengineering.stackexchange.com/a/185684](https://softwareengineering.stackexchange.com/a/185684)
:)

~~~
kurtisc
15-50 being quite a big range and the 2004 publication date of the book (the
comments hint at the reference being earlier) make me reluctant to take it at
face value without looking into it in more depth, especially regarding new
technology like TS, Rust, or enterprise Haskell.

~~~
dmitriid
Read it as 1.5-5% of lines contain bugs.

In the original post AirBnB said 38% of their bugs could be prevented by
static typing. This would bring this to 0.9-3%. Not insignificant, but LoC is
still more important.

------
Alex3917
This is probably a side effect of the type system preventing bugs involving
js's terrible type coercion system. I doubt that Python would have the same
level of bugs preventable by typing, even though it is similarly untyped by
default.

~~~
ggregoire
Even if it doesn’t help to find bugs, static typing is still worth it. I’ve
been fixing some stuff in an existing Python codebase in the last weeks. Most
of the time, when I see a new function, I have no idea what’s the type of its
parameters...

~~~
mrfusion
I like to think of python as a language that’s great for responsible adults.

If everyone is a good engineer and comments things and tests things you’re
going to have a great time. But if you start getting bad practices they’re
going to be multiplied.

~~~
johnfn
Heh. I’d counterargue by asking how many times you’ve heard of someone joining
a new job and looking at the code and saying, “Ah, this is clearly written by
responsible adults!”

~~~
Daishiman
Don't be cynical; I've definitely looked for work in companies that have good
codebases.

------
cryptica
38%? This is bullshit.

Even if that statement were true (which I highly doubt), it is still deceptive
because it does not account for:

\- The 2x to 3x extra time that it will take to complete projects using
TypeScript instead of JavaScript. This is time which could have been spent on
writing more tests.

\- The new bugs which TypeScript introduces that JavaScript did not have
related to things like source mapping issues, outdated DefinitelyTyped
definitions, TypeScript version mismatches, the illusion of runtime type
safely when dealing with parsed JSON data from remote clients, etc... I could
talk at lengths about the problems but there are so many that it would take me
about an hour to write them down.

I have over 1 year of experience with TypeScript in multiple projects and
earlier in my career I used ActionScript 3.0 (also typed ECMAScript) for over
3 years so unlike the people who make the decision to move to TypeScript, I
know what I'm saying. It's going to kill collaboration between projects. I
really hope that browser vendors are smart enough to wait for all the hype to
die before adding native TypeScript runtime in browsers. I'm certain that the
hype will die when people realize that TS is just the same as Java.

During the most difficult time in their existence, companies like AirBnb could
rely on JavaScript to build high quality software. I think that in reality
this move to TypeScript has nothing to do with software quality and everything
to do with keeping their employees busy and degrading their skill level so
that they will not be able to join a competing startup in the future. This is
just a strategy to turn their employees into corporate cattle and keep them
locked into some kind of internal AirBnb private module ecosystem which will
be completely disjoint from any universal module ecosystem.

Developers will use less and less open source modules and more and more
private company modules to do their work. The reason is because the company's
type system will eventually conflict with the type systems of all third party
open source modules.

~~~
sjapkee
>The 2x to 3x extra time that it will take to complete projects using
TypeScript instead of JavaScript. This is time which could have been spent on
writing more tests.

What's the reason to write tests for things, that just should works? You
shouldn't think about tests like "What error does it throw if I pass that
type?" With type checking you just won't have that type of issues.

~~~
jondubois
>> "What error does it throw if I pass that type?" With type checking you just
won't have that type of issues.

That's incorrect. If the object was parsed from JSON (e.g. sent to the server
by a remote client), then you still need to do a type/schema check with
TypeScript because types are only checked at compile time; not at runtime.

If you have good integration tests, you don't need to explicitly check for
types in JavaScript; type incompatibilities will show up as logic errors in
the tests. For example, if you add 100 with '23', you will get '10023' \- You
don't need to use `typeof ... === 'number'` in order for your test suite to
pick this up as a logic error.

Even if your test case is written in TypeScript, you still need to account for
the possibility that the front end will pass the value as a string; so the
JavaScript test is the same size as the TypeScript one.

~~~
sjapkee
> If the object was parsed from JSON

Just stop using it. Use gRPC. It's binary -> faster. It's support TypeScript
-> type safely. Type safety is a complex thing. If there is a type-safe
instrument instead of type-unsafe, you should use it.

>If you have good integration tests, you don't need to explicitly check for
types in JavaScript

It works only in the perfect world, where tests are always relevant and tests
all cases. But we live in the imperfect world. With people, which may forget
to update tests/documentation/etc. and things in something like JS still will
works. But in the type-safe world things are different. If you forgot to add
or deleted some fields - it'll break. If you pass wrong type - it'll break.
Type is a test, that always actual.

~~~
jondubois
JSON is the best, simplest, most robust, most readable, most flexible data
interchange format ever invented and fastest to integrate with external
systems. No way I would give it up for Protocol Buffers - That's like going
back to the old SOAP protocols.

Have you tried integrating with an external service via a SOAP API? It would
be quicker to rewrite the entire service from scratch than to integrate with
it.

Also, I'm not a big fan of gRPC; their decision to use HTTP2 instead of
WebSockets was a huge mistake. HTTP was designed to transfer hypertext
documents; RPCs are meant to transfer raw data; not hypertext documents. In a
way, gRPC makes the same mistake as TypeScript; instead of fixing the problem
at the root, they take an already complex solution which works well as a base
and then they add more complexity on top in an effort to make it behave in a
simpler way than the underlying technology.

You can't make something simpler by adding more complexity on top. You just
can't.

~~~
sjapkee
You can't call something simple, if you can't to determine how it's working at
each step. In JS all you can say is just "with that sort of data looks like it
works well, but with others it can throw error or has undefined behavior".
With types it works or not works. There is no type issues, only algorithm
issues. Of course it's simpler.

~~~
z3t4
There are trade-offs, for example if you pass "3" should it also work when
passing in "three" !? By limiting possible errors/inputs, you also make it
harder to use.

~~~
sjapkee
It's simpler to use when you see interface. Otherwise you should read all
function code to find out how it works and what kind of data you can pass into
it. Of course you can say, that there is should be comments/documentation, but
your code should be the best documentation itself.

------
danaliv
To me the biggest benefit of static types, type hints, annotations, etc. is
their documentation value. I don't have a particularly strong opinion on the
issue of static typing generally, but if you don't use types, you damn well
better document what your functions expect to receive and what they produce.

It is so frustrating to jump into a codebase and have to read every single
line to figure out what the inputs and outputs are. Think about how much time
is wasted. It's like an anti-multiplier. One engineer decides they don't want
to take a few minutes to annotate types or write a comment, and now every
other engineer on the team has to waste time figuring out what's happening. It
makes me want to scream.

------
jondubois
It's funny how TypeScript proponents seem to acknowledge that Java is bad and
yet they consistently fail to point out in what way it's inferior to
TypeScript.

I've worked with TypeScript for over a year and before that, I worked with
Java for about 2 years at university and if anything, Java is superior to
TypeScript because it has a much more consistent type ecosystem. Pretty much
every Java project uses the same URL class to represent URLs for example.
TypeScript has no consistency between libraries and projects - This will be
TypeScript's demise; once developers realize how empty and meaningless
supposedly universal type names are as an abstraction, they'll be begging to
go back to JavaScript.

Enforcing a type system which is consistent between all projects is as
pretentious as using global variables and yet that is the only way forward for
TypeScript as an ecosystem.

~~~
doktrin
Do TS folks really attack _Java_ specifically? Why? That doesn't make much
sense to me. By and large when I hear TS aficionados speak they compare TS to
vanilla JS and don't mention Java at all.

~~~
cryptica
They use this excuse to try to convert experienced Java developers who've seen
the light after switching to JavaScript and who are desperate to not go back
to the static typing hell hole that they came from.

I'm one of these people (2 years of Java at university).

The thing is that I know exactly why so many developers like statically typed
languages. I've been there in 2006 when I switched from ActionScript 2 to
ActionScript 3; I remember clearly the following 2 years of ActionScript 3
when I really thought I loved static types.

Unfortunately, I also remember the years after switching back to JavaScript
and the huge productivity increase that followed. The problem was not dynamic
types, it was my lack of experience.

That's why I cannot go back. I'm using TypeScript at work now and although I
really love the company mission and I feel that I'm producing really great
work, I don't think that I can stay there much longer because TypeScript slows
me down and makes me hate coding.

------
wellpast
It's also possible that even those same bugs could have been prevented by
hiring more experienced programmers. Or using non-static verification tools or
testing processes or many other tools in the toolbelt. Static typing is an
ideology, almost a religion[1]. Not to say that religions aren't bad. They can
keep a whole group of people under control. But I really don't like when
people say, "See! A static type would have fixed this issue." and then from
there conclude that static typing is a good idea.

[1] This might piss you off, but it's objectively true. Here's how you know.
Because static typing could be easily left as an optional choice throughout
the code base but no mainstream statically type PL I know of leaves it
optional. That's the definition of an ideology: it says this tool/thing/what-
have-you is the right thing to employ for all contexts at all times,
regardless of what your own judgement might conclude in the moment.

~~~
munificent
_> Because static typing could be easily left as an optional choice throughout
the code base but no mainstream statically type PL I know of leaves it
optional._

It is actually _not_ easy to design and implement a statically typed language
that gives you all of the benefits of types when you want them while still
allowing you to ignore them in some regions of your program.

The gradual typing folks poured years of time into this and still haven't
figured it out. Optional typing is more workable, but sacrifices many of the
benefits (soundness, performance) of static types even in code that is fully
typed.

~~~
z3t4
You can have static types with type inference. I would actually prefer static
typing if I did not have to annotate everything. But there are convenience
trade-offs like not having to cast when you actually mean to concatenate the
number with a string.

~~~
munificent
No, inference doesn't have anything to do with it. Inference is easy.

The challenge is around the runtime representation of types. Almost all widely
used statically typed languages maintain soundness by deferring some type
checks to runtime. C++ has dynamic_cast. Java has ClassCastException and
ArrayStoreException. C# has something similar.

When you add gradual typing where values and functions from untyped code can
flow into regions of typed code, you need even more runtime validation to
ensure you don't get uncaught type errors in your typed code.

The difficult then is figuring out how to represent those types efficiently,
what types to reify, etc. It's really really difficult.

~~~
z3t4
Most people talk about catching errors, but I think the the biggest benefit
with static types is performance - as it makes the code easier to optimize.
With TypeScript you do not get that benefit. Maybe we will see a new variant
of "use asm" for JavaScript, but more human friendly. I really wish TypeScript
would have used type inference instead of annotations, and only have a type-
checker, and not transpile. JavaScript is already strongly typed. And a
completely static type system is a pipe dream, as anything connected to the
real world have to deal with chaos.

------
_robbywashere
You spend more time reading code than writing code. Something like 80/20;
forgive me since I cannot point to a study. Sure more types will mean _more
code_ but isn't it nice that code is now explicitly typed; for you to read and
understand more?

If anything, I think types reduce stress :D

~~~
z3t4
I used to be a proponent for type annotations in JavaScript. But figured out
the reason was because I took C# code and translated it to JavaScript, which
surprisingly works well, all you have to do is to remove the type annotations.
But without the type annotations I could no longer understand what the code
did. To make the code understandable in JavaScript I had to rewrite it, and
name things properly. Example:

    
    
        Vector:x * Vector:s
    

vs

    
    
        position.x * speed.x

------
gigatexal
Yeah as a python guy myself for years and years I still like languages that
are typed. I don’t understand why people hate to define them and rely on
constructs like the compiler just to save some keystrokes. I think explicit
types make code easier to read and reason about.

~~~
Rotareti
I'm a Python guy too, and what I like about Python is that I can choose
between using it dynamically typed or statically typed. When I start a new
script/app, I usually start without type annotations and as soon as the data-
model becomes clear, I add type annotations and static type checking via
'typing' and 'mypy'. This is a worklflow I enjoy a lot and I'm very productive
with.

------
je42
a statement like this doesn't make much sense.

if they are not writing good unit tests and integration tests then may be the
statement :

"X% of bugs airbnb could have been prevented by writing better unit tests and
integration tests". is true as well...

~~~
singron
I think the significant difference between those two statements is that static
typing is concretely achievable for relatively cheap effort (i.e. use a
language with static typing), but "better tests" is something you will never
finish doing. Even if you have 100% code branch coverage, your tests don't
necessarily cover all the combinatorial cases that could cause bugs, so you
could continue to write "better tests" to prevent further bugs. If the code is
non-trivial, the combinatorial explosion is so big that you could probably
write 100 times as much test code as implementation code, and you will still
have bugs that could be solved by "better tests".

~~~
je42
you battle combinatorial explosion by making a risk analysis on the code. you
split your code in pieces and unit test those. with unit-tests usually you can
get full line + branch coverage, easily and quickly. then you go one level up
with the integration tests which these you test highly critical paths where
the unittests work together. and finally a black-box e2e test to make sure the
pieces work regardless of the implementation details.

------
drderidder
The typescript fever smells like most of the other herd stampedes over the
past several years. Check out this talk from a few years ago by Eric Elliot
"Static Types are Overrated". He goes over how types don't mean fewer bugs,
and if you're getting a lot of type-related problems it's probably got more to
do with your testing hygiene. He also just wrote a summary of 2+ years using
TypeScript and why it turned out to be more of a liability than a benefit.

------
amai
But the fashion in programming languages (Scala, TypeScript, Python) to write
the type behind the variable name has a disadvantage: When writing code an IDE
cannot suggest a variable name based on the type. This is an inconvenience one
will notice immediately when you are used to it from programming in Java,
where types are defined before the variable name.

~~~
AzzieElbab
Ummm reassignment is a rare thing in scala

------
tziki
This is a surprisingly high percentage. Usually studies have found about 15%
reduction when moving from untyped to typed.

~~~
z3t4
source ?

------
no_gravity
The slide says by 'TypeScript'. Not by 'Types'.

So the static code analysis of the typescript compiler would have catched the
bugs.

Without examples of those bugs it's hard to say if types play a role here.

It could very well be that most of these bugs would have been prevented by any
static code analysis. Independent of the usage of types.

~~~
danpalmer
Furthermore, a stronger type system than TypeScript's, Elm's for example, may
have caught even more than 38%.

For advanced type systems, it's often quite difficult to conceive of bugs that
could not be caught by them, although they add a very large overhead.

------
robbick
38% seems insanely high. Other estimates I've seen suggest more like 10%. If a
code base has an unusually large amount of bugs caught by types it feels like
it is missing basics like decent code review or unit tests.

* I am a huge TS fan I just don't think 38% of bugs a well written JS app should be type based

------
LaserToy
Each language was created as a tool to solve some specific sets of problems.
Saying - this is the only and the best one is a receipe for the disaster and a
sign of emotional attachement.

Use a proper language for a job be it c, java or python. Don’t try to do silly
things, like using JavaScript for all the backend

~~~
martin_a
> Use a proper language for a job be it c, java or python. Don’t try to do
> silly things, like using JavaScript for all the backend

But all the cool kids are using JS these days! Why would one choose a solid
language that doesn't break this easily, when you can just use the cool stuff?

~~~
Brometheus
Yeah, because Python and C and Java work so well in the browser ;D

~~~
martin_a
We're not explicitly talking about browser stuff here but developing in
general.

Seems like the proverb has to be changed: When you only know JS, every job
looks like a JS job.

------
egometry
This was Brie Bunge from AirBNB at JSConf Hawaii this past weekend, btw.

Great talk, should be online in a few weeks.

[https://www.jsconfhi.com/schedule/](https://www.jsconfhi.com/schedule/) for
reference.

------
brlewis
That 38% -- what strictness level of TS would have prevented those bugs?

This question is at the center of the debate surrounding the benefit:cost
ratio of using TS.

Side note: The article title says TypeScript specifically. The HN title says
types.

~~~
seattle_spring
JS bugs specifically, and it's with strict mode enabled.

------
sharno
We use Purescript at work. I don't remember the last time anyone on the team
needed to fix a bug in the Purescript code. Our team had to fix around 4-5
bugs in the JS code in the past week alone. The Purescript code is really well
designed with proper usage of types everywhere possible.

Refactoring is done in Purescript fearlessly, if it compiles it'll run
correctly or there's a bug in the JS or backend code that sends wrong data to
it.

I really wonder how the ecosystem of frontend would be if Purescript became a
widely adopted language

------
IloveHN84
That's why I hate JS You need 10-12 tools and frameworks to do something and
then you are full of bugs everywhere because of the poor designed language.

Large systems should rely on industry-proof languages (derived/based on C) to
be safe. Not a casa that there are approved coding standards that work (SERT
for instance)

~~~
ernst_klim
>rely on industry-proof languages (derived/based on C) to be safe

 _looking at the CVS list with the amazement_

C is the Javascript of system programming: weakly typed, everything is an int,
error prone, popular, nobody knows all the pitfalls.

~~~
IloveHN84
I said based on C, not C.

Alone C11 brings much more compared to C89.

But C++ and C# are pretty solid and robust. Rust is the newcomer, perhaps Go..

~~~
ernst_klim
C++ and Rust borrow their good parts from ML and Ada, not from C.

~~~
zozbot123
The "good part" of Rust compared to its closest alternatives is the machine
model, which is straight C. You can even directly transpile C into Unsafe
Rust.

------
mcv
The arguments in that threat aren't very good. Everybody makes mistakes[0],
types or not, and a type system doesn't prevent all errors. Every system that
prevents errors comes with its own overhead.

I think there are situations where explicit types are good, and situations
where they're unnecessary or get in the way.

Java's use of generics is a good example of the latter:

    
    
      ArrayList<String> list = new ArrayList<String>();
    

One of those just shouldn't be there. (Edit: Java 10 apparently added type
inference, which means this is not necessary anymore.)

But in function parameters, it's incredibly useful to be able to ensure that
the parameters are of the type you expect (and preferably not null, which most
languages don't offer). That prevents a lot of unnecessary boilerplate
checking whether you actually have the right type in your hands.

Basically I don't need explicit types for stuff I declare locally, because I
can see in the code what type it is. But for parameters and other data I get
from other parts of the system (ajax calls, for example), enforced types are
incredibly useful.

[0] Except Donald Knuth, who apparently cannot make mistakes.

~~~
hocuspocus
Local variable type inference was brought to Java with the version 10.

~~~
mcv
Ooh, nice. That sinks that part of my argument, I guess.

Still, it doesn't change the fact that some type systems are cumbersome in
some places, yet valuable in other places. I think we're currently seeing a
movement towards type systems that do more for you while getting in the way
less, and that's certainly useful.

~~~
hocuspocus
I think most modern(ized) languages have reached a fairly good compromise.
Full inference is typically infeasible or too expensive unless you stick to
the ML family and Haskell. And even then, I believe you want explicit type
signatures for self-documenting purposes, also to avoid unwanted
generalization.

~~~
mcv
Exactly. Explicit function signatures are very valuable. Having the system
check that the object you get fits your expectations is useful. There are
other situations where I could do without them.

------
iblaine
And this is ok. A shift away from strongly typed languages encourages
laziness. A shift towards resilient micro services accommodates laziness. It’s
good enough to get by and allow large companies like airbnb to grow. Clean
code vs time to market is a debate that’ll never end.

------
tonymet
One thing I've always liked about typing systems is the compiler basically
shaming me with "do you really know what you're doing". also small refractors
are more graceful

------
z3t4
100% of all bugs would be prevented if you could travel into the future and
look at the bug patches - postmortem analysis.

~~~
Forge36
Well sure, but what are the corrective steps? 38% of bugs could have been
caught sooner/prevented with types. The question to ask: What percentage of
the 38% would have been avoided?

Similar problems have been solved in the past: what percentage of index out of
bounds errors were caught because the concept was adopted by the language?

~~~
z3t4
Can you give more context. What language are you talking about ? What if I
spent five minutes extra looking at the commit, would that have spotted the
bug ? In order to give a fair conclusion, you should also look at commits
without any bugs, like a blind test to reduce bias, and measure false-
positives (errors that are not bugs). Maybe also use modern tools like
inference engines that did not exist back when the bug was made. And compare
with other techniques like unit testing to see which one is more effective,
and to see if there are any synergistic effects.

------
a_imho
If bugs can be caught by using types, can type checking called some form of
testing?

~~~
machiaweliczny
Yes it't test usage of all you functions.

But I would say documentation part is more important.

This need for typesystem grows with longer feedback loop. You can maybe
iterate on react component in playground fast without types, but it's
expensive to crash rockets to check if forgot about handling some case.

------
jakespracher
38% of bugs at Airbnb could have been prevented by better unit tests

~~~
kurtisc
Yet they didn't have them. Fallible humans didn't see the missing coverage. If
they had that hindsight, they could have just not written the bugs at all.

------
latch
Whenever I hear someone promote static typing for the type of thing you'd use
JavaScript for, my first thought is: they aren't testing [properly].

I think static typing unquestionably helps if you have a young and
undisciplined team. There are a couple indicators that this is a problem for
AirBnB. We know their switch from PG to MySQL was at least partially due to
lack of discipline. They're also rely on strict linting, which in my
experience, a well gelled well led team doesn't need.

UPDATE: My mistake. I confused AirBnB with Uber for the DB switch.

~~~
chriswarbo
Tests and types are complementary. In fact, testing becomes much more useful
when dealing with static types.

As a simple illustrative example, if a function argument is type-checked as a
boolean then we can write two tests (one for `true`, one for `false`) which
cover _all_ possible executions (note that this is far stronger than merely
code coverage).

This isn't ever possible in an untyped language, since arguments can have
_any_ value, and the number of possible values is countably infinite.

~~~
AnaniasAnanas
Tests and types can be complementary but this is not always the case. If you
use a language with dependent types you can prove that your functions are
correct, making tests redundant.

~~~
machiaweliczny
Can you recomend some good language with depended types to try?

~~~
AnaniasAnanas
Agda if you want to write proofs, Idris if you want to write programs. There
is also Coq which is more popular but I would not suggest it to a beginner.
(note: both Agda and Idris can be used for both proofs and programs, it's just
that each have their own focus)

