[HN Gopher] The Great CoffeeScript to Typescript Migration of 2017 ___________________________________________________________________ The Great CoffeeScript to Typescript Migration of 2017 Author : dgoldstein0 Score : 135 points Date : 2020-05-15 20:05 UTC (2 hours ago) (HTM) web link (dropbox.tech) (TXT) w3m dump (dropbox.tech) | jtth wrote: | This makes me miss CoffeeScript. Ah, well. | city41 wrote: | Only thing I still miss is noop functions are two characters. | Everything else I liked is in JS now that nullish coalescing | landed. | recursive wrote: | `_=>_` is technically more than two, but not by much. | hombre_fatal wrote: | Identity function is more confusing than just ()=>{} which | is obviously noop because it doesn't return the input. | seemslegit wrote: | Cofeescript will always be remembered as peak code hipsterdom. | erichurkman wrote: | My fond memory of CoffeeScript was an interview I did way back | when at Olark. It was a full day 'paid work along' interview that | was popular at the time. I'd never touched CoffeeScript prior. In | less than the day, I was proficient enough even navigating a | foreign code base to build out a small feature within the Olark | platform. (I think it was managing chat operators as groups?) | | Fond memories! | k__ wrote: | CoffeeScript? 2017? | | I had the impression that CS was done when ES2015 came out in ... | Well 2015 | | I personally prefered LiveScript, should have been. | bcrosby95 wrote: | They started the project of looking for a replacement language | in 2015. You can't instantly rewrite all the code. | k__ wrote: | -can't +shouldn't | | My co-worker of that time did exactly that one week before I | got hired. | | Also, he told noone. | | I just saw it one time, when I played around with a tool that | would visualize Git commits, years later. Thousands of lines | of code. | | Absolute mad lad. | thrower123 wrote: | The only people I ever knew personally who used CoffeeScript also | used Rails. That was usually the combo then. | | The shine has kind of come off Rails, and the cool kids followed | the shiny to the next thing, usually node, and so they moved to | Typescript. | nosefrog wrote: | I worked on this project, it was super fun. Open to answering any | questions. | faitswulff wrote: | What was fun about it? | city41 wrote: | I'm curious why not allow implicit anys instead of creating the | tool that inserted anys? Seems roughly the same outcome but | implicit anys would take a lot less work? | dgoldstein0 wrote: | Because of the way we had type checking set up - our existing | code already used noImplicitAny, and we wanted to keep that, | and we were typechecking it all in one shot, together, so we | couldn't have different typescript flags for different files. | | Now as to why to use noImplicitAny in the first place: mainly | because implicit anys are usually accidents - places where | developers didn't realize they should put a type. And the | explicit `any` in many ways is sitting there for anyone who | cares to replace it with something better; whereas implicit | anys are much harder to notice. | lewis1028282 wrote: | Is CoffeeScript all but dead? I use Ruby and Python a lot so the | syntax of CoffeeScript looks great to me! | rogem002 wrote: | I do Rails full time and most the CoffeeScript lives in the | "legacy" side projects. Most projects I'm on have moved to | vanilla JavaScript or ES6 via Webpack. | | I don't think it's dead (it's still popping up), but I think | it's time has passed. | CapriciousCptl wrote: | I fully remember picking up coffeescript because Dropbox had used | it. I only ever used it on one project. I try and remember that | every time I have the urge to go with Reason, Elm or even wasm | compiling things. Long live JS. | Roboprog wrote: | If you are trying to build for a business, or something you | yourself will have to maintain for years to come, vanilla JS | seems like the way to go. | | Perhaps Typescript isn't a fad to be abandoned, unlike say GWT, | CoffeeScript, et al, but why risk it? | | Javascript doesn't feel painful to me like Java does. I don't | have a lot of problems with it that need solving with an | alternate front end. | | Long live JS! | karatestomp wrote: | AFAIK TS is pretty committed (at the expense of possibly- | useful functionality) to being very, very simple to strip | out, leaving vanilla JS in its wake. Unless you're minifying, | the compiler output typically looks almost exactly like the | well-formatted, sane, and readable JS you'd have written | instead. That escape hatch is part of why I've not worried a | bit about taking it up. Turning a TS project into a JS | project, should you ever need to, is functionality that's | essentially built-in, and you do it every time you run "tsc". | Roboprog wrote: | Once you stop making hundreds of classes with globally | visible names and members, and start using function scope, | functional programming, and mostly short lived value objects, | much of the OOP induced pain of programming simply goes away. | | Alas, this requires training of the road not taken. | melling wrote: | Does any alternative have any traction? | | ReasonML is used by Facebook. Elm used to get more attention on | HN. | city41 wrote: | Since wasm has native browser support it doesn't really feels | like it fits into this group. I have a feeling in a few years | wasm will be pretty common. | julianeon wrote: | Yeah, wasm is offering something those others aren't. You | could say that Coffeescript to Typescript is a lateral move. | Try as you might, you can't do the things wasm is best for - | say, graphics - in Coffeescript. | eecc wrote: | I wonder what happened with the devs that started the tumble | towards the Coffeescript migration... still locked in the cellar? | dgoldstein0 wrote: | Author here, also willing to answer questions | Jare wrote: | > it was absurd to expect anyone to want this as their full time | job for even a month or two | | That gave me a true 'kids these days' moment... | | In my day within a spanish bank, as a team of 4 interns, we spent | over 6 months reviewing/documenting an entire proprietary | platform C codebase (full of gotos, endian-dependent hacks, post- | compile patches and every horrible thing you could imagine), and | then with a larger (~3x) team about 12 months cleaning, porting | and expanding that codebase to a clean platform (if you can call | SCO Unix 'clean'). | | What sort of dynamics prevent a product startup like Dropbox | build an engineering team that includes the capability to do such | a task? | bcrosby95 wrote: | Because startups tend to use how much you enjoy coding as a | proxy for how good of a coder you are. So if you purposefully | hire a bunch of people because they like coding, it's going to | cause a shitload of problems once you unleash an "unfun" job | like this on them for such a long period of time. | whynotminot wrote: | Wait what? So you should hire coders who don't like coding to | do coding? | mwcampbell wrote: | Maybe it's more about hiring people with a strong work | ethic, who will do whatever needs doing, not just what's | fun. Note: I don't think I'm really one of those people. | nojito wrote: | People who "like" coding tend to prefer hot new tech as a | way of experimentation. | | They often ignore the actual business problem that needs to | be solved, because it can be solved using "boring" | technology. | Jare wrote: | Consider that I joined the bank as an intern and college | student, but I had been programming for 10 years (almost 100% | assembly) including two commercial video games published in | my teens. And there was another like me in the team. We loved | coding dearly, and 30 years later I still do (the other one | pivoted into law, ah well). But work's work and must get | done, right? | austincheney wrote: | As a JavaScript developer this is limited only to everywhere. | | As for myself I like coding, but what I really mean is I like | writing original software to solve automation problems, which | clearly not the same definition some of my prior colleagues | have used. | iliekcomputers wrote: | I would assume most engineers would like to spend time building | stuff instead of migrating already built stuff to a different | but kinda similar language. | | I don't think it's unreasonable to not want to do a | CoffeeScript to TypeScript migration full time for an entire | year. It's basically the equivalent of creating a "tech-debt" | team and giving them only tasks which pay down tech debt. Sure, | there are situations where tech debt needs to be paid down and | you could make an entire team do it for an year, but the | engineers will probably not _like_ being on the team. | dgoldstein0 wrote: | I didn't say people _wouldn 't_ do it. Some people actually | did! the whole Maestro team, for most of Q2 2017, for instance. | | Part of my point though is that converting coffeescript to | typescript was very boring, mostly mechanical work (which is | more obvious in hindsight, since we actually automated most of | it). Sure, you could make the code better while you are there, | but that actually was likely to add bugs, which could | significantly delay such conversions, or lead you to chasing | around the codebase to figure out how to get typechecking to | work with your attempt at better types. What you are describing | - going through an old codebase and figuring out how to fix it | - sounds a lot more interesting! though definitely there are | plenty of people who wouldn't want that job either. | | But really the biggest blocker to executing on the manual | conversion strategy was management. They already had other | commitments for their teams, and spending a few thousand hours | converting coffeescript to typescript wasn't as high of a | priority for most of them, than the things their teams were | actually working on. This partly comes down to our incentive | structure - doing work for other teams, especially in a | migration like this, can often feel like a chore, and is often | not really rewarded with anything. But prioritization for a | large project like this also takes a lot of input from upper | management, and they didn't want to sacrifice other priorities | to keep the original manual conversion plan on track. | Jare wrote: | I guess part of what you are saying is, that getting that | task done was not so important for Dropbox in the grand | scheme of things. | | In the case I described, it was life and death for the entire | organisation (proprietary hardware platform was EOL'd, so | cero possibility of growth), and the managers that led it | (and trusted 4 interns to do the ground work!) got rewarded | handsomely AFAIK. | | Thanks for a great writeup and clarifications! | 29athrowaway wrote: | Coffeescript tried to simplify the syntax, but it went too far. | | - A statement such as f(g(x)) becomes absurd without parentheses. | | - Indentation has a meaning, but it is legal to have inconsistent | indentation. | | Code is written once, read many times. Coffeescript got that | backwards. | | CoffeeScript is to JavaScript what Stenography is to Writing. | Steno makes sense when you have to write something being dictated | to you in real-time, but if you are not in a hurry, just write. | diegoperini wrote: | > A statement such as f(g(x)) becomes absurd without | parentheses. | | This was a feature I actually enjoyed. | dgoldstein0 wrote: | precisely. | | Though some of their constructs, like classes and for-in loops | - are great for reading and writing. | 29athrowaway wrote: | Coffeescript does have useful features, but problems such as | the ones I described made CoffeeScript code inconvenient to | maintain in practice. | | If we weigh the convenient aspects of CoffeeScript against | the inconvenient aspects, in the end, CoffeeScript can be an | inconvenient language to use. It was the case at least for me | in various projects I had to maintain. | | Part of the inconvenience was all the JavaScript tooling you | cannot use, and occassionally being forced to read JavaScript | code generated by CoffeeScript. | dgoldstein0 wrote: | Yup, totally agree. In 2012 when we adopted Coffeescript, | it was less cut and dry - all the open source tools we love | now - prettier, eslint, etc. - didn't exist. So the | tradeoff was less obvious then. | [deleted] | blitmap wrote: | I truly do not understand why so many jumped from Coffeescript. I | still use it and still believe I can be more concise and | expressive in Coffeescript. Typescript and ES2015 picked up a lot | of wonderful things, but I find myself writing a lot less | boilerplate in Coffeescript. I will continue to "do me". I dev in | Coffeescript and publish in JS. The project even made it a focus | to transpile to readable/friendly JS. No biggie. | | I would not publish things like this, though :) | | console.log [ i if i % 3 and i % 5, 'fizz' unless i % 3, 'buzz' | unless i % 5 ].join '' for i in [ 1 .. 100 ] | | Separately, I bought overpriced raspberry pi's instead of cheaper | alternatives because I knew the community was a strong source of | support. Modern JS has a much larger community than Coffeescript | 2. | dgoldstein0 wrote: | I recall when we first adopted Coffeescript, the engineers who | did it touted that we had about 20% fewer lines of code as an | example of coffeescript being better - a lot of which was | probably just the removal of lines that only had curly-braces. | In hindsight, this wasn't a good metric to judge the language | on. | | As a larger engineering organization, what we've definitely | learned over time is that we need to prioritize readability | (and maintainability) over writability - as our code is going | to last a long time and the original engineer who wrote it, | will likely move on to another project, team, or even company. | And while maybe they train their replacement, after a second or | third iteration of that, the knowledge can easily end up lost. | | Coffeescript, as a language, definitely prioritizes terseness, | often at the expense of readability. And we didn't have | internal coding standards that pushed back on this. | | But even if we had done a better job using coffeescript, we're | still better off in typescript today, due to the stronger | community and stronger set of available open source tools to | work with the language. | baddox wrote: | In my view, the primary advantage of CoffeeScript was to | provide ways to avoid JavaScript footguns. I think that a | combination of ES 2015 and wider propagation of best | practices have made many such footguns avoidable in practice | without using CoffeeScript. | acdha wrote: | That matches my experience: the pitch was writing less, | safer code but I found that JSHint (back then) had a | comparable effect without a stop-the-world migration and a | lot of the size reductions weren't significant compared to | following any style standards for naming, comments, etc. | city41 wrote: | But it brought along its own footguns. The article has one | example | | > For example, we had a major production bug in the fall of | 2013 due to a misplaced space character. | agency wrote: | Definitely my experience. Implicit returns are just a | breathtakingly bad idea and I have personally witnessed | them cause countless bugs. | city41 wrote: | I think they can be ok in a language where it's been well | thought out. Like implicit return in clojure has never | bugged or surprised me. | blitmap wrote: | I think it does depend on how familiar the syntax feels to | each individual. To me Coffeescript is the right balance. I | absolutely love writing Literate Coffeescript. I am _not_ a | fan of strictly typed languages but I do hope Coffeescript | finds a friendly syntax for gradual typing like TS in the | future. I usually prototype in a 'ducky' way and then lock | down type expectations when I'm polishing. | dgoldstein0 wrote: | this is totally fair, but these days you are far more | likely to find engineers to hire who know JavaScript or | Typescript, than Coffeescript. This certainly matters more | to larger projects and larger companies. | erikw wrote: | I see readability as a key advantage of TS. Once you are able | to comfortably read type signatures, it is trivial to see | what a function is supposed to do, or what a library is | supposed to provide. When things don't work as expected, then | it's just a matter of hopping into the debugger to inspect | data inflight to find where the typings aren't matching up | with reality. | dgoldstein0 wrote: | yup, types are a huge advantage, especially in large | codebases where you probably don't know all the people who | may write code to interact with your code. | | Readability of types can become an issue over time, but | with the right naming of interfaces and useful type | aliases, that can be mitigated to some extent. And as the | typescript language and community evolve together, there | are new ways to make some types even more readable - I've | seen generics for getting the return type of a function, | which seems potentially really useful (and some people | swear by; I haven't used them extensively, but it looks | like a promising idea). | 2019-nCoV wrote: | It is not at all trivial to see what a function is supposed | to do from its type sig. There are an infinite number of | valid type safe implementations for: | transform(a: number): number | keymone wrote: | It makes a number out of a number. Type signature isn't | supposed to explain the implementation, just the | interface. | brazzy wrote: | Uh... welcome to static typing. Yes, it's nice. | Shacklz wrote: | > where the typings aren't matching up with reality. | | There are also libraries which provide runtime type | validation, such as zod or io-ts. Can only recommend; they | allow that in combination with typescript's strict mode | your types become completely reliable. | heipei wrote: | Same here, still using it for frontend (Ember and React) and | backend work to this day and very happy and productive with it. | Almost never have cases where I thought I needed more | strictness or better community support. I am both more | comfortable writing code as well as reading code in it, | especially because it enforces significant whitespace and | allows you to have more code on the screen because you omit a | lot of filler stuff like braces, semicolons, bar/let/const etc. | It's not for everyone but my brain is 100% in tune with it. | Coffeescript, lodash and a functional approach to writing code | are pure bliss to me. | luketheobscure wrote: | I ported several large code bases off of CoffeeScript last | year, mostly to JavaScript, but some to TypeScript. Simply | being able to use ESLint is worth it (CoffeLint wasn't even | close). I wrote CoffeeScript for years but I don't miss it one | bit-especially now that TypeScript has optional chaining! | choward wrote: | > I truly do not understand why so many jumped from | Coffeescript | | You clear up your own confusion right here: | | > console.log [ i if i % 3 and i % 5, 'fizz' unless i % 3, | 'buzz' unless i % 5 ].join '' for i in [ 1 .. 100 ] | | And you said: | | > I would not publish things like this, though :) | | You just did though ;) | | > I still use it and still believe I can be more concise and | expressive in Coffeescript. Typescript and ES2015 picked up a | lot of wonderful things, but I find myself writing a lot less | boilerplate in Coffeescript | | That boilerplate that you imply hinders conciseness isn't just | boilerplate. It's code that helps you automate getting rid of | certain classes of bugs. It also in most cases makes the code | more readable IMO. And if the problem you are trying to solve | is having to type less, I believe that's a job for your editor | and tooling. | studentik wrote: | CoffeeScript rocks for functional programming. Less chars and | more sense per LoC, easier to learn than JavaScript and syntax | sugar is sweet. | bambataa wrote: | As someone who came into development after the Coffeescript wave | I'm interested to know: how much did it feel like the future? | | Was it always an early adopter, "look how forward we are" kind of | thing, or was it just popular with Rubyists? | | I'm trying to calibrate it with other possibly-next-big-thing | front end languages. | wahnfrieden wrote: | Personally speaking from what I saw around the internet and my | own experiences with peers using it, it was contentious whether | it was so forward-thinking or sufficiently differentiated to | make it worth it. | bartread wrote: | Back in 2013/14 I remember on a couple of occasions being | quite annoyed when I found npm packages that I wanted to | bugfix were written in Coffeescript rather than plain old JS. | It always seemed so unnecessary, and tended to push me | towards alternative solutions. | agilebyte wrote: | Some things still remain in the "future" bucket and I miss in | JS/TS, like the native support for literate programming which | lets you write your code and documentation together and | generate e.g.: | | https://github.com/radekstepan/metalsmith-related#source | chipotle_coyote wrote: | I think CoffeeScript was definitely popular outside the Ruby | community, too, for a while. (After all, Dropbox was/is a | Python shop, not Ruby!) | | Speaking strictly for myself, while I liked a lot of what | CoffeeScript was trying to do, I didn't love the "one layer | removed" feel of writing in a language that wasn't the one | actually being executed. Also, I often found CoffeeScript to be | cryptic in ways that vanilla JS, for all its quirks, really | wasn't. So I think it felt like the future for a couple years, | until JavaScript ES6 took off and it started feeling kind of | superfluous -- ES6 felt like it was taking the good parts of | CoffeeScript while leaving a lot of the quirks behind. | dgoldstein0 wrote: | It was definitely popular beyond Rubyists - Dropbox was | originally a python-based engineering organization, and we | picked it up, and a lot of us liked it for a few years. | | I think the main thing to note is that we were supporting IE7+ | when we adopted coffeescript. So we couldn't even write | standard ES5 - ES3 would have been the lowest common | denominator supported. So having classes, optional chaining, | array comprehensions, for-in loops that actually looped over | items in an array (like ES6 for-of) - all those features were | super useful. And you didn't need to worry about function | declaration hoisting (or any confusion it could cause) because | coffeescript only compiled to function expressions, which got | bound to variables. | | Unfortunately, coffeescript came with some others like implicit | returns and tons of optional syntax that we didn't realize was | problematic until far too late. | | And being a python-based org, having a frontend language that | looked similar (space-delimited, a lot of similar features e.g. | array comprehensions were like list comprehensions, ternaries | that looked more readable) seemed like features. But some of | these features bit us hard at times, because they didn't work | like python - the worst, in my opinion, was that `is not` and | `isnt` looked the same but meant very different things in | coffeescript. `is not` meaning `=== !` and isnt meant `!==`. | | But given the alternative was writing prototypical-inheritance | by hand, and dealing with various IE7isms directly? It was a | sensible tradeoff at the time. | danenania wrote: | What's wrong with implicit returns? I've always liked those | in CoffeeScript and Ruby. | city41 wrote: | It can cause surprises. One of the biggest ones is turning | a loop into an expression if it's the last thing a function | does. | | Edit: here is an example | | https://coffeescript.org/#try:-%3E%20%0A%20%20for%20i%20in% | 2... | rraval wrote: | Accumulating loop results in an array is bad for perf, | but won't necessarily cause logic bugs. | | My favourite implicit return gotcha comes from the | intersection of CoffeeScript and jQuery, where implicitly | returning `false` from an event handler implies | `preventDefault()` and `stopPropagation()`. This can even | cause heisenbugs if your logging throws booleans around. | nevir wrote: | CoffeScript had quite a bit of influence on JavaScript and | TypeScript today (and/or really great timing w/ similar | thinking). All of these were in early releases of CoffeeScript, | and showed up in modern JavaScript years later: | | * fat arrow functions | | * classes | | * template strings, multiline strings | | * destructuring and ...rest values (splatting) | | * elvis operator (foo?.bar?.baz - in TypeScript) | | honorable mention | | * list/iterator comprehensions (made some good progress in the | ES speccing process, but ultimately didn't land) | dgoldstein0 wrote: | ah, I forgot coffeescript had destructuring! yes, that is a | great feature. | BurningFrog wrote: | Yeah, is this sense Coffeescript didn't only feel like the | future, it _was_ a preview of the future. | wonnage wrote: | I think it was also a forcing function for a lot of modern | development patterns. Bundlers, sourcemaps, even chrome's | prettyprint, all became mainstream around the time | coffeescript was relevant (~2011?) I think they all existed | before then, debugging coffeescript was a huge pain in the | ass without them. | chanind wrote: | Coffeescript definitely felt soooo much nicer to work with than | JS at the time. Writing in Coffeescript back in 2012 felt like | Typescript does now, where going back to working in base JS | felt miserable after using it. ES6 took a lot of ideas from | coffeescript which basically made it redundant. I wonder if the | same will happen to Typescript if types get added into a future | version of JS? We'll probably have another post about switching | a massive codebase off Typescript onto whatever the next big | thing is. | danenania wrote: | TypeScript almost seems designed to be transitional, and I | say that as a huge fan and heavy user of TS. Gradual typing | is fantastic for learning, porting a codebase, and interop | with JS libraries, but as TS gets more ubiquitous and | everyone goes toward strict mode, people are going to start | wanting runtime enforcement of types, and to stop adding a | 'type' or 'tag' or whatever metadata key to all their | objects. After getting a taste of a good type system, people | naturally want to go all the way. | | If TS doesn't figure out how to provide this in a nice way, I | imagine there will be a fork or a new dialect eventually, or | JS will get types added natively like you say, and lots of | people will move in that direction. | barrkel wrote: | Probably the single biggest practical thing it did was fix | `this` via `=>` when using jQuery or jQuery-based frameworks | like Backbone.js. This didn't feel like the future so much as a | fix for a giant painful wart in JS. | | The second nicest thing about it was the way it eliminated a | lot of ceremonial redundancy around code, parentheses in | particular. Just like Ruby, it's not actually a great idea to | leave those out due to ambiguities, but when you want a micro- | DSL to encode some pattern, it really helps reduce the | syntactic noise. | | Third thing was being opinionated about how you structure | classes and objects. This, again, didn't feel like the future; | it felt like papering over a big gap in JS. | karatestomp wrote: | Yeah, just getting rid of the "interesting I guess but I'd | never use them on purpose because they're just not helpful | and likely to cause confusion or bugs" parts of JS, like | direct fiddling with prototypally-inheriting objects (ew), | worrying a bunch about what "this" means and shuffling it | around for little to no useful reason, or entirely-unhelpful | scoping rules. Most of those are better in regular JS now. | For me, the syntax was at best neutral, leaning toward | undesirable. I just wanted the extra ergonomics and safety, | which didn't require such a departure from JS. | fourseventy wrote: | I worry about the long term viability of using an offshoot | language of Javascript such as Coffeescript or Typescript. These | types of languages have a habit of falling out of vogue and | basically becoming a dead language, which is exactly what | happened to coffeescript. If a company decided to write an app in | coffeescript in 2010, today they have a big pile of code written | in a dead language on their hands. If instead the company had | chosen a mainstream language with a guaranteed future such as JS, | Java, or c# it wouldn't be an issue. | ryanianian wrote: | Typescript is nice in that it's a superset (mostly) of js. That | doesn't mean it won't fall out of vogue, just that in a lot of | cases converting from TS to JS is mostly straightforward, so | you can "just" remove some type information and end up with | valid JS. | city41 wrote: | You should be able to let tsc do it for you with a properly | configured tsconfig file. Mostly just want it to not emit any | polyfills. | heipei wrote: | What do you mean by dead? It's still maintained and developed | and still works great. Yeah, not many people are using it for | new projects so if you're anxious about using something with | the biggest "mindshare" then Coffeescript isn't for you, I give | you that. ___________________________________________________________________ (page generated 2020-05-15 23:00 UTC)