Am I missing something or is this fundamentally not that interesting of an idea? The tl;dr of it is just that they slowly migrated a smaller subset of the internal tooling to use TypeScript, and probably in the last 3 years have migrated even more. Is that...notable? I'm sure lots of big companies use TypeScript now.
My company has roughly the same # of engineers as Google and has had some teams that adopted TypeScript while others didn't. We even own a product that uses Flowjs, for some reason. It didn't require a huge rigamarole to do so, just a hook into the internal build system (which, looking at it now, is significantly smaller in surface area than the rules_typescript Bazel rule).
The post covers this in detail. JavaScript at Google was almost completely different from JavaScript elsewhere. The tools were different, the libraries are different, and even the language itself is different (jscompiler’s ES4-inspired type system).
It’s also a huge company with a gigantic monorepo (there’s papers about it elsewhere) and a lot of inertia.
It’s amazing what Evan and his team were able to do for front-end development at Google by building tools to bridge between Google JS and TypeScript.
Lots of companies have turned JS into effectively another language with a subset of its features with internal libraries. Perhaps they aren't as academically interesting as Closure, but it's not that notable.
The monorepo aspect of the story just seems to just make doing this significantly more difficult for no discernible benefit. Isn't this the same team that made that 5 page issue on the TypeScript Github page complaining about a version bump?
This is one such change that is much harder with a monorepo because it introduces many breaking changes. However, in a lot of cases monorepos allow for upgrades and code sharing without much if any effort from individual teams. So a lot of people can get the benefits without doing anything.
It's interesting because it's a problem that crops up in every software shop to some degree. Tech debt is a wicked problem and certainly not exclusive to Javascript.
It's well written too; a good model for design / discussion papers.
Is typescript really that great? Every implementation I have seen has
1 - Work-arounds for interoperability with non typescript / legacy third party dependencies. (issue: ugly, non consistent code)
2 - Turn off strict type checking due to third party component compatibility. (issue: isn't the purpose of typescript type checking?)
3 - Is type checking really needed for most applications? (assuming some flavor of CRUD with the occasional special sauce). (issue: seems a bit academic unless your working on a webapp for the mars rover)
This is coming from someone who programmed in java, .net, strongly typed languages for years and then feels like javascript is being held back with typescript. I love programming in vanilla javascript using frameworks (in this order) vuejs, reactjs, and charge extra to work on angular.
I like TypeScript just because it makes it easier to know what you're writing, due to features like autocomplete with types, even if I don't strictly follow it.
2 out of 3 of the items you wrote down has to deal with old baggage, so whatever form of language you are dealing with those, you aren't going to have a good time. You can either bite the bullet and write the type definitions yourself, or just disable the type system altogether, which, if you can isolate it to a certain area in the code, you are fine.
If you are writing code that some other person is going to read and/or you are interested in having it behave reliably in the long run, I think a static type system is a must. Coupled with good unit tests, if the type checker does not complain, you can be very confident the code you wrote is working and will work for a vast majority of the cases.
Typescript is especially great because, unlike some other statically typed languages, you can choose not do use it in some cases (e.g., setting up mocks for tests, writing a small script to see how stuff works, etc), which is liberating.
I went from Python to Typescript. Python is still my go-to language for random tasks, though unless I have a good reason to do otherwise, I don't want to deal with a production codebase that does not do static type analysis anymore. I don't know others, but I just get more done in less amount of time in this way.
“If you are writing code that some other person is going to read and/or you are interested in having it behave reliably in the long run, I think a static type system is a must.”
Can’t this be accomplished with JavaScript? Assuming your interested in clean code and best practices.
“Coupled with good unit tests”
Can’t you also write unit tests in JavaScript?
“if the type checker does not complain, you can be very confident the code you wrote is working and will work for a vast majority of the cases.”
This is a false sense of security. “Compiling” without errors just tells me I did not do something dumb like assign a string to an int. Is this really the main issue devs have? From what I have seen no… Devs usually need to chase down and understand the code regardless of type checking.
I don't have that much experience migrating codebases from JS to TS, but I do have experience converting codebases from C to C++. The corollary is that C++ is typesafe while C isn't. So you can call a function taking a point to an int with a pointer to a double, and the compiler won't complain (too much).
Word on the street says that C programmers are usually expert engineers that know what they're doing. Yet, I had to deal with those conversion errors all the time. That C code isn't a random CRUD application on a simple website. That can be software embedded in controllers in sensitive equipment, or equipment that will be harder to update. So it's even more important to get it right. And yet...
In C if you pass a pointer to double to a function expecting a pointer to int, that is a constraint violation (see 6.5.16.1 in the standard), and the compiler is required to emit a diagnostic.
> Can’t this be accomplished with JavaScript? Assuming your interested in clean code and best practices.
There's nothing that prevents you from swimming against a stream, but we know swimming with the stream is faster. Same thing here. It's not impossible in javascript, but typescript makes code maintenance much more easier.
> Can’t you also write unit tests in JavaScript?
"Being more than sum of its parts" and all that.
> This is a false sense of security. “Compiling” without errors just tells me I did not do something dumb like assign a string to an int. Is this really the main issue devs have? From what I have seen no… Devs usually need to chase down and understand the code regardless of type checking.
Typescript does not solve all the software engineering problems. It makes common problems and annoyances much more easy to handle.
> This is a false sense of security. “Compiling” without errors just tells me I did not do something dumb like assign a string to an int. Is this really the main issue devs have? From what I have seen no… Devs usually need to chase down and understand the code regardless of type checking.
I disagree. Working towards a successful "compile" isn't much different than TDD. The number of runtime errors I run into is significantly lower with TS than it ever was without which gives a very real sense of security.
You do need to understand the code but without types it can be very difficult to track down all the places that need to be fixed when you need to change your data model. Types are more important for refactoring than writing IMO
Strongly agree. Typescript is fantastic and extremely expressive.
I recently had to take over development of a fairly large legacy application and the first thing I did was convert the core of it to Typescript, that process uncovered a lot of bugs around handling of input/output especially lack of null/undefined checking. Typescript replaces a lot of the effort that used to spent on JSDoc type annotations and unit tests (of course tests are still required but it reduces the scope of possible input from any possible type to a smaller subset).
One thing that works really well with Typescript codebases is to push the untyped code (such as legacy libraries) and input validation to the edges of the application, and ensure the core is fully type safe.
> 1 - Work-arounds for interoperability with non typescript / legacy third party dependencies. (issue: ugly, non consistent code)
These "workarounds" are typically to use third-party or hand-rolled type defs. The other common case is to write and use typeguard functions that do runtime type checking but can contextually narrow types inside conditional blocks that use them. It's a little extra work, but the ROI is there, in my experience.
> 2 - Turn off strict type checking due to third party component compatibility. (issue: isn't the purpose of typescript type checking?)
I've never seen this done. I'd always take one of the approaches I mentioned above.
> 3 - Is type checking really needed for most applications? (assuming some flavor of CRUD with the occasional special sauce). (issue: seems a bit academic unless your working on a webapp for the mars rover)
The productivity gains alone make it worth it, IMO. Refactoring without worry that you forgot to maybe update one place is just so freeing. Amazing auto-complete and intellisense makes it so much easier to work with third party libs you're unfamiliar with. And the best part is of course that many simple mistakes get caught before you even run your code at all. It takes me less time to write TS code than it does to write the equivalent JS in even simple projects. A higher likelihood of writing correct code is valuable in just about any setting, not just space projects.
I am glad to hear your more productive in TS. Personally takes me longer to keep all my proper interfaces and models up to date than rename variables (which does not happen all that often that is out of the scope of a function or let alone a file.)
Your interfaces rarely change in isolation though, right? If they're changing, so are a lot of the places you're interacting with the fields of objects of those types. A "Refactor>Rename Symbol" flow on the interface field would also update all places you used it.
I think it may take a little bit of time for things to "click", but once they do, it's usually much faster/easier/safer to work in TS.
Funnily enough, almost none of that applies to Google.
1 - there is very little third-party JS at Google due to historical issues interoperating with the Closure compiler, as documented in the post.
2 - Strict type checking is used and continually made stricter.
3 - Yes, when you have thousands of engineers contributing to the same code base for some quite sophisticated web applications, type checking is extremely useful.
1 is almost a non issue. Most libraries have decent types and TS has features for adding types yourself in your project.
2 - I've never had to disable strict mode to get a library working. Worst case you can use things like `any` as an escape hatch out of TS but it is usually tucked away in a black box that is nicely typed. Do you have examples?
3 - Correctness is important for most professional software not just billion dollar NASA projects. Runtime errors cause crashes which wrecks UX.
Things are a lot better now than they were in 2018, in large part due to his work and his team's. The typescript migration has gone well, with good automatic migration tooling, and I mostly only use TS now. This means good error messages, and good editor support.
(Disclosure: I work on ads at Google, speaking only for myself)
It sounds supremely annoying to have to wait for the entire ecosystem to develop (Cider extensions, Bazel rules, whatever-the-fuck-else-someone-needed-to-feel-less-guilty-about-making-$700k/yr) in order to write code in a new framework that's significantly more modern than the ones that are used currently.
On the other hand, internal tooling like cider, bazel, etc. are so advanced at these companies that the old frameworks like vanilla javascript are a lot better than what outsiders using javascript have. Moving to Typescript is still a huge benefit but I don't think the old development was that bad either.
Blaze and Cider are really amazing though. Consistently my favorite tools I use by and large. I wish the OSS world adopted bazel more so "what language do we use" is less of a problem.
these tools only work if you are big. small companies probably will never need bazel. the dependency management is just aweful and not all languages are equally well supported.
and for small shops it's probably stupid to add build files everywhere.
There is active work to improve this and make external does a first class feature. It will improve as more external contributors work on solutions and adopt bazel.
> not all languages are equally well supported
Similar to the previous statement. It doesn't make sense to imply "it's not perfect so it will never be perfect". The vision and feature set makes sense to me and I see no other build system tackling this scope.
> and for small shops it's probably stupid to add build files everywhere.
What makes it stupid? If your team is so small that you're only building one binary you only need one BUILD file. Very similar to how Gradle works actually.
Also, build files are mostly auto generated if you wire your source code to standard conventions. It's something you only need to think about or touch when doing something complex (that also is not supported by other build systems). Example: using genrules to automate something or packaging things for deployment.
If you have:
- more then one language
- unit tests
- package an artifact for deployment (Docker, tar, zip, etc)
- can benefit from caching
Bazel-likes are pretty much the only option right now.
There are quirks but there's also a growing community trying to smooth out those areas.
It will be interesting to see how things shake out. I haven't used Nix much so I don't know how easy it is to do iterative development (change, build, run, repeat) for apps (web, Android, iOS) or services (binaries, containers)
Personally, I’m not a huge fan of TypeScript. I feel it’s unnecessarily verbose at times. I used ReasonML for a while, and I absolutely LOVED it. I’m just bummed about the uncertainty of the projects future and adoption and the lack of alternatives that seem to make TypeScript the defacto standard.
I agree, however its utility outweighs that in a large org. It’s basically indispensable for frontend programming at scale. Having dozens or even hundreds of people contributing to a codebase without it (or equivalent) would be chaotic and painful.
Super set of JS instead of a beging a totally different language, fix its main issue (lack of useful types for error checking and refactoring), adopted by many projects, backed by Microsoft and quickly releasing new versions: there is no wonder it's replacing JS where it can.
It’s a fad. Give it some time… it’s not the first layer on top of JavaScript someone has come up with. Microsoft drops project all the time- this is a stunt on their part to attract devs and it’s actually working for now.
I don't know how anyone who's actually used plain Js and Ts in a large project can say it's a fad.
For frontend it might be different, but as someone who usually touches the Js ecosystem through node, I pretty much won't use Js.
Like why should I give up insane utility with negligible (if any) runtime cost, high configurability (with sane defaults), easy buy in (since all Js is valid Ts)?
Maybe the last part is what you're missing? Most "layers on Js" needed you to rewrite or annotate all your code to get and value at all.
But you drop a tsconfig in a project and you instantly get value out of it. What past layer on Js had that?
It's not a fad, it's based on JS.net and Actionscript (ES4) syntax that existed well before Ecma Script 5 existed. Microsoft has been iterating over Typescript for about 20 years.
Lately I've gotten into the habit of giving my pure JS projects a tsconfig.json file, so that my editor runs the files through tsc and I get all the code hints and errors it reports.
I find that as long as the code is reasonably straightforward, I get most of TS's benefits without actually declaring any types. It was kind of a pain to originally set up, but the code hints really are pretty magical.
Most of my projects have a god object at the center, so if I explicitly type that one object then I get basically all the important code hints for free.
A side benefit of this is that you can also use TypeDoc to generate docs. It's not really made for vanilla JS, but once I got over the initial road bumps I've been happy with the results.
typescript is only slightly more verborse than reason (or is it rescript?), the syntax is almost identical (does reason still have those annoying explicit ocaml/js conversions?).
At this point the features that ts has and reason doesn't out number that of the other way around. I only know that reason has more stringent jsx types and opaque types (easily done in ts in 2 lines of code). On the other hand ts has mapped types and conditional types, weird as they are, pretty unique to itself. In the future, expect ts to be even more functional and absorb ideas from F# which is also from microsoft.
People here forget that typescript is both a language and a static code analyzer for Javascript. You don't have to use Typescript syntax to use. You can write plain old Javascript and still use Typescript compiler to make sens of your code.
You can't do that with ReasonML, you are forced to adopt another language that is not Javascript.
I just resigned from Amazon today, and reading this is giving my flashbacks to my earlier years there. When I first joined in 2013, it was incredibly difficult to leverage open source third party libraries and build systems like grunt/gulp. I ended up doing a lot of work to make it possible to model JS dependencies using the standard Amazon dependency management setup and to create bindings to our language/stack agnostic build system. It was an uphill battle at times, but I got things to a point where you could reasonably do things in Amazon similar to how you'd do them externally (without sacrificing any of the advantages of of our first party tools).
The solutions I engineered still had to make some compromises and better solutions by dedicated teams were built later on, of course. All this just to say that I can very readily sympathize with the challenges that Googlers must be facing.
Edit: To clarify, I put in my 2-week notice a while back and today was my last day. That's what I meant by "resigned today".
Oh, hey Alex. As soon as I saw your handle, the name "Alex Rattray" popped to mind, and sure enough, that's who you are. I think I probably met you at a hackathon many years ago (maybe PennApps?), though it was probably in passing, since I don't think we ever worked together on a project. Small world though!
I'd been at Amazon for many years and had always wanted to move on to doing my own startup, which is what I'll be doing starting tomorrow. It's an exciting moment for me. My biggest worry about leaving is figuring out what to do about health insurance, but my fallback plan is to go with COBRA until I figure something out.
You should also checkout the health insurance exchange if in Washington. Those policies can be cost competitive to your COBRA costs, and resignation is an event that allows you grab one outside of open enrollment.
Yeah, for sure. I was using them as early as this morning, haha. I've been through the whole end to end spectrum of this at Amazon, from wild-west every team doing their own custom things to building BrazilGrunt/BrazilGulp, and moving on to all the successors since then.
Overcoming the incompatibility of npm's multi-version allowance and Brazil's need to have a single version of each package in the transitive closure of the dependency graph without hacks like shrinkwrapping was a key turning point.
66 comments
[ 3.4 ms ] story [ 128 ms ] threadGuess that means Gmail is now 17 years old.
My company has roughly the same # of engineers as Google and has had some teams that adopted TypeScript while others didn't. We even own a product that uses Flowjs, for some reason. It didn't require a huge rigamarole to do so, just a hook into the internal build system (which, looking at it now, is significantly smaller in surface area than the rules_typescript Bazel rule).
It’s also a huge company with a gigantic monorepo (there’s papers about it elsewhere) and a lot of inertia.
It’s amazing what Evan and his team were able to do for front-end development at Google by building tools to bridge between Google JS and TypeScript.
The monorepo aspect of the story just seems to just make doing this significantly more difficult for no discernible benefit. Isn't this the same team that made that 5 page issue on the TypeScript Github page complaining about a version bump?
It has many other benefits as well that have been outlined in lots of other posts.
It's well written too; a good model for design / discussion papers.
1 - Work-arounds for interoperability with non typescript / legacy third party dependencies. (issue: ugly, non consistent code)
2 - Turn off strict type checking due to third party component compatibility. (issue: isn't the purpose of typescript type checking?)
3 - Is type checking really needed for most applications? (assuming some flavor of CRUD with the occasional special sauce). (issue: seems a bit academic unless your working on a webapp for the mars rover)
This is coming from someone who programmed in java, .net, strongly typed languages for years and then feels like javascript is being held back with typescript. I love programming in vanilla javascript using frameworks (in this order) vuejs, reactjs, and charge extra to work on angular.
Many libraries come with TS support out of the box and the autocomplete and automatic renaming across files is quite nice.
I'm using strict mode and didn't have issues yet, but I'm just at the beginning, so let's see how it goes.
2 out of 3 of the items you wrote down has to deal with old baggage, so whatever form of language you are dealing with those, you aren't going to have a good time. You can either bite the bullet and write the type definitions yourself, or just disable the type system altogether, which, if you can isolate it to a certain area in the code, you are fine.
If you are writing code that some other person is going to read and/or you are interested in having it behave reliably in the long run, I think a static type system is a must. Coupled with good unit tests, if the type checker does not complain, you can be very confident the code you wrote is working and will work for a vast majority of the cases.
Typescript is especially great because, unlike some other statically typed languages, you can choose not do use it in some cases (e.g., setting up mocks for tests, writing a small script to see how stuff works, etc), which is liberating.
I went from Python to Typescript. Python is still my go-to language for random tasks, though unless I have a good reason to do otherwise, I don't want to deal with a production codebase that does not do static type analysis anymore. I don't know others, but I just get more done in less amount of time in this way.
Can’t this be accomplished with JavaScript? Assuming your interested in clean code and best practices.
“Coupled with good unit tests”
Can’t you also write unit tests in JavaScript?
“if the type checker does not complain, you can be very confident the code you wrote is working and will work for a vast majority of the cases.”
This is a false sense of security. “Compiling” without errors just tells me I did not do something dumb like assign a string to an int. Is this really the main issue devs have? From what I have seen no… Devs usually need to chase down and understand the code regardless of type checking.
Thanks for your perspective!
Word on the street says that C programmers are usually expert engineers that know what they're doing. Yet, I had to deal with those conversion errors all the time. That C code isn't a random CRUD application on a simple website. That can be software embedded in controllers in sensitive equipment, or equipment that will be harder to update. So it's even more important to get it right. And yet...
There's nothing that prevents you from swimming against a stream, but we know swimming with the stream is faster. Same thing here. It's not impossible in javascript, but typescript makes code maintenance much more easier.
> Can’t you also write unit tests in JavaScript?
"Being more than sum of its parts" and all that.
> This is a false sense of security. “Compiling” without errors just tells me I did not do something dumb like assign a string to an int. Is this really the main issue devs have? From what I have seen no… Devs usually need to chase down and understand the code regardless of type checking.
Typescript does not solve all the software engineering problems. It makes common problems and annoyances much more easy to handle.
I disagree. Working towards a successful "compile" isn't much different than TDD. The number of runtime errors I run into is significantly lower with TS than it ever was without which gives a very real sense of security.
You do need to understand the code but without types it can be very difficult to track down all the places that need to be fixed when you need to change your data model. Types are more important for refactoring than writing IMO
https://www.destroyallsoftware.com/talks/ideology
I recently had to take over development of a fairly large legacy application and the first thing I did was convert the core of it to Typescript, that process uncovered a lot of bugs around handling of input/output especially lack of null/undefined checking. Typescript replaces a lot of the effort that used to spent on JSDoc type annotations and unit tests (of course tests are still required but it reduces the scope of possible input from any possible type to a smaller subset).
One thing that works really well with Typescript codebases is to push the untyped code (such as legacy libraries) and input validation to the edges of the application, and ensure the core is fully type safe.
These "workarounds" are typically to use third-party or hand-rolled type defs. The other common case is to write and use typeguard functions that do runtime type checking but can contextually narrow types inside conditional blocks that use them. It's a little extra work, but the ROI is there, in my experience.
> 2 - Turn off strict type checking due to third party component compatibility. (issue: isn't the purpose of typescript type checking?)
I've never seen this done. I'd always take one of the approaches I mentioned above.
> 3 - Is type checking really needed for most applications? (assuming some flavor of CRUD with the occasional special sauce). (issue: seems a bit academic unless your working on a webapp for the mars rover)
The productivity gains alone make it worth it, IMO. Refactoring without worry that you forgot to maybe update one place is just so freeing. Amazing auto-complete and intellisense makes it so much easier to work with third party libs you're unfamiliar with. And the best part is of course that many simple mistakes get caught before you even run your code at all. It takes me less time to write TS code than it does to write the equivalent JS in even simple projects. A higher likelihood of writing correct code is valuable in just about any setting, not just space projects.
I think it may take a little bit of time for things to "click", but once they do, it's usually much faster/easier/safer to work in TS.
1 - there is very little third-party JS at Google due to historical issues interoperating with the Closure compiler, as documented in the post.
2 - Strict type checking is used and continually made stricter.
3 - Yes, when you have thousands of engineers contributing to the same code base for some quite sophisticated web applications, type checking is extremely useful.
1 is almost a non issue. Most libraries have decent types and TS has features for adding types yourself in your project.
2 - I've never had to disable strict mode to get a library working. Worst case you can use things like `any` as an escape hatch out of TS but it is usually tucked away in a black box that is nicely typed. Do you have examples?
3 - Correctness is important for most professional software not just billion dollar NASA projects. Runtime errors cause crashes which wrecks UX.
For programming in it on anger, only when the underlying framework is also written in Typescript.
It is so liberating to just code in JavaScript with a plain <script/> include, without the pleothora of FE build tools.
Maybe one day browsers will actually replace JavaScript with Typescript.
(Disclosure: I work on ads at Google, speaking only for myself)
Hence plenty of companies still on Java 8, baby steps adopting C++11, Python 2.7, .NET Framework 4.8 is now being deployed, and similar....
Installing whatever you feel like locally doesn't work, because either you miss the required rights, or it will die on the CI/CD pipeline anyway.
There is active work to improve this and make external does a first class feature. It will improve as more external contributors work on solutions and adopt bazel.
> not all languages are equally well supported
Similar to the previous statement. It doesn't make sense to imply "it's not perfect so it will never be perfect". The vision and feature set makes sense to me and I see no other build system tackling this scope.
> and for small shops it's probably stupid to add build files everywhere.
What makes it stupid? If your team is so small that you're only building one binary you only need one BUILD file. Very similar to how Gradle works actually.
Also, build files are mostly auto generated if you wire your source code to standard conventions. It's something you only need to think about or touch when doing something complex (that also is not supported by other build systems). Example: using genrules to automate something or packaging things for deployment.
If you have:
- more then one language
- unit tests
- package an artifact for deployment (Docker, tar, zip, etc)
- can benefit from caching
Bazel-likes are pretty much the only option right now.
There are quirks but there's also a growing community trying to smooth out those areas.
For frontend it might be different, but as someone who usually touches the Js ecosystem through node, I pretty much won't use Js.
Like why should I give up insane utility with negligible (if any) runtime cost, high configurability (with sane defaults), easy buy in (since all Js is valid Ts)?
Maybe the last part is what you're missing? Most "layers on Js" needed you to rewrite or annotate all your code to get and value at all.
But you drop a tsconfig in a project and you instantly get value out of it. What past layer on Js had that?
I find that as long as the code is reasonably straightforward, I get most of TS's benefits without actually declaring any types. It was kind of a pain to originally set up, but the code hints really are pretty magical.
A side benefit of this is that you can also use TypeDoc to generate docs. It's not really made for vanilla JS, but once I got over the initial road bumps I've been happy with the results.
At this point the features that ts has and reason doesn't out number that of the other way around. I only know that reason has more stringent jsx types and opaque types (easily done in ts in 2 lines of code). On the other hand ts has mapped types and conditional types, weird as they are, pretty unique to itself. In the future, expect ts to be even more functional and absorb ideas from F# which is also from microsoft.
You can't do that with ReasonML, you are forced to adopt another language that is not Javascript.
The solutions I engineered still had to make some compromises and better solutions by dedicated teams were built later on, of course. All this just to say that I can very readily sympathize with the challenges that Googlers must be facing.
Edit: To clarify, I put in my 2-week notice a while back and today was my last day. That's what I meant by "resigned today".
I'd been at Amazon for many years and had always wanted to move on to doing my own startup, which is what I'll be doing starting tomorrow. It's an exciting moment for me. My biggest worry about leaving is figuring out what to do about health insurance, but my fallback plan is to go with COBRA until I figure something out.
Overcoming the incompatibility of npm's multi-version allowance and Brazil's need to have a single version of each package in the transitive closure of the dependency graph without hacks like shrinkwrapping was a key turning point.
As others will point out alot has progressed and changed since then, this isn't news.
Lots of previous discussion: https://news.ycombinator.com/item?id=17894764