-
Notifications
You must be signed in to change notification settings - Fork 2k
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
No way to do ES6 'for .. of' loops for generators? #3832
Comments
I came to ask the same question. Having to manually run next and check for done is quite counter to the syntax-goodness that CS normally prides itself of. |
Shoot. That's a major bummer. @alubbe et. al — any ideas here? Do all of the runtimes that support generators also support ES2015's |
@jashkenas to my knowledge only chrome, firefox and opera support generators and all three support Syntax wise, this will be a bit of a challenge. |
We might have to add a flag for this to compile CoffeeScript for-in to ES6 for-of. I don't see any better way. |
@michaelficarra That sound problematic -- a given script could either loop through generators, or arrays. Node 0.11 and iojs also support I'd much rather have a special syntax, like |
@jagill: ES6 for-of works with arrays because they are iterables. |
I think @michaelficarra's suggestion is the most sensible approach. I personally would prefer releasing a backward incompatible version of CS (2.0, 3.0, what have you) that aligned I'm not in favour of adding yet another looping construct to CS. |
if they're supposed to be used by generators, can't we use something like the currently-invalid |
@vendethiel did you mean A current workaround would be something like: forOf = (gen, fn) ->
`for (value of gen()) fn(value)`
forOf gen, (i) -> console.log i |
Yes, sorry. |
I dislike creating type-specific loop declarations. So fundamentally, there are two routes and we'll need @jashkenas to give us a pointer:
|
Couldn’t the same syntax be used? If the context of the |
@ssboisen, the problem is that we can't determine the context of the @jashkenas, I'd vote for backward incompatible CS 2.0 (according to semver!) Breaking changes will allow introduce new keywords for existing problems as well (I mean |
Ha, ha, suckers! 😉 Never assume that a new feature in JS is going to be "cheap" or smart to use — not when its freshly implemented, and probably not even after many years of use. Check this out. Run it yourself. |
nice! that is some next level performance if I've ever seen one. @jashkenas can you help me interpret whether your response means that your are leaning towards a new third syntax or changing CS's loops? :) |
I don't know of a great solution just yet — but I haven't really had a chance to sit down and give it a think. There are, however, ground rules:
|
Regarding 2: please please please no! for ... of is a feature independent of generators and should have no impact on whether we keep this new awesome feature around or not. It is a loop over iterables, and an instantiated generator just happens to be iterable. |
Here is more information on what for ... of does: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/The_Iterator_protocol Basically, it converts strings, arrays, maps, etc. into a generator, instantiates it and continually calls .next() on it. I assume that is where all of the performance is lost. Looking at it, I think CS could go without for ... of for the time being. It's quite slow and, if you really ever need
|
That's sort of the kind of thing I'm talking about ... Is a direct:
... a lot faster than a |
No, it is just as slow: http://jsperf.com/for-in-vs-for-of/2 |
@jashkenas you don't want "for x from y" as a third syntax then? |
Apropos of nothing — what the hell is up with the:
... bullshit? Are we trying to pretend like we're not in a dynamic language that embraces duck typing any more? On what planet would that be preferable to:
Maybe for ES2019, we'll need a new third type of strings, after strings and symbols, to avoid name clashes again, so that we can have:
</grump> |
One of the things I've liked about CoffeeScript is that it allows me to do anything I could do in Javascript, modulo a couple bad constructs. Assuming we don't think the That being said, I have less absolute feelings about when it happens. For my own CS use (since iojs and "soon" Node 0.12 support generators), I'd prefer it to be sooner rather than later. |
Yeah, it's lamentable. But the philosophy of never breaking backwards compatibility, nor breaking existing applications, plus the common practice of extending native objects, makes it impossible to extend the language in a sane way like adding a normal Hell, not even something as simple as |
I think |
ES5 has two |
But wouldn't it just be super tragic for:
... especially when, IIRC, ES6's for-of was partially a syntax "cowpaved path" borrowed from CoffeeScript? It's even more tragic when you consider that in a perfect language, you wouldn't have three different syntaxes for these loops — you would only have one that handled arrays, objects and iterables. |
Yeah, it sucks and there should definitely be one loop type ideally. But unless you want to implement type-inference in the compiler (hard), or type checks at runtime (slow), we're kinda stuck right? |
My two cents: What about adding a keyword to for...of to let the interpreter know it's a generator?
One of those would compile to Cheers! |
@michaelficarra Thanks for explaining! |
@michaelficarra So the only way to access elements of a generator in coffescript right now is to iterate over it using
No |
@bernhard-42 As of right now, yes. |
@michaelficarra Thanks |
Bad performance is not specific to the Therefor the performance issue is less relevant than generally thinking about how breaking changes will be introduced into coffee in the future. TC39 is just starting and es7 and es8 are not too far off... They will certainly not stop advancing the language now like they did 15 years ago and if coffee wants to stay relevant it has to move on too. Hack or Break(+1)? |
I tend to think the optimal syntax for using iterators/generators would be Neither of these syntax suggestions would interfere with legacy CoffeeScript code either. This is all assuming you want to keep iterator syntax separate from array ( Plus, ES5 could take advantage of iterators too; so long as the object being used follows the iterator protocol, a structure not unlike what was suggested by @bernhard-42 could be used to run through it. |
Unfortunately for standard arrays in the current nodejs, iojs, Chrome and Firefox
(see https://gist.github.com/bernhard-42/27836f4ce719de6bee3e) For the nodejs world I would really not like to see ES6
From a performance perspective not critical, but ugly ... |
I'm probably not qualified enough to be anpart of thus discussion but here's my 2 cents What if we had a special shebang-esque comment to put CS in ES2015 mode? Something like What I'm proposing is everything by default compiles to ES5 (discount the es6 features already implemented) but when the shebang-thing is present, things like for..of are compiled assuming ES2015 (compiled to for..of rather than a es5 for..in). This -i think- would not break backwards compatibility and allow the es2015 users to use the parts they love about es2015 in CS without the need for new keywords, etc. |
*anpart = a part |
Bikeshedding here, but what about this (no new keyword): for yield value in squares()
alert value |
@nilskp I don't think would work, because that's already a valid expression for a function returning an array. You can't assume that it's returning an iterator. |
@dyoder is it valid syntax? I get |
Coffeescript 2.0 should break backward compatibility and compile to ES6 & ES7 or become itself "backwards" from an era progressively ever behind us. |
@nilskp I stand corrected. :) My brain parsed that as an expression and move right along. But of course that's an assignment so an expression isn't valid. So what you're suggesting is basically a My only concern with that is semantic. Iterators aren't related to |
@dyoder My proposal was for generators specifically, which was the original subject. I haven't thought about Iterators in general. |
Maybe: for next x in generator()
console.log x I'm not sure anyone here wants a new keyword, but I'd prefer this over Considering that generators in Coffeescript are defined in the same way regular functions are: It seems like there's an effort to make creating and using generators as transparent as possible. Iterating over a generated iterator is done in an for x in generator()
console.log x Coffeescript could reference a utility function to detect if it should iterate by eachIter = (a, f) -> (isArray(a) and walkArray or walkIter) a, f
|
I'd like to voice support for Javascript had Then, using So basically for...in and for...of were added to CoffeeScript to completely supersede the sad version of for...in that Javascript supported, even with completely disparate syntax. Now Javascript finally has for...of and they choose to make it not even support proper enumeration of objects but just iterators. It's perfectly in line with previous decisions made by the CoffeeScript team to say "this syntax is garbage and we will make our own". tl;dr |
I'm totally convinced by the rationale for I can't tell you the number of times I've accidentally tried to loop over the same generator twice in Python. Of course the second loop never executes because the generator is now empty! Having |
* Added support for for-from loop, see #3832 * for-from: remove extra newline and add support for ranges * for-from: tidy up the lexer * for-from: add support for patterns * for-from: fix bad alignment * for-from: add two more tests * for-from: fix test "for-from loops over generators" See explanation here: #4306 (comment) * for-from: delete leftover console.log * Refactor the big `if` block in the lexer to be as minimal a change from `master` as we can get away with * Cleanup to make more idiomatic, remove trailing whitespace, minor performance improvements * for-from: move code from one file to another * for-from: clean up whitespace * for-from: lexer bikeshedding * Move "own is not supported in for-from loops" test into error_messages.coffee; improve error message so that "own" is underlined * Revert unnecessary changes, to minimize the lines of code modified by this PR
This has been merged into master per #4355. Anyone up for writing some documentation? |
Great stuff! ✨
That is still an option. A universal |
Given a generator
how do we loop through it via the javascript
for .. of
loops? In javascript, we'd doThe coffeescript
for i in gen()
gives the C-stylefor (_i = 0; _i < gen().length; i++)
loops, andfor i of gen()
givesfor (i in gen())
. Is there some way to getfor (i of gen())
that I didn't see in the documentation?The text was updated successfully, but these errors were encountered: