Closed SonOfLilit closed 9 years ago
Cheers.
Thanks.
If you can clarify a bit, I'll submit a PR for the FAQ page. Feel free to ignore one or more of the points if you don't have time for this.
Specifically:
var
.I’m tired of reading how CoffeeScript is obsolete now that ES2015 is here to save us. I use CoffeeScript for the syntax, not the features that ES2015 has been busy catching up to, and the day I stop using CoffeeScript will be the day it’s pried out of my cold dead curly braces.
I am worried, though, that as time goes on and more people learn ES2015, I’ll have a harder time convincing teams and bosses to use CoffeeScript. There’s currently barely a mention of ES2015 in the readme or on coffeescript.org, and too many people assume that the project is dead and will slip into obsolescence as ES2015 gets more widely adopted. At the very least, there needs to be a prominent section in the readme and at coffeescript.org explaining CoffeeScript’s relation to ES2015, especially why CoffeeScript is still relevant today and will continue to be relevant when ES2016 and ES2017 and so on arrive. What I tell skeptics is that I expect CoffeeScript to continue to mature along with JavaScript, and when new versions of JavaScript reach wide adoption CoffeeScript will simply compile down to whatever the new target is, when there is a performance or readability benefit to doing so. I tell people that they should think of CoffeeScript as primarily an alternate syntax for JavaScript, one that prevents stupid bugs through things like significant whitespace and the ?
operator, and that this much-improved syntax will never get obsolete so long as ES* maintains backward compatibility.
I see defenses of CoffeeScript in this new ES2015 era that go along the lines of, well currently both ES2015 and CoffeeScript need to be transpiled down to ES5 or ES3, and that will be the case for many years, so what’s the difference? And by the time Microsoft Edge is the oldest IE we need to support, CoffeeScript will (presumably) compile down to ES2015, so there’s nothing to worry about. But this neglects two moderately large use cases where big chunks of ES2015 are usable today, without transpiling, thanks to the growing support already present in Chrome:
I don’t know what, if any, performance benefits anyone gets from letting Node 4 use native ES2015 features rather than the compiled-to-ES5 replacements, but presumably someone somewhere will claim that they must have ES2015-native code running in their Node app, or their app will suffer mightily, and therefore the app can’t be coded in CoffeeScript. Or ditto for a private Chrome-only app. And the thing is, they might be right. At the very least, it will be easier to debug such apps if the fat arrow compiles to a fat arrow, etc.
So besides updating the docs, which I feel like is the bare minimum response that ES2015 requires, we should perhaps discuss some future CoffeeScript that compiles at least some features to ES2015. Perhaps this could be a non-default feature enabled by argument, e.g. --target=es2015
say for when we’re compiling server-side code. A lot of work has been done in this pull request for CoffeeScriptRedux; maybe it can serve as a starting point? And as for updating the docs, I second @SonOfLilit and would be happy to start or contribute to a pull request explaining CoffeeScript’s post-ES2015 roadmap, if @jashkenas or another project maintainer would be so kind as to share some thoughts as to where they generally see CoffeeScript’s way forward.
I just started work on a site generator type thing. The tool is V8 only, so thought I'd be lazy and give ES6 a go. I had about 30 lines of JS written when I switched to CoffeeScript. It was like switching from Klingon to French.
(as a french one, I can guarantee we still have some pretty weird rules :P)
Looks like ES6 support might be happening, jashkenas has offered commit access to Decaf author (Decaf is CoffeeScript that transpiles to ES6).
Hey folks, @juliankrispel.
Julian emailed me back, but I'll respond here, so as to leave it in public. I just thought that since there's rightly a lot of interest in having CoffeeScript target ES6 instead of ES3, and Julian was actually doing something about it, and he attracted the interest of known solid contributors like @lydell and @eventualbuddha, it might have a higher chance of success getting done in a branch over here with a little more attention available to it.
That said, if anyone — new contributors or old — wants to experiment or play around in an "es6" branch, go nuts. I'd imagine you'd start behind a coffee --compile --es6
flag, and see how things shake out.
That'd be a huge boost to the project @jashkenaz!
Thanks!
What do I do now? :)
Julian Krispel-Samsel rainforestqa.com goodafternoon.co
On Jan 31, 2016, at 12:13, Jeremy Ashkenas notifications@github.com wrote:
Hey folks, @juliankrispel.
Julian emailed me back, but I'll respond here, so as to leave it in public. I just thought that since there's rightly a lot of interest in having CoffeeScript target ES6 instead of ES3, and Julian was actually doing something about it, and he attracted the interest of known solid contributors like @lydell and @eventualbuddha, it might have a higher chance of success getting done in a branch over here with a little more attention available to it.
That said, if anyone — new contributors or old — wants to experiment or play around in an "es6" branch, go nuts. I'd imagine you'd start behind a coffee --compile --es6 flag, and see how things shake out.
— Reply to this email directly or view it on GitHub.
What do I do now? :)
hmm, i’d say:
get @eventualbuddha’s expertise on board.
decaffeinate is more mature than decaf, so i bet he’s learned some lessions that could be beneficial to know.
make the output configurable. current design is based on the node method Base::compile()
which means: “render me to ES3”. the node classes need to be decoupled from the output format.
dunno how to do backwards compat here though. most Base
methods are coupled with the ES3 output. we need to know how much we can throw out of the node classes. ideally we remove everything that varies with output and the helpers built to do the ES3 output, and keep the node manipulating functions (e.g. to find and traverse children). finally we add a renderer
optional argument to compile
that handles all the compiling/rendering. the default (ES3)-renderer contains all the code currently in each node’s compileNode
method.
then it’s just a matter of adding a second renderer which can be passed to some node’s compile
method and handles conversion to ES6.
If I could just offer one suggestion: keep in mind the destinations for this generated code. In broad terms, they are:
I suppose the easiest approach for now is to set a target of ES2015, and let Babel handle converting that down to ES5 for all three destinations. It would be nice, though, if we could somehow get ES2015 or mostly-ES2015 code for cases 2 and 3, so that the code we debug with is closer to the original CoffeeScript (i.e. with fat arrows preserved, etc.). Maybe that’s a challenge for Babel rather than CoffeeScript, assuming that Babel will need to be part of the pipeline until ES2015 support is complete in Node and in whatever browsers your app is designed to support.
At the very least we should probably call the flag --es2015
or --target=es2015
so that when ES2016 is finalized and we eventually support compiling to ES2016, it’s possible to control whether we’re compiling to ES2015 or ES2016 (and beyond). If we want to go all out, we could provide a way to set a configuration, telling the compiler exactly which features to compile in the ES2015 way and which ones to not—for example, to configure fat arrows to stay fat arrows, ES2015-style, while everything else gets converted down to ES5. Such granular configuration would mean that we wouldn’t need Babel in the pipeline for server-side code or for Chrome-only apps, as we could configure the CoffeeScript compiler to generate code that uses only the ES2015 features that Node or Chrome support while compiling down to ES5 for the rest.
I would actually prefer not to compile to ES6 syntax where we have an ES3 syntax that works as well or better. For example, there's no reason to compile to let
to enforce scope where closures are being used for the same thing. The effect is identical, and probably more likely to outperform native. As another example, we shouldn't touch how functions compile at all. It works better the way CS does it.
What I'd like to focus on is only those cases where we can't compile to something usable in the three cases that @GeoffreyBooth listed above, and to cases where the ES6 equivalent really is incompatible with features included today.
At the end of this road, it should be easy to write canonical code using pretty much every currently-popular framework/environment, while being better and more fun to use than vanilla JS.
If the focus is on the differences, rather than trying to create a complete target to ES6, then I would hope that it would be less total work to do.
no matter what route we take, in the end there should be an ES2015 (which is as close to idiomatic, hand-written JS as possible) and an ES3 output (with the same semantics as the current output)
It’s easy to get carried away when thinking about what to compile CoffeeScript to (at least that’s my experience) :)
I’d say that we do things in small steps. Let’s start with the most important one: import
and export
. The good thing in that case is that we don’t need to think about compile targets: We can do it like we handle yield
.
I also agree with @bjmiller that I see no point in compiling to let
“just because,” or "a #{b} c"
to a #{b} c
“just because”. That’s just extra work for no gain. I suggest that we start by focusing on real problems instead. For example, somebody might want to compile class
to an ES2015 class so that they can extend natives. Or compile destructuring to ES2015 destructuring so that they can work with generators.
you’re already talking about which features the ES2015 compile target should be implemented first.
i talked about how we have to change the current code to have a second compile target at all.
if we simply say “we don’t introduce a second compile target and selectively start compiling some features to their ES2015 equivalents”, i think this will go down in flames. people will be annoyed that their mobile phone from 2008 can’t handle those features and say that it’s mission critical for their job to have for x in y
to compile to for (var i=0; i<y.length; ++i)
and not for (const x of y)
another way would be a babel-preset-coffeescript
which compiles the ES2015 versions of our features to the old ES3 versions. then we’d have for x in y
–(CS)→ for (const x of y)
–(Babel)→ for (var i=0; ...)
As for things like compiling "a #{b} c"
to a #{b} c
, or =>
to =>
, there is a reason other than “just because”—the closer the JavaScript output is to the original CoffeeScript, the easier the JavaScript is to debug. And presumably some JavaScript engines will parse =>
and similar things faster than their ES3 equivalents, so there might be a performance gain e.g. for Node 5 to use the ES2015 syntax. I agree that features with perfectly usable ES3/ES5 equivalents should be last on our list of priorities, but I think such features should at least be on the to-do list.
Actually I'd just like to talk about putting decaf into coffeescript first.
For any who don't know: Decaf isn't a fork of coffeescript. It's simply a program that takes the coffeescript syntax tree compiled by the coffeescript parser and converts it to an esprima-based syntax tree built with ast-types to ensure we're outputting valid js. Decaf has no knowledge of coffeescript internals and coffeescript doesn't have to know about decaf internals to use it for es6 compilation.
This decoupled relationship is possible because coffeescript, like any great modular program, exposes functionality that can be used outside of itself (lexer, parser and compiler).
Modularity is a good thing for so many reasons that I'm not going to elaborate on right now but for that reason I'd prefer decaf to maintain a separate repo, possibly inside a 'coffeescript' github organisation.
Anybody with me here? @jashkenas would be great to get an answer from you on that.
Oh, I didn't realize that was your approach @juliankrispel! Awesome! Now all I can say is: Continue on that path! :+1:
@juliankrispel sure, and this fits well with my idea here:
decaf would be an alternative renderer to the default one, and the default one would be included in CS. and to use decaf, you’d do:
import decaf from 'decafjs'
import {parse} from 'coffee-script'
const es3 = parse('a -> b').convert()
const es2015 = parse('a -> b').convert(decaf)
@flying-sheep I'm 100% with you on that one. I've started to implement this, will be sharing it soon :)
@juliankrispel If you would like to move the juliankrispel/decaf repo to the coffeescript organisation, I can help you with that. We should have moved this repo (jashkenas/coffeescript) there long ago.
As folks may know, Modules have two parts: the ECMA import/export es6 syntax/semantics, and the WHATWG browser module loading. This has created a mess in the current es6 world with webpack, browserify, common vs amd, bundling, and way, way more. It makes it a bit hard to use our modules, and babel can only do half the job because of the ECMA/WHATWG split.
There are two ways to minimize the hassle for using/testing Modules ourselves:
<script type="module ...>
has been approved by whatwg and is soon to be in browsers: https://twitter.com/domenic/status/689897197308092416 This should eliminate all module loading workflow because it too does the recursive module resolving as well. (I Hope!)Hi @backspaces, I think your comment points to a big design decision that needs to be made: when CoffeeScript supports ES2015 modules, is that support limited to simply outputting ES2015 JavaScript (and then Babel or <script type="module">
or something else in the build chain would be responsible for actually doing the importing and exporting) or will CoffeeScript support not just some equivalent module syntax but also resolving all the modules to output ES3 JavaScript?
I was assuming with my --target=es2015
suggestion that CoffeeScript would simply output ES2015-compliant JavaScript, and that’s where CoffeeScript’s responsibility would end. Babel and other tools already do a good job of taking ES2015 JavaScript and transpiling it down to ES5 or ES3, and I don’t see why CoffeeScript needs to duplicate all that effort. If CoffeeScript “is just JavaScript” and ES2015 is JavaScript now, we should be able to just output ES2015 and leave it at that (at least when we’re in --target=es2015
or later mode).
Though without --target=es2015
, modules wouldn’t be supported; so there would have to be a big warning in the docs that if people want to use modules, they need to pass this flag. The more ambitious approach, which I think your comment is suggesting, is that modules would be supported whether CoffeeScript is outputting either ES2015 or ES3, in which case the --target=es2015
flag would be unnecessary (at least for module support, leaving aside the cases when you might really want ES2015 code as your final output). I suppose if we want to go this far, we could include Babel as a dependency; CoffeeScript would always output ES2015, and unless --target=es2015
was set, CoffeeScript would pass its output onward to Babel to generate the final ES3 or ES5.
Sorry to be late.
Yes: modules are somewhat independent of the JS version in that import/export are defined in es6 but module loading is defined by the DOM spec .. whatwg in this case.
So I see no harm in allowing JS5 or JS3 code using the DOM loading spec, which is mainly about System.js or similar.
I ran a simple experiment for the simplest possible use of System.js, see a rough talk here: http://backspaces.net/temp/Modules.pdf I ran babel 6's fine-grain transpiler only for module transpilation (Canary supports > 90% es6), then used System.js.
I believe it is possible to have System.js do this for you w/o any transpilation, at least the github page sez so. I'd ask Guy Bedford.
Even this will go away as soon as <script type="module" ...> is completed which should be relatively soon for modern browsers.
-- Owen
On Fri, Feb 5, 2016 at 11:24 PM, Geoffrey Booth notifications@github.com wrote:
Hi @backspaces https://github.com/backspaces, I think your comment points to a big design decision that needs to be made: when CoffeeScript supports ES2015 modules, is that support limited to simply outputting ES2015 JavaScript (and then Babel or Githubissues.
Githubissues is a development platform for aggregating issues.
I'm doing research prior to adopting Coffeescript for a young startup's codebase. After intensive googling, I found no clear answers but many people asking themselves the same questions, so it may be a good idea to amend the FAQ with answers to these:
jslint
?coffeelint
? Anything else different from what you'd use with vanilla JS?Thanks.
A discussion we had today on IRC: