-
Notifications
You must be signed in to change notification settings - Fork 177
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
[Discussion] The ES6 future of CoffeeScript. Looking for a ES6-friendly CoffeeScript replacement. #128
Comments
A few notes, You're comparing ES6 using ES5 as an example: for (var key in props) {
if (!props.hasOwnProperty(key)) { continue; }
}
// VS
Object.keys(props).forEach(function(key) {
var value = props[key];
} With that said the design goal of CoffeeScript is to support all browsers down to ES3 (enter IE6 stage left). Because of that any ES6 is incompatible with ES3 syntax. The only way to by pass this is with backticks. This is expected as CS was designed to trans-pile to JavaScript which needs to be compatible. For now backticks are the way to manage this and I use them in my Ember-CLI project which is an es6-transpiler project. It is likely that in the future as the rest of the world finally moves from the old JavaScript and ES6 gains more traction that CS will diverge and there will be an CoffeeScript 3 version and a CoffeeScript 6 version. I doubt this will not be driven by the core CoffeeScript dev team but instead by a forked team. Anyway enough speculation. I feel the goal of this Cook-book project is to offer patterns / recipes for such a case when a user wishes to use some of the ES6 syntax in the current version of CS. An example might look like: `import Ember from 'ember'`
`import MyModule from '../my-module'`
MyClass = Ember.Object.extend
foo: "bar"
baz: -> "baz"
`export default MyClass` |
It might be worthwhile separating out the syntax issues from semantics/polyfill issues. So array comprehensions are syntax (alas not in es6 but still supported in some of the transpilers) but a lot of the improvements in JS objects/Arrays/iterables etc not syntax and are available to CS. Modules are sorta in the middle and easily managed with backticks or direct use of SystemJS. This would help me just understand how bad it would be to just jump to es6! Array Comprehensions still are huge for me. James Long (@jlongster) had a nifty suggestion for the TC39 committee: when considering a change in syntax to Javascript, build a SweetJS Macro of it for testing. I'm wondering how hard it would be to do that for any much-loved CS syntactic feature not in ES6? Build macros for them? Then we'd be OK with es6 itself, filling in with Sweet macros any features we badly miss. |
For the rather mind-numbing discussion about this very topic check out issue jashkenas/coffeescript#3162. IMHOI found I mostly agreed with the following quote from @bjmiller:
|
Hi @lolmaus, you told "Some of core CS features conflict with ES6, namely backticks and fat arrows", but reading http://6to5.org/docs/learn-es6/#arrows we see "Arrows are a function shorthand using the => syntax. They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both expression and statement bodies. Unlike functions, arrows share the same lexical this as their surrounding code." Is this not exactly the CS fat arrow behavior? In the example we can see: v => v + 1;
(v, i) => v + i;
v => {
if (v % 5 === 0)
fives.push(v);
}; I sure could rewrite this in CS as: (v)=> v + 1
(v, i)=> v + i
(v)=>
if v % 5 is 0
fives.push(v) So... I don't see a problem to translate CS's About the backticks (Template Strings), i don't see any problem. CS has a way better design in this area. While JS has I don't see any problem in translating CS's double quote to ES6's backticks, on the contrary, that is much better to my keyboard, and to the coding culture. I believe CoffeeScript needs a " So, is there a real translation problem between CS and ES6 or is this only a FUD? |
Compiling CS fat arrow to ES6 fat arrow will be a breaking change. The awesomest feature of CS fat arrow is being able to reference both local scope via As for backticks (and other constructs including the fat arrow) is that they mean different things. It's fine for CoffeeScript, but if we start a new preprocessor, we should embrace the ES6 syntax and use other syntax constructs for preprocessor features. @bjmiller in the CoffeeScript thread has stated an awesome idea, you should totally read his original comment. For the features that have syntax conflicts between CS and ES6, CS does a better job. A CoffeeScript coder will never feel a need in those ES6 features.
Other features either don't conflict with ES6 syntax or can be passed through backticks. Also, it makes perfect sense to use CoffeeScript AND a ES6 transplier like 6to5. Or you can use libraries like RSVP to have more powerful alternatives to certain ES6 features. Can anyone name a feature where CoffeeScript falls short? |
Heh. Good thing workflow tools (Gulp etc) handle transpilation so well. I On Fri, Jan 23, 2015 at 12:48 PM, Andrey Mikhaylov (lolmaus) <
|
I'm not trying to be offensive but this doesn't feel like a feature to me. The mixing of CS and JS to handle scope suggests a abuse of the language. Why not set a variable at the correct scope level instead of swapping This is defiantly a code smell and if used needs refactoring. |
Oh I like these, Spot on. |
@sukima .. oh gawd, thanks for explaining the (kinda cool) difference between @ and |
Regarding your first point:
Might I suggest LiveScript? http://livescript.net/ |
Thx for your contribution, @sleepyfox. LiveScript is the only preprocessor i'm aware of that possesses the spirit of CoffeeScript and has a large community. But their ES6 status is identical to that of CoffeeScript. The only difference is that LiveScript haven't closed their ES6 issue ticket, but it's as inactive as CoffeeScript's. I no longer think that lack of support of native ES6 syntax in CoffeeScript is a pitfall. As i said above, it's not necessary. Also, CoffeeScript has just added support for generators, so it's not forever stuck in ES3 as it seemed before. I thought of writing an article to coffeescript-cookbook.github.io that compares ES6 features and their CoffeeScript alternatives. Do you guys think it's worth doing? |
What is in ES6?
So all in all, there's really no reason to drop LS for ES6 as far as I can see, and CS supporting Generators really just means more options for people. |
Oh, and yes, I do think it is worth doing writing an article comparing CS to ES6 features, the more people are informed about this stuff the better off we will be. |
Also missing get and set literals for classes. |
For anyone who is interested in a comparison of CoffeeScript and some of the things coming in ES6, I wrote an article to show some of the differences in syntax. |
This is going a little off topic but the lack of getters and setters syntax can be worked around by using |
I remember from my old Java programming days that using getters and setters was considered a code smell and violated the "Tell, don't ask" rule... |
@sleepyfox in general I would agree, especially in most code example on getters and setters. However there is a time and place for them. For example when writing a library where you need to manage change events. An example would be Backbone where it's API requires all assignment and fetching to be done with So yes it can be abused and violate the "Tell, don't ask" but in the above example you are telling it to set a property who's side effect is intentional, well known, and expected. In conclusion, there is a time and a place for them even if most examples don't teach when and where and instead tend to insight code smells. |
It is pretty simple to wrap state in a closure (use the module pattern) and prevent anyone fiddling with your object's properties. That way you can enforce your class's contract. |
I found another ES6 feature that is impossible with CoffeeScript, at least without too much scaffolding: private properties. Demo: http://goo.gl/juKxyx Also, async/await: http://goo.gl/wnQS4j (Is IcedCoffeeScript still alive?) |
@lolmaus really? I do three impossible things before breakfast, behold! class Person
constructor: (name) ->
person_name = name
@get_name = -> person_name
Bob = new Person('Bob')
alert Bob.get_name() # = 'Bob'
alert Bob.person_name # = undefined Alternatively you can instead apply Crockford's 'module pattern' and use factory functions like so: makePerson = (name) ->
do ->
secret_name = name
visible =
get_name: -> secret_name
Bob = makePerson('Bob')
console.log Bob.get_name() # = 'Bob'
console.log Bob.secret_name # = undefined I hope this helps. |
@sleepyfox, a number of issues with your approach:
|
The reality is that JavaScript is not Java, nor is it C#, C++ or SmallTalk. Objects do not work the same way, and inheritance works in a very different way (i.e. Self's prototypical version) than other so-called OO languages. Part of learning how to use JavaScript effectively is in knowing what works, and what doesn't. Trying to write C++ or C# using JavaScript, just because there is thing called Personally I wish @jashkenas had called it something other than |
Hey @sleepyfox, i agree with your reasoning (except for 5: it ruins TDD). Bu you're mixing two different things here: language capabilities and best practices. The fact that you're able to shoot into your leg does not mean that gun manufacturers should make it impossible to shoot into legs. Sometimes shooting into a leg is what you need from a gun. In much the same way, sometimes you do need to deliberately monkeypatch a class. Sometimes you need to simply add a method to a single instance of a class, and that method should have access to that instance's private properties. Sometimes subclassing is the way to go (and it is very often, even in JS. Have a look at Ember). A JS preprocessor should never limit a user in what he's able to do with JS. |
@lolmaus OK, let's agree to disagree, about testing private methods, sub-classing and monkey-patching. Guns: remind me never to stand near you on a range. As far as what a JS pre-processor should or should not do, I think that's really the purview of the person who writes the pre-processor. If we disagree with their premise, we're perfectly capable of writing our own. Going back to the original point: you said private properties were impossible with CoffeeScript; I showed you two different quite simple ways that they could be implemented, and I'm sure there are more. In most cases I have observed encapsulation is well enough served by closures and modules to make the need for secure private properties or methods moot. YMMV. |
Fun discussion but this is totally off-topic for the coffeescript cookbook Would like to close this issue. Thoughts? |
It indeed does not relate to the cookbook directly, but this project is a community of CoffeeScript enthusiasts, people who should be worried with the indeterminate future of CoffeeScript. Unless we've got strict policy for the issue queue, i suggest we keep this open for discussion. |
With the addition of generators to CoffeeScript (something that forks like LiveScript have been working with for some time) the last major reason for thinking of swapping to ES6 has been removed for me. |
I love CoffeeScript and i can't imagine my life without it. I would hardly be a frontend dev if it weren't for CoffeeScript. But the matter is that JS is going to evolve further, and CoffeeScript will get more and more out of sync with JS syntax and constructs. It will end up being a weird thing used only by those oldfags who started using it in ES3 era and were too stubborn to move on. It's already being considered an ill manner to use CoffeeScript both in open source and private projects. The JS world is becoming squeamish about CoffeeScript, and not unreasonably. We do need a preprocessor that posesses all the CoffeeScript goodies (meaningful indentation, implicit return, optional parens and commas,
Thoughts? |
@lolmaus it sounds like you're asking for "a better version of the ES6 draft that looks more like CS", is that what you want? |
@sleepyfox, why would i want a different version of an EcmaScript draft? That's ridiculous, no runtime or transpiler would ever support it. |
Because drafts leave draft status to become approved. And then runtimes (eventually) support them. |
Are there two lists somewhere of the ES6 features, one of syntax changes Then looking at the first list, factor out those features that are not in It would give the conversation a more precise focus: what can't we do in -- Owen On Mon, Feb 9, 2015 at 3:21 AM, Sleepyfox [email protected] wrote:
|
@backspaces, no such list so far. Here's what i know so far:
BTW, the CoffeeScript maintainer said that he might consider implementing modules but as an compiler to AMD/CJS rather than transpiler to ES6. |
Again, this is totally off-topic. the cookbook is a reference for beginners of either obvious or verifiable best-ish solutions. The end result of this argument will be
really think this is a distraction for this project and would prefer the conversation moved elsewhere. |
@michaelglass your probably right; but this does need to be discussed somewhere. Maybe a repo dedicated to this very issue? |
I just ran into a CS incompatible issue: Tagged template strings `hbs\`{{foo-bar}}\`` Does not work. It has to be in ES6 and there is a discussion about this issue. |
@lolmaus You can write it like this without for (let [key, value] of Object.entries(props))
style[key] = value compare that to what coffeescript's var key, value,
hasProp = {}.hasOwnProperty;
for (key in props) {
if (!hasProp.call(props, key)) continue;
value = props[key];
style[key] = value;
} |
FWIW, coffeescript 2.x generate ecmascript6 compatible javascript |
ES6 is gaining a lot of spread. It introduces a lot of new concepts into JS. Here are nice overviews: short, comprehensive.
And people already use those features! Thanks to the effort from such projects as 6to5, es6-transpiler and Traceur, for a modern JS developer who does not use CoffeeScript, there is simply no reason not to use ES6 nowadays. Many modern JS projects are already being written in ES6. Moreover, popular JS frameworks already demand that their users code in ES6 out of the box (this includes Angular 2 and EmberJS).
CoffeeScript is essentially locked at ES5. Some ES6 features are accessible via backticks, but others directly conflict with the CS syntax, including said backticks. With main contributors having explicitly refused to support ES6, CS is doomed to become a thing of the past.
This worries me a lot. I still use CS for all my projects, but i will doubt using CS in a new project.
My problem is that i absolutely adore CS syntax. I worship it. After getting used to CS, i can't stand vanilla CS anymore.
Here's an extract from React sources i saw today (by the way, React is written in ES6):
This can be rewritten in CoffeeScript as:
JS code is more than 100% larger than CS with zero benefit!
Back to the matter. With CS maintainer having doomed CS to be obsolete, we need a replacement.
I suggest that here we:
The text was updated successfully, but these errors were encountered: