gkz / LiveScript

LiveScript is a language which compiles to JavaScript. It has a straightforward mapping to JavaScript and allows you to write expressive code devoid of repetitive boilerplate. While LiveScript adds many features to assist in functional style programming, it also has many improvements for object oriented and imperative programming.
http://livescript.net
MIT License
2.31k stars 156 forks source link

Incorrect if JavaScript depending on context #1098

Closed LeXofLeviafan closed 4 years ago

LeXofLeviafan commented 4 years ago

When compiling the code x = (if foo! then bar(that) or baz(that)) (that is, relying on if-let to locally bind result of the first subexpression), the resulting JavaScript looks like this:

x = (that = foo()) ? bar(that) || baz(that) : void 8;

Which works pretty straightforwardly, as one would expect. If, however, you pass the same exact expression to, say, while loop, the output will have different structure:

while (if foo! then bar(that) or baz(that))
  console.log 42
while ((that = foo()) && bar(that) || baz(that)) {
  console.log(42);
}

Which deviates from expected behaviour, because now baz will be executed even when that is falsey (due to JavaScript operator precedence). It is possible to reproduce structure from the first example in second case, but only by providing an explicit else branch:

while (if foo! then bar(that) or baz(that) else void)
  console.log 42
while ((that = foo()) ? bar(that) || baz(that) : void 8) {
  console.log(42);
}
rhendric commented 4 years ago

I'm really glad you reported this. I remember when I was investigating #1096, I noticed the code that caused this issue and idly wondered how it was that it worked. It can't be broken, I thought; surely someone would have reported that bug! So much for that flawless reasoning. :grimacing: