effekt icon indicating copy to clipboard operation
effekt copied to clipboard

js runtime: `CAPTURE` drops the return value

Open marzipankaiser opened this issue 7 months ago • 2 comments

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
  }))
}

Playground


Thanks @b-studios for helping to find the underlying cause.

marzipankaiser avatar May 22 '25 15:05 marzipankaiser

Just to be sure, the expected/desired behavior is that the return value is not dropped but returned instead of unit?

dvdvgt avatar Jul 03 '25 08:07 dvdvgt

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.

b-studios avatar Jul 03 '25 09:07 b-studios