-
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
Fix #5013: return statement as an expression #5014
Conversation
test/functions.coffee
Outdated
|
||
eq "(function() {});", compile("-> (return)") | ||
eq "(function*() {});", compile("-> (yield return)") | ||
eq "(async function() {});", compile("-> (await return)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we test these against generated JS?
Why is there no return
in the JS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yield return
, await return
are ways to mark a function as a generator/async without needing to use yield
or await
in the body.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but it seems incorrect for there to be yield
, await
and return
in the CoffeeScript and for none of those to appear in the generated JavaScript. They’re not CS-only keywords, they’re basically passthroughs. When else do we swallow a return
in the CoffeeScript and not output it in the JavaScript?
I would think that -> (yield return)
should generate:
(function*() {
(yield return);
});
which is invalid JavaScript; but that’s okay. It’s what the user typed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have been slicing Return
s off the end of Block
s since the very beginning(™).
I'm a little confused by this one.
|
It is confusing. Other statements in the expression are allowed as of #4849. So, since ->
if true
b = 1
return
b = 2 @GeoffreyBooth both |
The right way to write the latter, is: for a in b
a()
break Or: for a in b then a(); break Let's not loosen the rules to allow people to write clever, but syntactically nonsensical code. Let's keep things tidy. |
@jashkenas so #4849 should be reverted then? This was labeled as a bug since 2014. |
I would confirm with @lydell and @GeoffreyBooth first, but my opinion is yes: The whole point of statements is that they represent constructs that can't meaningfully be used as a part of a larger expression. In CoffeeScript, we want as much as possible to be an expression (including things that aren't in JavaScript, like variable initialization). But some things just can't be expressions, and |
Yes, but my point was that the original CoffeeScript has a I see no reason to disagree with @jashkenas here. #4849 was only merged in a few weeks ago, we can revert it. That would basically be fixing a regression, in that #4849 more or less introduced a bug in that statements are suddenly allowed where they shouldn’t be. #3441, the bug from 2014, would remain closed as per @jashkenas’ comment here it shouldn’t have compiled in the first place. At least now we can explain why. |
@GeoffreyBooth I'll make changes in this PR to revert to the previous state. |
I don't really mind how it ends up anyway, I just feel like pointing one thing out:
This is less, imho, about statements vs expressions, that about simulating a JS block using parentheses and the semicolon operator, which is somewhat our alternative to JS' comma operator. The distinction between expression and statement is still present. |
I see that point of view, but it still feels like something that we shouldn't support and encourage. Instead of tricks using parentheses to jam a bunch of stuff on a single line — just write it the other way. |
I'm used to this syntax in Ruby since it's the only way to write early returns in a single line in Ruby. I use this pattern very often both in Ruby and CoffeeScript 1. For example (in Ruby): (render 'error'; return) if error? At least in Ruby, when discussing such early results statements once in a ticket Matz told that was the recommended approach for those cases, so he doesn't seem to find it weird. By the way, I use the same pattern in a case statement block as well (with break). |
Fixes #5013 and return statement as an expression in general.