jashkenas / jashkenas/coffeescript
return doesn't work in for loop comprehensions
- Dominant language
- CoffeeScript
- Stars
- 16.6k
- Forks
- 2k
- PR merge metrics
- No merged PRs in 30d
Description
Feature request (or maybe bug)
### Input Code
```coffee
```coffee
f = ->
for x in [1..5]
return null if bad x
x
```
[try link](https://coffeescript.org/#try:f%20%3D%20-%3E%0A%20%20for%20x%20in%20%5B1..5%5D%0A%20%20%20%20return%20null%20if%20bad%20x%0A%20%20%20%20x)
### Expected Behavior
I expected this code to return an array if none of the `bad` calls came up true:
```js
var f;
f = function() {
var i, results, x;
results = [];
for (x = i = 1; i <= 5; x = ++i) {
if (bad(x)) {
return null;
}
results.push(x);
}
return results;
};
```
### Current Behavior
However, in the code generated by CoffeeScript, the function returns nothing if none of the `bad` calls come up true:
```js
var f;
f = function() {
var i, x;
for (x = i = 1; i <= 5; x = ++i) {
if (bad(x)) {
return null;
}
x;
}
};
```
### Possible Solution
I'm guessing that this issue is caused by `class Return` declaring `isStatement: YES`, which makes sense by itself. But perhaps it could be worked around in "the hairiest method in all of CoffeeScript.", `For::compileNode`.
### Context
I guess the main discussion to have is whether the existing behavior is intended. The documentation expresses the spirit of [Everything is an Expression (at least, as much as possible)](https://coffeescript.org/#expressions), and further encourages:
> Even though functions will always return their final value, it’s both possible and encouraged to return early from a function body writing out the explicit return (`return value`), when you know that you’re done.
So my feeling is that my expected behavior is "more correct", though it would technically be a backward-incompatible behavior. (Code that didn't return anything before would now return something.)
### Environment
* CoffeeScript version: web try / 2.5.1
Contributor guide
Research direction
Start with the `For::compileNode` entry point and the `Return` class's `isStatement` behavior, using the linked try example to reproduce the generated JavaScript. Done means the comprehension returns an array when no `bad` call succeeds and still returns `null` on an early return, with the intended backward-compatibility behavior resolved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- coffeescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100