Closed ceremcem closed 2 years ago
The equivalent code in Coffeescript is:
demo = ->
for i in [5..1]
console.log "Waited #{i} seconds..."
await sleep 1000 # wait one second
console.log "Done"
which produces the following output:
var demo;
demo = async function() {
var i, j;
for (i = j = 5; j >= 1; i = --j) {
console.log(`Waited ${i} seconds...`);
await sleep(1000); // wait one second
}
return console.log("Done");
};
sleep = (ms) ->
new Promise (resolve) ->
setTimeout resolve, ms
demo = (seconds) !->>
for i from seconds to 1 by -1
console.log "hey #i"
await sleep 1000 # wait one second
console.log "Blastoff!"
demo 3
Correctly (expectedly) compiles to:
var sleep, demo;
sleep = function(ms){
return new Promise(function(resolve){
return setTimeout(resolve, ms);
});
};
demo = async function(seconds){
var i$, i;
for (i$ = seconds; i$ >= 1; --i$) {
i = i$;
console.log("hey " + i);
(await sleep(1000));
}
console.log("Blastoff!");
};
demo(3);
If we use for i in [seconds to 1]
instead of for i from seconds to 1 by -1
, generated output changes dramatically and is far from desired output:
demo = (seconds) !->>
for i in [seconds to 1]
console.log "hey #i"
await sleep 1000 # wait one second
console.log "Blastoff!"
compiles to:
var demo;
demo = async function(seconds){
var i$, ref$, len$, i, fn$ = async function(){
var i$, results$ = [];
for (i$ = seconds; i$ <= 1; ++i$) {
results$.push(i$);
}
return results$;
};
for (i$ = 0, len$ = (ref$ = (await (fn$()))).length; i$ < len$; ++i$) {
i = ref$[i$];
console.log("hey " + i);
(await sleep(1000));
}
console.log("Blastoff!");
};
@rhendric Is this change also expected or this is some sort of bug?
First, you almost certainly don't want [seconds to 1]
; you probably meant [seconds to 1 by -1]
instead. LiveScript loops and ranges alike always default to counting up, even if you give a number that is greater than the upper limit.
But allowing for that mistake, this result looks right to me. That's what a for loop that iterates over an unknown array looks like when compiled. Arguably, LiveScript could special-case this when the array is a range expression, but... why? The for-loop syntax already gives you a way to express this.
Thanks for the answer.
Is there any use case where for i in [x to y]
form is preferable over for i from x to y
form? If there isn't any, can I explicitly forbid the i in [x to y]
form in my applications?
I can't think of any case where the former is better, no.
FYI:
For those who wants to refactor the entire project to get rid of for i in [x to y]
like usages:
find . -name "*.ls" -and -not -path "*/node_modules/*" | xargs grep -PHn 'for\b.*\s\[(?!(\d+\s+(to|til)\s+\d+)).*\]'
The regex and its test cases are here: https://regex101.com/r/Bj9pZE/3
FYI:
For those who wants to refactor the entire project to get rid of
for i in [x to y]
like usages:find . -name "*.ls" -and -not -path "*/node_modules/*" | xargs grep -PHn 'for\b.*\s\[(?!(\d+\s+(to|til)\s+\d+)).*\]'
The regex and its test cases are here: https://regex101.com/r/Bj9pZE/3
better to do it manually, no ?
better to do it manually, no ?
Yes. The Regex pattern is quite basic, but it works for me. I decided to integrate it into my build tool, so a warning message can be displayed via a popup as the project is saved.
I need to generate the following output, wher
i
is from[0 to 5]
:What is the Livescript equivalent of above Js code?