CoffeeScriptRedux
CoffeeScriptRedux copied to clipboard
Cannot use a ReturnStatement as a value
Can't compile below sample file. will throw "expr: Cannot use a ReturnStatement as a value"
Confirmed with latest git and beta 2.
a = ->
return i for i in [1..3]
I think it is impossible to use a return value after the return has happened. There is no more code running. That example would return 1 and do nothing else.
Or is this a valentine's day joke?
On Thu, Feb 14, 2013 at 4:09 AM, Jinzhu [email protected] wrote:
Can't compile below sample file. will throw "expr: Cannot use a ReturnStatement as a value"
Confirmed with latest git and beta 2.
a = -> return i for i in [1..3]
— Reply to this email directly or view it on GitHubhttps://github.com/michaelficarra/CoffeeScriptRedux/issues/168.
@mark-hahn It's not a valentine's day joke, i fear. The code should is equivalent to:
a = ->
for i in [1..3]
return i
Which looks more like a reasonable usage and (fortunately, i think) raises the same compilation error in Redux.
A valid usage could be finding an element in an array:
findBy = (array, fn) ->
for x in array
return x if fn x
Which, written as a one-liner should be:
findBy = (array, fn) -> return x for x in array when fn x
And before anyone says "but you shouldn't write that as a one liner", i agree, but it currently works on CoffeeScript 1.4 and apparently people rely on those for one-liners with early returns :anguished:
You message subject is misleading. You don't want it to return a value, you just want to be able to use the return. I was scratching my head as to what you meant, especially with the 1..3 example.
I understand your use case which I have used before. I would never use that one-liner though. It looks like an entry in an obfuscation contest.
On Thu, Feb 14, 2013 at 10:17 AM, Demian [email protected] wrote:
@mark-hahn https://github.com/mark-hahn It's not a valentine's day joke, i fear. The code should is equivalent to:
a = -> for i in [1..3] return i
Which looks more like a reasonable usage and (fortunately, i think) raises the same compilation error in Redux.
A valid usage could be finding an element in an array:
findBy = (array, fn) -> for x in array return x if fn x
Which, written as a one-liner should be:
findBy = (array, fn) -> return x for x in array when fn x
And before anyone says "but you shouldn't write that as a one liner", i agree, but it currently works on CoffeeScript 1.4 and apparently people rely on those for one-liners with early returns [image: :anguished:]http://stackoverflow.com/questions/14831462/can-this-statement-be-written-in-one-line
— Reply to this email directly or view it on GitHubhttps://github.com/michaelficarra/CoffeeScriptRedux/issues/168#issuecomment-13569982.
Would need to be added here, I suppose.
@Nami-Doc: That will probably work because of this: https://github.com/michaelficarra/CoffeeScriptRedux/blob/60916462e816cffdcb8b330ecc5d4fc611d71203/src/compiler.coffee#L95-L96
For the record, I highly discourage writing code like this. Gross. But we should support it.
The compilation error seems to be triggered only when the for loop is treated as a comprehension. If another statement is added after the loop it compiles:
# This compiles:
findBy = (array, fn) ->
for x in array when fn x
return x
undefined # Remove this line and it stops compiling.
Now, the funny thing is that the original CS compiles this:
findBy = (array, fn) ->
for x in array when fn x
return x
Into:
var findBy;
findBy = function(array, fn) {
var x, _i, _len;
for (_i = 0, _len = array.length; _i < _len; _i++) {
x = array[_i];
if (fn(x)) {
return x;
}
}
};
Which means that the compiler is detecting that the for loop contains a return statement and therefore does not generate an array as the return value. But, what if the return inside the for is not executed? Shouldn't the function then return an array, as the last expression is an array comprehension? Or are for loops not considered array comprehensions when they include a return statement?
@michaelficarra, i think i now understand why you consider that the array comprehension syntax should include some [] around it and be different to normal for loops =P
@epidemian: You're exactly right, on both points. Comprehensions are not inferred to be such when they contain pure statements (or at least return). We could make it an error if we explicitly denoted that we wanted a comprehension. And that's why I think using a pure statement in what would otherwise be an implicit comprehension is such a gross style. But the original compiler intentionally supports that exact case, so we will have to as well.
@michaelficarra I guess it's a trickier problem than i though.
In order to maintain consistency with the original compiler not only would it be necessary to add support for these for loops with return statements as the last expression in a block, but also change how things like this get compiled:
foo = ->
for x in arr
if someCondition
return []
x
// Generated by CoffeeScript 1.4.0
(function() {
var foo;
foo = function() {
var x, _i, _len;
for (_i = 0, _len = arr.length; _i < _len; _i++) {
x = arr[_i];
if (someCondition) {
return [];
}
x;
}
};
}).call(this);
// Generated by CoffeeScript 2.0.0-dev
void function () {
var foo;
foo = function () {
return function (accum$) {
var x;
for (var i$ = 0, length$ = arr.length; i$ < length$; ++i$) {
x = arr[i$];
if (someCondition)
return [];
accum$.push(x);
}
return accum$;
}.call(this, []);
};
}.call(this);
Then again, this probably could be considered a bug in the original compiler =P
(Btw, the bracketed array comprehension is no more harmony's which decided to go [for (a in b) a] style).
Not sure why CSR produces a closure here, seems unefficient no? I don't see the use case it fixes
Not sure why CSR produces a closure here, seems unefficient no? I don't see the use case it fixes
Me neither. But but i was trying to point out is that the behaviour of the generated code differs. Redux returns an array (as, i think, would be expected) from the function (in case the return inside the loop is never executed) while the original compiler doesn't.
Oh. Definitely a bug in the original compiler. Would need to check how makeReturn works in coffee
This snippet also won't compile. I think it's related.
fn = ->
while true
if true
1
else
return 2
@krisnye You didn't mention a solution and then you closed the bug. If you have fixed this bug then please post your solution. If the bug is not fixed then please reopen it again so that it stands a chance of getting fixed (at the very least I could really use this being fixed!).
@michaelficarra I suspect this bug was closed by mistake. I am seeing this same issue in 2.0.0-beta 6. Can you reopen it please?
@D1plo1d I didn't close this bug, I only closed the related bug filed against commonjs-everywhere.
@krisnye Ahh, my mistake. Sorry about that!