js runtime: `CAPTURE` drops the return value
When using CAPTURE in the javascript backend, this replaces the return value by $effekt.unit. Some of the existing FFI relies on this behavior (we then don't have to explicitly return unit):
https://github.com/effekt-lang/effekt/blob/fea824aa840891375c7cea198b38babfb3076338/libraries/js/effekt_runtime.js#L83-L89
Example program
The following program triggers above behavior via promise.resolve.
import io
extern io def rT[T](run: => T at {io, async, global}): T =
js "$effekt.runToplevel((ks, k) => ${run}(ks, k))"
def main() = {
val pr = promise::make[Int]()
println(rT[Int](box {
pr.resolve(2);
12
}))
}
Thanks @b-studios for helping to find the underlying cause.
Just to be sure, the expected/desired behavior is that the return value is not dropped but returned instead of unit?
It's not that simple. In many cases we want to return unit, since we use it mostly for async calls that don't return anything.
The right thing to do would be to change CAPTURE to actually return the value, then change all calls to return unit, then be annoyed and potentially creating a derived version of CAPTURE that does return unit.