In open source, it's lovely, and fairly rare, to see someone pick up the ball on a quiet project, and run with it to completion without getting frustrated or losing interest first.
Geoffrey Booth — with big assists from Simon Lydell and Chris Connelly — has really gone the distance here, spending a full year working on drafts of CoffeeScript 2.0 to upgrade it from a language designed around ES3, to make it as ES6+ friendly as possible.
And GeoffreyBooth coordinated the effort, posting regular status updates & calls for help, handling bugs / feature requests, etc. I didn't realize he was also writing most of the code!
CoffeeScript2 started with a manifesto at https://github.com/coffeescript6/discuss which turned into a cooperative effort with jashkenas to move CoffeeScript forward in a responsible way. An interesting story in its own right.
I can't imagine CoffeeScript will see much adoption these days as most people seem to think ES6+ is "good enough". I miss how concise functions are in CoffeeScript and also miss being able to do object literals without the braces. But there's no chance at all in convincing my team to adopt it, as modern JS really is "good enough".
Thank you! I love CoffeeScript! It's been so sad to see it slowly fade away in favor of, in my opinion, inferior and uglier things. I -- and many others, I'm sure -- appreciate this update a great deal. I hope I get to write beautiful CoffeeScript code again soon.
To parent post, why should we settle for "good enough"?
Hey, I'm working on a template language that compiles into Redux + IncrementalDOM. Part of it involves a pipeline syntax similar to underscore or lodash. I'm wondering what you would consider a modern equivalent of those two libraries using native methods, iterators, etc. or if vanillajs is sufficient now.
If anyone wants to take a look it's at tmzt.github.io/isymtope and github.com/tmzt/isymtope
The #cleanup-symbols branch is much further along and has a mostly working TodoMvc.
Hmmm. If you're doing the compilation yourself, I'd imagine you could rely on what browsers provide these days, and compile to what you need. For the kinds of data transformations that templates tend to need, I wouldn't imagine that you'd really find a utility library to be necessary. Check out the Svelte output, for example.
I still use CS every day on multiple projects. IMAO CS is one of the best non-typed languages out there. It's really sad that so many modern/babel JS proponents fail to see the beauty of it.
I hope that this release (and hopefully future releases) will help to keep CS alive. Thanks to all contributors!
I think it's worth remembering too that the reason JS is "good enough" for most these days is because of all of the great language features that you and friends put into CoffeeScript and which then got adopted by JS.
I was browsing the CoffeeScript docs and everything looks much more concise. It seems like your code would half the size. Have people done real world comparisons on large code bases? Rewrites?
We did. And had to "decaffeinate" everything a few months later because it is hell to work with implicit returns, objects without brackets, no spread operator, significant whitespace, no variable declaration keyword...
It really is a matter of taste, but the large majority of us didn't like it. It is pretty, but I felt like fighting against the language all the time (implicitly returning an bracketless object is not something that's easily readable)
In my experience it has only been a problem when porting existing code bases. We only had to be a bit careful putting a return after a for loop at the end of a function so it doesn't build a list unnecessarily (otherwise implicit returns of unused random values don't hurt). For clarity, one of the few rules we have is to use return explicitly when a function is more than a single expression.
> objects without brackets
The language allows it but it doesn't mean you must use them. We have a loose style guide where we forbid a few confusing uses (like bracket-less one liners or returned objects). So loose it's shorter than this comment.
> no spread operator
It always had a spread operator (except for the first month of life). It's just called splat instead of spread, like in Python. Now it also allows ES6 syntax which is very similar (...foo vs. foo...).
> significant whitespace
That's not a bug, it's a feature ;)
> no variable declaration keyword
In the last year or two, that only bite us once. If it's more frequent than that your functions are way too long.
From the perspective of how it was intended to be used, you've got it exactly right. Just because you can implicitly return a braceless object, doesn't mean you should.
some colleagues of mine have complained about the significant whitespace being difficult to understand. i can't argue with something subjective like that.
however i like to point that our entire codebase, CS, JS, TS, Python, Java, Swift, 100% of it already has significant whitespace.
...it's just that the JS/TS/Java also have curly brackets.
No, twykke is saying that in almost every language, even ones that don't technically have significant whitespace, people still use coding conventions and style guides that restrict whitespace to match the curly braces. Some people even use automated commit hooks to reject commits that don't follow the guide.
The end result (or arguably, driving force) is that even in languages where whitespace isn't significant, people read the whitespace, not the curly braces. So the curly braces are basically redundant noise.
I agree about { } being mostly noise but I think they are the lesser evil. I'm making most of my money with Python and I still believe significant whitespace is a very bad idea. The Ruby alternative of using end is better even if not super elegant (and Ruby is my language of choice). It's on par with curly braces. After 30+ years of programming I still have to find a satisfying solution to the problem.
This mirrors my experience as well. Try having a relatively simple piece of code exhaust all available memory because CS was kind enough to turn a simple loop into a clusterfuck of epic proportions all because you forgot to return null on a function that well, doesn't need to return anything. Then you go and decaffeinate the entire thing, actually look at the JS output and your jaw drops at the amount of useless crap that your "syntactic sugar" added. Is it really worth it?
This could easily be fixed by adding a -!> operator that disables implicit returns, but no, they are so opinionated that a change like that will ruin their perfect little universe. I know that there are forks that add this sort of functionality among fixing some of my other gripes with CS but my point still stands: I'm not going to invest my time into a cult.
Yes, CoffeeScript is chaos. I've found that CS's biggest proponents can be heard to say "Let's just replace it with a custom thing I'll build this weekend" much more frequently than normal. Surely this is coincidental. ;)
The old joke was that Perl is a write-only language, and CoffeeScript et al are essentially thought experiments for how deep into the write-only abyss people are willing to plunge as a non-joke. It's no mystery that CS primarily attracts people who heavily discount the importance of long-term maintainability.
The core issue seems to be that some people have conflated prescience with elegance. We must stop deluding ourselves into pretending there are languages that can read our minds. Put your intent in the code, avoid ambiguity. If the answer is not obvious and consistent, do not rely on either the computer or the human to extract your intent from the ether.
The only reason most people used CS was short hand function declaration and classes, It really made writing javascript easier as dealing explicitly with prototypes is a pain in the ass AND it also eliminated differences between browsers when it came to JS implementation (yes IE8 was still a thing back then).
All these things are irrelevant today.
1/ Most of CS features are supported by javascript
2/ ECMASCRIPT spec is big and complex. Learning another syntax on top of something every front end developer should know is a wasted effort in my opinion.
> The only reason most people used CS was short hand function declaration and classes
And for loops (which double as list comprehensions). And the existential operator. And "this." shorthand. Among other reasons. To my team it's also more clean-looking than Python (which used to be my favourite language), esp. when using a good syntax highlighter like Atom's (or at least that differentiates function calls, like Github's).
Yes, there's not much difference now from ES6 regarding features, but for some of us it's still worth it.
I miss some elements of coffeescript (the existential operator was really cool), but I think in some ways it served its purpose: large parts of it were lifted for use in es6.
These days we have typescript as another option, and I feel like there's more gains from that than the syntactic niceness of coffeescript.
i really wanted to like coffeescript, but the idea of compiling, transpiling or any other kind of piling of javascript just rubbed me the wrong way. this is true of scss, less and other css flavors too.
i understand the problems these tools are trying to solve, but i don't like that you have to learn two (or more) grammars and syntaxes, and the quirky interactions between them, to get those benefits (because you can't debug one without debugging the other). it's a lot more cognitive overhead for what amounts to a little syntactic sugar.
standard es-whatever javascript needs to be "good enough", and, despite my disdain for using coffeescript, the improvements that coffeescript induced in javascript are heartily welcomed.
If you automate it and it's part of your deployment pipeline, you'd hardly notice it's there. We use both SCSS and CS via Rails and it's a breeze. The occasional times when I don't understand why something is not working I go to the coffeescript website and read the transpiled code and it's usually obvious what's going on.
I honestly think both ES6, Coffee and the like are going in the absolute wrong direction. Every release replaces more keywords with punctuation marks. That's the reason the community abandoned Perl. How much productivity do I gain by replacing "function()" with "() =>"? Round and round we go.
Before anyone tells me, yes I know the semantics are slightly different, but muddling the semantics with arcane syntax is not an optimal solution.
I think the comparison to perl isn't fair. It's pretty accepted that () => is a function type construct. It mimics lambdas and function calls in many other languages. Perl did really crazy stuff like storing regex results in obscure global variables.
As for () =>, it can make a big difference in scenarios like `myArray.map(a => a.foo)` versus `myArray.map(function(a) { return a.foo })`
>> Every release replaces more keywords with punctuation marks.
I can't think of any other examples. Closures get used heavily in JS and arrow functions do make their use quicker and more concise, as well as fixing `this`. Compared to other languages like Scala, OCaml, Elm and Haskell, with symbols for functional combination and pipelining, pattern matching, and whatever you call the thing where you can miss out parameters and use underscores in function bodies in Scala ... JS is relatively light on symbols.
I’m going to tell you anyways :-D. function() { ... }.bind(this) is the correct comparison to () => { ... }, which is not only a productivity gain but a readability gain.
CoffeeScript has lost a lot of adoption after Typescript and ES6 gaining its turf. But by all means it's a good wrapper to JavaScript. Congrats on shipping.
Wait, using the arrow function notation doesn't bind this, arguments, super, or new.target[1] in javascript, as opposed to the normal function syntax. Not being a user of coffeescript, did coffeescript not do that already, or did they also throw in code to change that in the generated code?
It seem to me it would make sense to map items that match conceptually, not just notationally (unless it's common to have both coffeescript and JS side by side). Can someone comment on how this is handled?
Javascript's => doesn't bind this though, and function does, which was my point (and is what the reference I included was saying). That's a specific change in JS, and either coffeescript had code in place to emulate the current behavior in prior versions where they used function(), or they have code in place now to emulate function() now that they're using =>.
I'm going to update my original comment to be a bit more clear on what I was saying.
Old Coffeescript behaviour for => was to use a function where this was bound to that of the environment. This seems subtly different from having this not being bound at all (in that you can't rebind it under the new translation), but that's unlikely to have been a common use case.
The main other difference seems to be that there is no arguments object for the local function anymore, although once again that's unlikely to be a problem in most functions defined with a fat arrow.
As someone else also said, there were two ways to define functions, one using =>, one using -> the latter maps to a normal JS function.
> Old Coffeescript behaviour for => was to use a function where this was bound to that of the environment.
Okay, so it sounds like coffeescript 1.0 => was effectively doing what JS => does now, so it makes sense to move to the newer JS syntax Thanks for elaborating! (It's interesting how "binds this" can, and was interpreted in multiple ways, Perhaps there's a better, more specific wording I could have used to cut through those misunderstandings, whether they be with those that replied or me reading their replies).
I think we're getting our wires crossed. Both Javascript and CoffeeScript have (more or less, for the common use cases) the same `this` behaviour for =>. It preserves the `this` value from the context.
Yes, that's what was explained in the sibling. There's a lot of confusion on what "binds this" can mean, and while I thought you might have been misinterpreting me, I may have been misinterpreting you. I was using the terminology that MDN uses in reference to the function arrow, but in the context of this question, some additional elaboration might have been useful to distinguish exactly what "this" is when it's bound (the calling environment, or the current subject being called on as is often the case).
You have it backwards. => in JS binds this, and => in coffee used to bind this also but now just emits JS' =>. => in JS was pretty much taken from coffee, there was no prior version of => in JS.
Coffee also has -> which desugars to a regular function() {}
I don't know what to think about coffeescript anymore. I love it back then before babel and ES6, but right know I didn't even know how to use coffee and a library used today.
Still miss the python/ruby-sque sintaxt witouth brackets.
Edit: After reading more about the changes about CS 2.0, I may give it one more chance, let's see how it work now.
First off thank you for Underscore, Backbone and CoffeeScript. Your work really has helped me and my development team.
This question is a little off topic but one I've been wanting to ask for a long time:
Last year you took a year off from The New York Times to ride your motorcycle across the Western Hemisphere. Just recently you were hired back at the paper, doing what it appears to be the same thing in the graphics department.
From a hiring perspective, did you have to reapply for your job, or did the Times just give you the necessary time off?
If this was considered a "sabbatical," how did you justify traveling around the Americas as something that could benefit the paper?
I don't mean to offend. I'm genuinely curious. A lot of people aren't fortunate enough to take a year off for traveling and then be rehired at their company, especially in the journalism industry with the revenue declines, job cuts and managers wanting to hire cheaper people.
I can't answer for him. but it would seem to me that there is a pretty universal shortage of quality developers, much less superstar developers familiar with your existing codebase. Rehiring him would be a no-brainer.
That is a good point. The NYT is responsible for other awesome tools: d3.js, ai2html, etc.
I'm sure if the company has a person who creates a tool that is used all over the world under its watch, they would allow that person to take as much time off as he or she needs.
Still, I know people who are --- no pun intended -- the backbone of codebases at their company, and taking a year off and being rehired is out of the question.
What's to stop the company from finding a replacement who can be up to speed with the code in a short amount of time?
>What's to stop the company from finding a replacement who can be up to speed with the code in a short amount of time?
The fact that it's very, very hard and the competition is fierce?
Also, this is not a romantic relationship we're talking about. If you leave your place of work, no matter how irreplaceable you are the company is going to carry on as best they can. If a year later you are available again and they still need a person for this position that they know you would fit well, why would they not rehire you?
I think that something else to take into consideration is that hiring good people is a non-trivial problem. Folks can do well in a interview and seem amicable and then turn out to be incompetent and/or jerks later. So there is substantial risk in hiring. It seems like knowing for certain that someone is competent and works well with the rest of the team is worth A LOT.
Graphics editors are also developers if they are writing code to make graphics, i.e. every newspaper's graphics team that has made interactive projects.
Happy to answer, although this is a bit of a funny forum for it:
From a work perspective, it's pretty simple. I quit, and then was rehired to the same position a year later.
But The Times' Graphics Desk was super nice about it. We had a handshake agreement that I'd come back when I got back, and they even lent me a laptop to maybe file some travel-ish bits and bobs from along the road. So in that sense, it was partially justified.
In the end I didn't end up writing anything for them for a few reasons: I didn't want to turn the ride into work; I wasn't on my best NYT-standards behavior (booze, bribes, women) — well, one spectacular woman, and we're married now; and finally, I personally hew somewhat to the Janet Malcolm attitude:
“Every journalist who is not too stupid or full of himself to notice what is going on knows that what he does is morally indefensible. He is a kind of confidence man, preying on people's vanity, ignorance, or loneliness, gaining their trust and betraying them without remorse.”
Especially with respect to travel writing. You can do it right, but you really have to take the time and be invested and involved. And I was riding to follow the seasons and wasn't.
Ultimately, even though the industry as a whole is in decline, the NYT and other world-class news sources are still strong, and in some ways, getting stronger. In particular, the visual journalism The Times publishes every year keeps pushing the state of the art.
Nothing too spectacular, I've got enough Spanish to talk through all of the border crossing paperwork comprehensively, which helps avoid problems with papers down the line.
You have to get a temporary import/export permit and country-specific insurance every time you cross a border. I ended up crossing 33, so that's plenty of paperwork to potentially get fouled up on. And in some countries checkpoint cops love busting gringos for their paperwork, because if they're missing something mandatory, that's easy money.
I screwed up the US/Mexico border first by not having done my research. Crossing from Presidio to Ojinaga, I made sure to get Mexican insurance, but didn't think to set Banamex bond for the temporary import permit — not required in the border zone, so the customs officials don't mention it. I didn't have it, and if any official in the length of Mexico had asked me for my paperwork (despite passing multiple checkpoints), that would have been full legal grounds to seize the bike. But I made it to the Guatemalan border trouble-free, and the customs exit officer nailed me for it there. "It's easier if you just pay me the fine." Around $50, I think. I got change from his wallet.
The second not doing my research screwup was not bringing my original title document to the motorcycle with me, just some color photocopies. In most cases, copies are fine — after all, we don't drive around with our titles in our glove boxes. But leaving El Salvador, at the Honduras border, a cop in front of the immigration building decided to make an issue of it. "I'm sorry, but without the original title document, there's nothing that can be done." After about half an hour, with some help from a roadside border-crossing fixer (there are many on the El Salvador / Honduras border, because these situations are notorious there) and a little over $200, the bike and I were through.
Of course, the first thing I did after arriving in Choluteca, Honduras, was to head over to the police station and file a false report, saying that I had left the original title in the top bag of the motorcycle and someone had stolen it, along with a few other miscellaneous documents. When getting yourself out of paperwork trouble, an officially stamped police report is as good as gold. From that point on, at any border where the photocopied title wasn't good enough (Peru, in particular, gave me a really hard time about it), I could show them the police report, show them that the VIN on the report matched the VIN on the photocopied title matched the VIN on the bike, and we were good to go.
Are you kidding? Spin the bit about the border-crossing fixer into a homily about capitalism, italicize a list of the meats you ate, and you've got a Friedman column.
> In the end I didn't end up writing anything for them
I understand that you didn't write anything professionally about your trip, but did you ever write anything casually about it - blog posts or the like? It sounds like it would make for interesting reading :)
This isn't recommended. If you quit the company, that shows you obviously do not want to work for them.
If you quit once, what's the likelihood you'll quit again? And how soon? Why waste everyone's time? You'll need to make a seriously good case as to why the company should rehire you.
In Jeremy's case, he wrote a lot of code that a lot of people use around the globe. That adds a lot of value to him. Luckily, for him, the NYT is lenient to bring him back on the job.
Just ask! And if it's not ok, do it anyway and then get another job. Maybe this is more common over here in europe but basically everybody who really wants to travel does it like this.
On my travels (mostly most of asia, south and middle america, some europe) I have met nurses, doctors, military doctors, journalists, devs (a lot), sound engineer, hair stylists, bankers (he was hilarious), DJs, salespeople, night watchman, ....
Travelling the world gives you more experience, more insights and more perspective than just being another desk jockey like everybody else in the company.
Also never let your actions be determined by fear ("will not be hired again, will not be as valuable in the workforce if I travel for a year, ..."). if you want to travel, just do it. (and read books about stuff that really interests you while you do it.)
And: companies are usually not nice, but the people within companies are most of the time pretty decent, and they usually like people which just do their thing.
While I understand the let vs var thing, I wish I could tell the compiler that I promise not to non-obviously reference a local var (e.g. in an eval). Then CoffeeScript could determine it is only written at decl time and could use const. Technically, this could be used for var scoping too in the let vs var issue.
> Keep in mind that const only protects you from reassigning a variable
While I haven't looked, I'd suspect there are performance implications too.
First congrats, this is hard-work. Second I implore people not to use a language where the designers think breaking changes are OK, while giving no real advantage over plain modern Javascript or the use of a linter. Worse, since CS has slighly different semantics than JS it will lead to so much confusion. Coffee Script served its purpose, now let it rest.
>Second I implore people not to use a language where the designers think breaking changes are OK
This is a big deal when you also have to use libraries written in the same language. Python 3 being a fundamentally different language (the underlying bytecode is not backwards compatible) from Python 2 made the transition very difficult.
However, this will never be a problem for a javascript transpiler.
And also, the list of breaking changes really isn't too incredible. I imagine it'll be fine for most coffeescript projects to take this update quite liberally, as it shouldn't be too hard to write CoffeeScript 1.x/2.x polyglot code to transition to the new version.
So great to see a good release after all these years. Congratulations to all!
I'm curious though about what happened to the Kickstarter project that took a few grand to write what was to be "CoffeeScript 2" at the time - did any of that code end up in this release?
Although Geoffrey and folks considered a rewrite of the compiler along the lines of Michael Ficarra's CoffeeScriptRedux, they decided it was more pragmatic just to work with the existing compiler and get it to produce Modern JS instead of the Lowest-Common-Denominator JS it previously output.
A wise choice, especially given 2017 interest and energy levels.
Edit: To be clear, to the extent anything can or can not be considered official in open source, Michael's project was his project, and never made it in to the main repo. We encouraged it just as we'd encourage anyone to try and make an independent implementation — but CoffeeScript has never asked for financial support.
Agreed, getting this upgrade out the door in 2 months is a monumental achievement and I can't imagine a full rewrite happening at anything close to that pace. I'll be happily hacking away with CoffeeScript 2 + Crystal this weekend! Thanks for being awesome :)
CoffeeScript is still very relevant for me. I have two medium-sized Ember projects written in CoffeeScript (and Emblem and Sass--the original, indented variety, thank you very much).
I have been looking at React (will probably skip due to the patent license) and Vue, but cannot imagine going back to semicolons and (excessive) curly braces and parens.
If you married CoffeeScript just out of convenience (being able to avoid prototypes, bind, etc.), then it no longer serves much of a purpose. But if, like me, you fell in love with CoffeeScript's beauty, then no amount of ES6+ features will make it obsolete (as long as you can also keep using those features directly in CoffeeScript).
i also don't use CoffeeScript because of any 'feature' it has over standard JS but instead because of its concise but expressive syntax. it's less about what it does have/do, and more about what it doesn't have/do.
some small aspects of CS i forgo because they (in my opinion) are a little too concise such that they sacrifice readability, but all in all it has my favorite syntax of any language.
I personally think calling .map() on an array is more readable than an array comprehension. But since CS is "just JavaScript" you are free to use the native JS array methods (and even more elegantly, at that).
list comprehensions was exactly what i was talking about :) however i replace them with lodash and ramda, which benefit enormously from CS's lambda syntax
Sure, but other coffee operations like x||=5 are also abominations. Brevity and purity are often at odds and the choices made by a language can be arbitrary.
Actually, Javascript does not require semicolons to be present. If you skip them, the only edge-case is when you try to start your line with `[` or `(`. In that case, you can prefix the line with `;`.
Omitting semicolons breaks the "delete a line in isolation" rule, unless you begin the line with a semicolon instead. Which is even noiser than just having them at the end of the line, where they are unconsciously glossed over by anyone who's ever worked in a language with C-derived syntax.
I hear this a lot, but in ~4 years writing JavaScript without semicolons, I've had to do this maybe two or three times. I just don't feel like starting a line with [ or ( is very common, to the point that it's a complete non-issue to me.
In the majority of cases you can't "delete a line in isolation", because it's part of a program. You have to look around and understand what the impact of deleting that line will be -- and modify nearby lines as necessary.
You should write tests when building a project in a dynamically typed language to alleviate some paranoia anyway. As long as you have decent test coverage and use a decent linter/formatter such as StandardJS[0] or prettier[1], you'll be fine.
Yeah, if your linter/build tool can't handle Javascript that doesn't have semicolons, it should be considered fundamentally broken and/or incomplete.
So the question to me becomes, if the build tool doesn't correctly parse the JS that's lacking semicolons, should you really trust that build tool with the rest of your code? You already know at that point that it doesn't handle your otherwise-valid semicolonless JS correctly.
I loved CoffeeScript, but I felt it was a double edged sword.
I would still use it though, if there were JSX style xml/html tags. But React changed everything for me and as a full stack dev, I can use only few frameworks on one level.
And I'm glad they broke the different behaviour of =>. It might need a fix in a lot of code bases, but this price is cheaper than having the mental burden of it.
I personally can't stand jsx, and coffeescript makes it so much nicer to avoid when using React. It's almost like haml / slim / jade / pug if you know what I mean.
Elm... And not to forget PureScript... and to a lesser extend ReasonML (by which you can still use React and JSX)... and Haskell/GHCJS. There are quite a lot of ways to seek refuge from both type scarcity and the "semicolon" line noise that was mentioned.
Here some benchmarks for several of the FWs that are popular in these languages (Elm has the FW built-in, ReasonML-React is missing but should be close to React.js).
I'm not a big fan of the new =>, it means the arguments variable will have parent scope in => but not in ->, it kind of erodes into coffeescript's elegance/consistency imho, unless I'm missing something ?
I never used => but when JavaScript introduced the fat arrow and made it different from the fat arrow in CoffeeScript, this introduced a mental barrier for me. By definition, the JavaScript fat arrow is the important one to know.
Sure, but there used to be a strong performance advantage when using the arguments variable with function.apply, also editing arguments' values affected named parameters' values (not sure that's desirable, but you know, semantics)
I felt the same way when I switched from CoffeeScript to TypeScript but the type checking was worth all the braces, returns and lack of existential operator. If CoffeeScript added an (optional) type system I'd switch back in an instant.
> If CoffeeScript added an (optional) type system I'd switch back in an instant.
The home page talks a little about achieving this by using Flow annotations in Coffeescript source and then having the build system pass the Javascript output to Flow: http://coffeescript.org/#type-annotations
This is cool! That being said, it would be very nice to have (optional) syntactically more beautiful type annotation. I assume Flow must be compatible with regular javascript, but CoffeeScript could take more flexible approach. I have no idea what the actual syntax could be, though.
With Vue.js you can use Coffeescript (alongside others) as well as SCSS, Pug, etc in single file components using lang="coffee" attribute in the script (or style or template for the others) tag.
Need to add a couple more dependencies to your package.json but it works like a charm.
It's easier when you use something like Prettier which formats the code for you, same workflow as coffeescript except less work and possibly more readability.
Might I suggest trying out JavaScript Standard Style [0]? It has editor plugins and a CLI tool for linting.
You can write JavaScript just fine without semicolons. I used to be in the same camp, but Feross eventually convinced me to try dropping em. Despite being cautious and a bit skeptical, I tried it out in a few projects by removing all semicolons with a search and replace. In every single case, I encountered zero issues.
Maybe it's just me, but I can't imagine dealing with scope without those little curly braces. They give a definitive beginning and end I can see, rather than trust my indents are correct. But maybe I just didn't give Coffeescript enough time to get used to it.
Never used CoffeeScript in anger, and I don't see it regaining the level of hype it once had, but despite its lack of dominance I think it emphatically suceeded in helping to push Javascript towards its modern (and much improved, IMO) incarnation. A good recent example of how a technology doesn't need to capture marketshare in order to have a positive impact on the market.
As a CoffeeScript fan things were looking pretty bleak a year or two ago. In particular there was zero momentum for new features.
How things have changed! Major kudos to Geoffrey Booth and all involved. Coffee's beautiful syntax combined with async/await has taken a lot of the 'ick' away from coding in JS, at least for me.
having used Coffeescript almost exclusively (in the Node.js world) for something like 6 years, async/await was the only feature i have been gnashing my teeth waiting for, but i wasn't even that impatient because i have also been using Fibers for just as long.
I think its likely that at some point in the future cs will get strong type support. Iirc the creator is opposed to it but theres interest from others.
Augh. Anytime I see a Coffescript project all I see is wasted money trying to recruit engineers who actually want to use it. 90% of people who write JavaScript roll their eyes and move on.
Another way to look at it: you will only draw developers who share your appreciation for whitespace-significant languages.
I have worked on two startups with a fellow programmer who knew Python but not CoffeeScript. He picked it up very quickly, along with Emblem (indented Handlbars alternative, useful for Ember projects) and indented Sass. Once we told the text editor to insert 4 spaces in place of tabs, we had much less to worry about in terms of stylistic disagreements.
Since you were changing everything, I thought it would include a bunch of new revolutionary syntax and features, just like Coffeescript 1 did many years ago and made the world jump into ES6+.
Since this is just keeping up with the already existing ES6, why would anyone bother to move from ES6 to Coffee?
219 comments
[ 3.8 ms ] story [ 283 ms ] threadhttp://coffeescript.org/#breaking-changes
Edit: Seems that my computer doesn't consider the cert authority valid for bootstrapcdn.
Geoffrey Booth — with big assists from Simon Lydell and Chris Connelly — has really gone the distance here, spending a full year working on drafts of CoffeeScript 2.0 to upgrade it from a language designed around ES3, to make it as ES6+ friendly as possible.
https://github.com/jashkenas/coffeescript/commits/master
He also redid the website and the docs for good measure: http://coffeescript.org/
Bravo.
A bunch of people helped out: https://github.com/jashkenas/coffeescript/wiki/CoffeeScript-...
And GeoffreyBooth coordinated the effort, posting regular status updates & calls for help, handling bugs / feature requests, etc. I didn't realize he was also writing most of the code!
CoffeeScript2 started with a manifesto at https://github.com/coffeescript6/discuss which turned into a cooperative effort with jashkenas to move CoffeeScript forward in a responsible way. An interesting story in its own right.
CoffeeScript has saved me thousands of hours of parentheses closing alone.
But for the folks who still do — or have existing codebases — this update is for you.
To parent post, why should we settle for "good enough"?
Because it's an actual standard and benefits from wider mindshare and support.
If anyone wants to take a look it's at tmzt.github.io/isymtope and github.com/tmzt/isymtope
The #cleanup-symbols branch is much further along and has a mostly working TodoMvc.
I hope that this release (and hopefully future releases) will help to keep CS alive. Thanks to all contributors!
It really is a matter of taste, but the large majority of us didn't like it. It is pretty, but I felt like fighting against the language all the time (implicitly returning an bracketless object is not something that's easily readable)
In my experience it has only been a problem when porting existing code bases. We only had to be a bit careful putting a return after a for loop at the end of a function so it doesn't build a list unnecessarily (otherwise implicit returns of unused random values don't hurt). For clarity, one of the few rules we have is to use return explicitly when a function is more than a single expression.
> objects without brackets
The language allows it but it doesn't mean you must use them. We have a loose style guide where we forbid a few confusing uses (like bracket-less one liners or returned objects). So loose it's shorter than this comment.
> no spread operator
It always had a spread operator (except for the first month of life). It's just called splat instead of spread, like in Python. Now it also allows ES6 syntax which is very similar (...foo vs. foo...).
> significant whitespace
That's not a bug, it's a feature ;)
> no variable declaration keyword
In the last year or two, that only bite us once. If it's more frequent than that your functions are way too long.
But as you say, it's a matter of taste.
however i like to point that our entire codebase, CS, JS, TS, Python, Java, Swift, 100% of it already has significant whitespace.
...it's just that the JS/TS/Java also have curly brackets.
The end result (or arguably, driving force) is that even in languages where whitespace isn't significant, people read the whitespace, not the curly braces. So the curly braces are basically redundant noise.
I agree about { } being mostly noise but I think they are the lesser evil. I'm making most of my money with Python and I still believe significant whitespace is a very bad idea. The Ruby alternative of using end is better even if not super elegant (and Ruby is my language of choice). It's on par with curly braces. After 30+ years of programming I still have to find a satisfying solution to the problem.
This could easily be fixed by adding a -!> operator that disables implicit returns, but no, they are so opinionated that a change like that will ruin their perfect little universe. I know that there are forks that add this sort of functionality among fixing some of my other gripes with CS but my point still stands: I'm not going to invest my time into a cult.
The old joke was that Perl is a write-only language, and CoffeeScript et al are essentially thought experiments for how deep into the write-only abyss people are willing to plunge as a non-joke. It's no mystery that CS primarily attracts people who heavily discount the importance of long-term maintainability.
The core issue seems to be that some people have conflated prescience with elegance. We must stop deluding ourselves into pretending there are languages that can read our minds. Put your intent in the code, avoid ambiguity. If the answer is not obvious and consistent, do not rely on either the computer or the human to extract your intent from the ether.
All these things are irrelevant today.
1/ Most of CS features are supported by javascript
2/ ECMASCRIPT spec is big and complex. Learning another syntax on top of something every front end developer should know is a wasted effort in my opinion.
And for loops (which double as list comprehensions). And the existential operator. And "this." shorthand. Among other reasons. To my team it's also more clean-looking than Python (which used to be my favourite language), esp. when using a good syntax highlighter like Atom's (or at least that differentiates function calls, like Github's).
Yes, there's not much difference now from ES6 regarding features, but for some of us it's still worth it.
These days we have typescript as another option, and I feel like there's more gains from that than the syntactic niceness of coffeescript.
i understand the problems these tools are trying to solve, but i don't like that you have to learn two (or more) grammars and syntaxes, and the quirky interactions between them, to get those benefits (because you can't debug one without debugging the other). it's a lot more cognitive overhead for what amounts to a little syntactic sugar.
standard es-whatever javascript needs to be "good enough", and, despite my disdain for using coffeescript, the improvements that coffeescript induced in javascript are heartily welcomed.
This isn't really accurate with respect to meta languages like SCSS that add new features not present in the underlying language, like variables.
You really are missing out on a lot by not using the meta languages.
Well, this is how a lot of JS (if not most) is done today anyway.
Before anyone tells me, yes I know the semantics are slightly different, but muddling the semantics with arcane syntax is not an optimal solution.
As for () =>, it can make a big difference in scenarios like `myArray.map(a => a.foo)` versus `myArray.map(function(a) { return a.foo })`
I can't think of any other examples. Closures get used heavily in JS and arrow functions do make their use quicker and more concise, as well as fixing `this`. Compared to other languages like Scala, OCaml, Elm and Haskell, with symbols for functional combination and pipelining, pattern matching, and whatever you call the thing where you can miss out parameters and use underscores in function bodies in Scala ... JS is relatively light on symbols.
It's not that ES6 is good enough; it's that CoffeeScript is actually "bad".
Wait, using the arrow function notation doesn't bind this, arguments, super, or new.target[1] in javascript, as opposed to the normal function syntax. Not being a user of coffeescript, did coffeescript not do that already, or did they also throw in code to change that in the generated code?
It seem to me it would make sense to map items that match conceptually, not just notationally (unless it's common to have both coffeescript and JS side by side). Can someone comment on how this is handled?
1: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Edit: Added "in javascript" after reference to make it obvious I was talking about JS behavior for the binding.
http://coffeescript.org/#breaking-change-fat-arrow
Seems to map fairly well conceptually.
Javascript's => doesn't bind this though, and function does, which was my point (and is what the reference I included was saying). That's a specific change in JS, and either coffeescript had code in place to emulate the current behavior in prior versions where they used function(), or they have code in place now to emulate function() now that they're using =>.
I'm going to update my original comment to be a bit more clear on what I was saying.
The main other difference seems to be that there is no arguments object for the local function anymore, although once again that's unlikely to be a problem in most functions defined with a fat arrow.
As someone else also said, there were two ways to define functions, one using =>, one using -> the latter maps to a normal JS function.
Okay, so it sounds like coffeescript 1.0 => was effectively doing what JS => does now, so it makes sense to move to the newer JS syntax Thanks for elaborating! (It's interesting how "binds this" can, and was interpreted in multiple ways, Perhaps there's a better, more specific wording I could have used to cut through those misunderstandings, whether they be with those that replied or me reading their replies).
I think we're getting our wires crossed. Both Javascript and CoffeeScript have (more or less, for the common use cases) the same `this` behaviour for =>. It preserves the `this` value from the context.
Coffee also has -> which desugars to a regular function() {}
Edit: After reading more about the changes about CS 2.0, I may give it one more chance, let's see how it work now.
First off thank you for Underscore, Backbone and CoffeeScript. Your work really has helped me and my development team.
This question is a little off topic but one I've been wanting to ask for a long time:
Last year you took a year off from The New York Times to ride your motorcycle across the Western Hemisphere. Just recently you were hired back at the paper, doing what it appears to be the same thing in the graphics department.
From a hiring perspective, did you have to reapply for your job, or did the Times just give you the necessary time off?
If this was considered a "sabbatical," how did you justify traveling around the Americas as something that could benefit the paper?
I don't mean to offend. I'm genuinely curious. A lot of people aren't fortunate enough to take a year off for traveling and then be rehired at their company, especially in the journalism industry with the revenue declines, job cuts and managers wanting to hire cheaper people.
Thanks again for all you've contributed.
I'm sure if the company has a person who creates a tool that is used all over the world under its watch, they would allow that person to take as much time off as he or she needs.
Still, I know people who are --- no pun intended -- the backbone of codebases at their company, and taking a year off and being rehired is out of the question.
What's to stop the company from finding a replacement who can be up to speed with the code in a short amount of time?
The fact that it's very, very hard and the competition is fierce?
Also, this is not a romantic relationship we're talking about. If you leave your place of work, no matter how irreplaceable you are the company is going to carry on as best they can. If a year later you are available again and they still need a person for this position that they know you would fit well, why would they not rehire you?
If the former, then the company is an advantageous position to pick someone from the pool. It's not like ZERO people will apply for the job.
If you're talking about the latter, then it's irrelevant. I'm mainly focusing on the company.
The pool of people as talented as jashkenas, that are looking for a job, and want to work in the NY Times is tiny.
https://github.com/jashkenas
From a work perspective, it's pretty simple. I quit, and then was rehired to the same position a year later.
But The Times' Graphics Desk was super nice about it. We had a handshake agreement that I'd come back when I got back, and they even lent me a laptop to maybe file some travel-ish bits and bobs from along the road. So in that sense, it was partially justified.
In the end I didn't end up writing anything for them for a few reasons: I didn't want to turn the ride into work; I wasn't on my best NYT-standards behavior (booze, bribes, women) — well, one spectacular woman, and we're married now; and finally, I personally hew somewhat to the Janet Malcolm attitude:
“Every journalist who is not too stupid or full of himself to notice what is going on knows that what he does is morally indefensible. He is a kind of confidence man, preying on people's vanity, ignorance, or loneliness, gaining their trust and betraying them without remorse.”
Especially with respect to travel writing. You can do it right, but you really have to take the time and be invested and involved. And I was riding to follow the seasons and wasn't.
Ultimately, even though the industry as a whole is in decline, the NYT and other world-class news sources are still strong, and in some ways, getting stronger. In particular, the visual journalism The Times publishes every year keeps pushing the state of the art.
Kind of curious about the "bribes" part...
You have to get a temporary import/export permit and country-specific insurance every time you cross a border. I ended up crossing 33, so that's plenty of paperwork to potentially get fouled up on. And in some countries checkpoint cops love busting gringos for their paperwork, because if they're missing something mandatory, that's easy money.
I screwed up the US/Mexico border first by not having done my research. Crossing from Presidio to Ojinaga, I made sure to get Mexican insurance, but didn't think to set Banamex bond for the temporary import permit — not required in the border zone, so the customs officials don't mention it. I didn't have it, and if any official in the length of Mexico had asked me for my paperwork (despite passing multiple checkpoints), that would have been full legal grounds to seize the bike. But I made it to the Guatemalan border trouble-free, and the customs exit officer nailed me for it there. "It's easier if you just pay me the fine." Around $50, I think. I got change from his wallet.
The second not doing my research screwup was not bringing my original title document to the motorcycle with me, just some color photocopies. In most cases, copies are fine — after all, we don't drive around with our titles in our glove boxes. But leaving El Salvador, at the Honduras border, a cop in front of the immigration building decided to make an issue of it. "I'm sorry, but without the original title document, there's nothing that can be done." After about half an hour, with some help from a roadside border-crossing fixer (there are many on the El Salvador / Honduras border, because these situations are notorious there) and a little over $200, the bike and I were through.
Of course, the first thing I did after arriving in Choluteca, Honduras, was to head over to the police station and file a false report, saying that I had left the original title in the top bag of the motorcycle and someone had stolen it, along with a few other miscellaneous documents. When getting yourself out of paperwork trouble, an officially stamped police report is as good as gold. From that point on, at any border where the photocopied title wasn't good enough (Peru, in particular, gave me a really hard time about it), I could show them the police report, show them that the VIN on the report matched the VIN on the photocopied title matched the VIN on the bike, and we were good to go.
Like I said, not NYT-standards behavior.
Are you kidding? Spin the bit about the border-crossing fixer into a homily about capitalism, italicize a list of the meats you ate, and you've got a Friedman column.
I understand that you didn't write anything professionally about your trip, but did you ever write anything casually about it - blog posts or the like? It sounds like it would make for interesting reading :)
Thanks for the response. It seems your situation was unique, and you're definitely fortunate to have a department willing to make this agreement.
The Average Joe more than likely can't pull this off, especially if the company can hire a replacement.
just do it.
If you quit once, what's the likelihood you'll quit again? And how soon? Why waste everyone's time? You'll need to make a seriously good case as to why the company should rehire you.
In Jeremy's case, he wrote a lot of code that a lot of people use around the globe. That adds a lot of value to him. Luckily, for him, the NYT is lenient to bring him back on the job.
Some other companies aren't so nice.
Just ask! And if it's not ok, do it anyway and then get another job. Maybe this is more common over here in europe but basically everybody who really wants to travel does it like this.
On my travels (mostly most of asia, south and middle america, some europe) I have met nurses, doctors, military doctors, journalists, devs (a lot), sound engineer, hair stylists, bankers (he was hilarious), DJs, salespeople, night watchman, ....
Travelling the world gives you more experience, more insights and more perspective than just being another desk jockey like everybody else in the company.
Also never let your actions be determined by fear ("will not be hired again, will not be as valuable in the workforce if I travel for a year, ..."). if you want to travel, just do it. (and read books about stuff that really interests you while you do it.)
And: companies are usually not nice, but the people within companies are most of the time pretty decent, and they usually like people which just do their thing.
I loved the elegance coffeescript & it was the language that convinced me JS was a reasonable target.
Though I, like many, moved to TS, I use CS every day via its spiritual child es6.
> Keep in mind that const only protects you from reassigning a variable
While I haven't looked, I'd suspect there are performance implications too.
This is a big deal when you also have to use libraries written in the same language. Python 3 being a fundamentally different language (the underlying bytecode is not backwards compatible) from Python 2 made the transition very difficult.
However, this will never be a problem for a javascript transpiler.
And also, the list of breaking changes really isn't too incredible. I imagine it'll be fine for most coffeescript projects to take this update quite liberally, as it shouldn't be too hard to write CoffeeScript 1.x/2.x polyglot code to transition to the new version.
I'm curious though about what happened to the Kickstarter project that took a few grand to write what was to be "CoffeeScript 2" at the time - did any of that code end up in this release?
Although Geoffrey and folks considered a rewrite of the compiler along the lines of Michael Ficarra's CoffeeScriptRedux, they decided it was more pragmatic just to work with the existing compiler and get it to produce Modern JS instead of the Lowest-Common-Denominator JS it previously output.
A wise choice, especially given 2017 interest and energy levels.
Edit: To be clear, to the extent anything can or can not be considered official in open source, Michael's project was his project, and never made it in to the main repo. We encouraged it just as we'd encourage anyone to try and make an independent implementation — but CoffeeScript has never asked for financial support.
I have been looking at React (will probably skip due to the patent license) and Vue, but cannot imagine going back to semicolons and (excessive) curly braces and parens.
If you married CoffeeScript just out of convenience (being able to avoid prototypes, bind, etc.), then it no longer serves much of a purpose. But if, like me, you fell in love with CoffeeScript's beauty, then no amount of ES6+ features will make it obsolete (as long as you can also keep using those features directly in CoffeeScript).
some small aspects of CS i forgo because they (in my opinion) are a little too concise such that they sacrifice readability, but all in all it has my favorite syntax of any language.
I personally think calling .map() on an array is more readable than an array comprehension. But since CS is "just JavaScript" you are free to use the native JS array methods (and even more elegantly, at that).
Actually, Javascript does not require semicolons to be present. If you skip them, the only edge-case is when you try to start your line with `[` or `(`. In that case, you can prefix the line with `;`.
You should write tests when building a project in a dynamically typed language to alleviate some paranoia anyway. As long as you have decent test coverage and use a decent linter/formatter such as StandardJS[0] or prettier[1], you'll be fine.
[0]https://standardjs.com/ [1]https://github.com/prettier/prettier
So the question to me becomes, if the build tool doesn't correctly parse the JS that's lacking semicolons, should you really trust that build tool with the rest of your code? You already know at that point that it doesn't handle your otherwise-valid semicolonless JS correctly.
; are eyesores to an already fairly technical debt heavy/bloated language.
There's also some odd ASI issues within class bodies.
https://github.com/prettier/prettier/pull/1129 can be a useful reference (and tool!)
I would still use it though, if there were JSX style xml/html tags. But React changed everything for me and as a full stack dev, I can use only few frameworks on one level.
Edit: Ok, JSX is now supported. http://coffeescript.org/v2/#jsx
And I'm glad they broke the different behaviour of =>. It might need a fix in a lot of code bases, but this price is cheaper than having the mental burden of it.
I wrote a comparison about it a couple years ago: http://rapin.com/blog/2015/02/03/reactjs-with-coffeescript/
I'm not doing much react these days (cough elm), but I think it's still mostly relevant.
Here some benchmarks for several of the FWs that are popular in these languages (Elm has the FW built-in, ReasonML-React is missing but should be close to React.js).
https://medium.com/@saurabhnanda/benchmarks-fp-languages-lib...
It is a dilemma, but so far I have gotten by without type-checking.
(I'm joking, but actually.. why not?)
https://github.com/jiangmiao/toffee-script
The home page talks a little about achieving this by using Flow annotations in Coffeescript source and then having the build system pass the Javascript output to Flow: http://coffeescript.org/#type-annotations
But wow, "not elegant" is an understatement.
Good interop with Flow isn't quite there yet, though.
https://vuejs.org/v2/guide/single-file-components.html
I continue using it in my Vue projects and it's a pleasure.
I appreciate the work the team has put into bringing elegance and brevity to my daily life.
You can write JavaScript just fine without semicolons. I used to be in the same camp, but Feross eventually convinced me to try dropping em. Despite being cautious and a bit skeptical, I tried it out in a few projects by removing all semicolons with a search and replace. In every single case, I encountered zero issues.
[0] https://standardjs.com
How things have changed! Major kudos to Geoffrey Booth and all involved. Coffee's beautiful syntax combined with async/await has taken a lot of the 'ick' away from coding in JS, at least for me.
I have worked on two startups with a fellow programmer who knew Python but not CoffeeScript. He picked it up very quickly, along with Emblem (indented Handlbars alternative, useful for Ember projects) and indented Sass. Once we told the text editor to insert 4 spaces in place of tabs, we had much less to worry about in terms of stylistic disagreements.
Since this is just keeping up with the already existing ES6, why would anyone bother to move from ES6 to Coffee?