effekt-lang / effekt-lang/effekt
Miscompilation of Knuth's "man or boy test" program on JS
- Dominant language
- Scala
- Stars
- 469
- Forks
- 41
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 23
Description
In the following [famous](https://en.wikipedia.org/wiki/Man_or_boy_test) program (the Effekt translation being based on the [Koka version](https://rosettacode.org/wiki/Man_or_boy_test#Koka)), Effekt miscompiles it on the JS backend with NodeJS reporting "ReferenceError: b_0 is not defined" at runtime.
```scala
def a(k: Int) { x1: => Int } { x2: => Int } { x3: => Int } { x4: => Int } { x5: => Int }: Int = {
if (k <= 0) x4() + x5()
else {
val m = ref(k)
def b(): Int = {
m.set(m.get - 1)
a(m.get) {b} {x1} {x2} {x3} {x4}
}
b()
}
}
def main() = {
println(a(10) {1} {-1} {-1} {1} {0})
}
```
But it does work when I eta expand `{b}` manually to `{ () => b() }` + it works on LLVM and Chez.
It also crashes when compiled with `--no-optimize`.
This might be related to #1229 and #1358.
Also, cc @phischu, this might not be the worst benchmark, the wiki link above has known values & it scales by the arg given to `a` :)
---
Here's the JS translation (same with and without opts) of `a`:
```js
function a_0(k_0, x_2, x_4, x_3, x_0, x_1, ks_0, k_1) {
a_1: while (true) {
if ((k_0 <= (0))) {
return x_0(ks_0, (v_r_0, ks_1) =>
x_1(ks_1, (v_r_1, ks_2) => () => k_1((v_r_0 + v_r_1), ks_2)));
} else {
const v_r_2 = { value: k_0 };
const v_r_3 = v_r_2.value;
const v_r_4 = set$impl(v_r_2, ((v_r_3 - (1))));
const v_r_5 = v_r_2.value;
/* prepare call */
const tmp_x_0 = x_0;
const tmp_x_1 = x_2;
const tmp_x_2 = x_3;
const tmp_x_3 = x_4;
k_0 = v_r_5;
x_2 = b_0; // <- oops, `b_0` not defined!
x_4 = x_2;
x_3 = x_4;
x_0 = x_3;
x_1 = x_0;
continue a_1;
}
}
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.