Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CoffeeScript 2.0: “UNIX philosophy compilation strategy”? #3596

Closed
lydell opened this issue Aug 20, 2014 · 18 comments
Closed

CoffeeScript 2.0: “UNIX philosophy compilation strategy”? #3596

lydell opened this issue Aug 20, 2014 · 18 comments

Comments

@lydell
Copy link
Collaborator

lydell commented Aug 20, 2014

I suggest that CoffeeScript should always compile to the latest “stable-enough” standard JavaScript. If the user’s environment doesn’t support that JavaScript, it is up to the user to include needed polyfills—perhaps using autopolyfiller—and/or pipe the JavaScript into another transpiler, such as esnext.

Wanting to use future JavaScript features isn’t unique to CoffeeScript. Regular JavaScript wants that too.

Examples:

  • Compile spread/rest/splat/whatever into ES6 ...foo whenever possible. es6-spread
  • Compile classes into ES6 classes. es6-classes
  • Compile => functions into ES6 => functions when possible. es6-arrow-function
  • Compile a in b into b.indexOf(a) >= 0. polyfill.
  • Compile yield into yield. regenerator
  • Compile destructuring into ES6 destructuring.
  • Compile a.throw to a.throw (not a["throw"]) etc.
  • Remove the “bare” option and always compile bare. Users should use a module system, or a separete “wrap-in-IIFE”-tool instead.

Pros:

  • Allows the user to choose which environments they want to support, which has been asked for numerous times.
  • Simplifies CoffeeScript compilation a lot.
  • Easy to support the latest ES specs (no need to worry about old browsers).
  • Follows the UNIX philosophy better. CoffeeScript becomes an alternate syntax with more features, such as chained comparisons (0 < a < 5), more splats ((a, b..., c) ->), expansion ([..., last] = foo), etc.

What do you think?

@jashkenas
Copy link
Owner

Super cool idea -- but that's not what CoffeeScript is. It would be totally great for you to pursue a fork that gives this approach a try.

@lydell
Copy link
Collaborator Author

lydell commented Aug 20, 2014

@michaelficarra It would be interesting to hear your opinion on this. Something for redux?

@michaelficarra
Copy link
Collaborator

@lydell: Yes, I think this is a very promising way for the language to move forward. I've been concerned (and pretty vocal) about the future of CoffeeScript if it refuses to acknowledge the existence of overlapping ES6 features. CoffeeScript is supposed to be a language that is in the same vein as JavaScript, but with more expressivity through mostly syntactic enhancements. That means accepting ES6 syntax/semantics where they differ from CoffeeScript's.

As a matter of policy, this implementation has targeted "lowest-common-denominator JavaScript", which is essentially ES3. I think there's pretty strong demand from our users for an implementation with this target, as well as an implementation targeting a more modern environment. If we can achieve both goals by targeting ES6 and depending on polyfills and ES6-to-ES3 compilers, I think that'd be a great implementation that would make everyone happy, while making it easier to add features to the language in the future.

@jashkenas
Copy link
Owner

You can certainly achieve this goal by targeting ES6 and then depending on an ES6 -> ES3 compiler -- but the runtime semantics won't be quite the same as the regular lowest-common-denominator version of CoffeeScript. You'll have two subtly different versions of the program — essentially, a fork.

Which is totally fine and great. If it works well, we can even link to it up at the top of the homepage. Maybe call it CoffeeScript6, or something...

@michaelficarra
Copy link
Collaborator

@jashkenas Do you think it's acceptable to leave CoffeeScript with features that are identical in spirit to ES6 (comprehensions, classes, super, etc.), but with subtly different syntax/semantics? I think that is doing a disservice to our users. Major version bumps (as in Python 3, Perl 6, Ruby 2, C++11, etc.) give us the opportunity to make backwards-incompatible changes. In my opinion, CoffeeScript 2 should become ES6++. CoffeeScript 3 should be ES7++.

@vendethiel
Copy link
Collaborator

Python 3, Perl 6

Those have a pretty bad history of being accepted (we can also talk about D and I'm sure others). Well, they took a lot of time to get there, much more than we should take.

Ruby 2, C++11

Not a huge deal for C++ because they didn't break bc (I think they removed one function that was terrible)
(the breaking one was more Ruby 1.9, for some reason, and it was mostly about encodings IIRC. Plus the community is very going-forward, but the same could be said of the nodejs one)

@jashkenas
Copy link
Owner

In my opinion, CoffeeScript 2 should become ES6++. CoffeeScript 3 should be ES7++.

That sounds fine to me, as long as you're thinking of "CoffeeScript 2" and "CoffeeScript 3" as a "different thing" than CoffeeScript 1. As long as you don't give the expectation that code compiled with one of them is seamlessly interoperable with code compiled with the other.

@backspaces
Copy link

One issue is a runtime library, something we've avoided.

Traceur uses a runtime. It also has options that allow you to use the browser's esnext features as well as smart polyfilling only when needed. Unfortunately you need to build your own runtime to defer to the browser's new syntax .. Traceur can't auto-defer these features in advance. I.e. if your browser/node environment has a feature that Traceur has a polyfill for, it will not install the polyfill. But syntax changes like classes and comprehensions can not be similarly adaptive.

Modules present a challenge. Traceur uses a separate project's module loader. This is a fairly subtle problem due to desired compatibility with existing node/browser loaders. Es6 defines the System object hooks for loaders but I believe we'll need a runtime for import/export for quite a while.

@carlsmith
Copy link
Contributor

If anyone is going to actually implement this stuff, they should just drop support for older browsers altogether, like jQuery, and develop an evergreen version in parallel.

@carlsmith
Copy link
Contributor

Targeting any established standard is a bad idea. CoffeeScript targets the current lowest common denominator. It could just target the latest version of V8, or every feature currently available in all modern browsers, and that could work too, so long as the target moves.

@backspaces
Copy link

This is more subtle than es6 or not. It is that, if there is an important capability available, and not accessible from CS, then an attempt to access to this should be made.

This can be even more narrow: consider only things that introduce a important syntactic element, and with no equivalent in CS. Many improvements are available as polyfills and need not be considered.

I think the best example is Modules with import/export and the underlying System object. I believe this will possibly become available for es5, initially via polyfills for System, and later native. And I think the browsers and node might easily convert to the new System based import/export.

I've recently gotten back into JS and es6 and they still are like using a stone for a hammer. Don't like it. But working in a team environment, import/export is really a brilliant tool. Gone are all the <script...> tags in html, they are automatically resolved via the import/export. And our modules have become much smaller.

This also makes "frameworks" much lighter weight, they only get the (now smaller) parts they need.

Many of the other syntactic changes aren't need, CS already has them, and they're better. There could be a slight performance advantage for native, but fast.js has shown that is not always the case.

Resolving the import/export problem also resolves the "political" problem between CommonJS and AMD .. they can use the same System object and hopefully migrate to import/export so that our node/browser code can work in both.

There are a few others. "let" is pretty nice, but CS protects us from variable declarations entirely! "const"? Probably. A lot are available as libraries and are not syntactic. So hunt for the syntactic features that you really, really think important. For me, modules.

@backspaces
Copy link

Whoa! This is interesting: http://labs.ft.com/2014/09/polyfills-as-a-service/

And the latest Chrome ends up with near-zero polyfills!

@carlsmith
Copy link
Contributor

@backspaces - nice post. Really good points.

For me it's generators. They're not a novel request around here, but my issue arises from working on a CoffeeScript shell, where I want co-routines to implement something like threads. In ES6 non-strict, you can create a generator that can compile and evaluate a string of CoffeeScript in the generator's scope, then yield control flow to the 'main thread', and the generator can pick up and carry on its job with a call to next, running another chunk of code in the same scope. It's about six lines of code.

Before anyone chips in, eval is my favourite function.

@adambiggs
Copy link

In my opinion, CoffeeScript 2 should become ES6++. CoffeeScript 3 should be ES7++.

Amen 🙌

@lydell
Copy link
Collaborator Author

lydell commented Aug 15, 2015

Just for the fun of it, I wrote up a bit about my “dream compile-to-JS” language with UNIX philosophy in mind: https://github.com/lydell/frappe. If you also like fantasizing about syntax it might be worth a read ;)

@vendethiel
Copy link
Collaborator

I guess everyone has the... "Coffee of their dreams" ;-).

@backspaces
Copy link

In my conversion to es6, I've been using:
JavaScript Standard Style
https://github.com/feross/standard#javascript-standard-style
It too is semi-less.

After doing it for 3 months, it's been such a relief. Sorta like an AA
meeting: I've been of them for 3 months! I often challenge people to tell
me where semi's should be. They can't. It's really easy to tell where they
can safely be omitted and the few corner cases. And yes, its way more
readable.

Coffee folks will really like es6:

  • It's got a lot of coffee already

  • Subtle new syntax features are great

  • You'll gain back all the friends that have abandoned all your CS projects.

  • Modules. Imagine HTML without 20 <script> tags
    .. there's more but jump in, babel is the new coffee compiler.

    -- Owen

On Sun, Aug 16, 2015 at 6:11 AM, ven notifications@github.com wrote:

I guess everyone has the... "Coffee of their dreams" ;-).


Reply to this email directly or view it on GitHub
#3596 (comment)
.

@bjmiller
Copy link

I strongly disagree.

  • Every "coffee-feature" ES6 does, CS still does better.
  • Many of the "subtle" new syntax features aren't great, they're confusing.
  • If people have religious problems with CS, I submit that you don't need them.
  • Modules are actually orthogonal to syntax, and ES6 modules are still really unpleasant to use compared to Common JS.

If CS "needs" to do anything, it's that it needs to respond to the cases where ES6 allows you to do something, and CS doesn't because of its own syntax rules. Which is to say that you should somehow be able to make CS output any valid JS, without needing the backtick-escape to hack around things. But, things like that are all small adjustments at heart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants