effekt-lang / effekt

A language with lexical effect handlers and lightweight effect polymorphism
https://effekt-lang.org
MIT License
335 stars 24 forks source link

Multiple copies of a region on the stack #244

Open serkm opened 1 year ago

serkm commented 1 year ago

When a resumption is called within itself, it leads to a region being a subregion of its copy.

Here is an example where a resumption is captured in f and called within the resumption itself. resume(10) calls f() which then calls resume(4) (and resets f to avoid infinite recursion).

effect E {
    def e() : Int
}

def main() : Unit = region r1 {
    var f = fun() { () }
    try region r2 {
      val i = do e()
      var x = 0
      f()
      println(x)
      x = x + i
      println(x)
    } with E {
        def e() = {
          f = fun() {
            f = fun() { () }
            resume(4)
          }
          resume(10)
        }
    }
}

After resume(4) is called, the stack has the shape r2 : r2 : r1 : []. This code prints

0
4
0
10

which is what I'd expect, but should it be possible have multiple copies of a region on the stack?

serkm commented 1 year ago

Update: I changed the example a bit and the output is NOT what I expected.

effect E {
    def e() : (() => Unit at {})
}

def main() : Unit = region r1 {
    try region r2 {
      var x = 0
      val f = do e()
      f()
      println(x)
      x = x + 1
      println(x)
    } with E {
        def e() = {
          def f() = { () }
          def g() = {
            resume(f)
          }
          resume(g)
        }
    }
}

Output:

0
1
1
2

Shouldn't the value of x be 0 when the resumption is called, regardless of other calls of that resumption? Tested on the js backend and all chez backends.

b-studios commented 10 months ago

I tried running the example and on llvm it outputs:

[info] running effekt.Server --noexit-on-error --backend llvm issue244.effekt
[error] scala.NotImplementedError: an implementation is missing
[error]     at scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
[error]     at effekt.machine.Transformer$.transform(Transformer.scala:470)
[error]     at effekt.machine.Transformer$.transform(Transformer.scala:461)
[error]     at effekt.machine.Transformer$.transform(Transformer.scala:133)
[error]     at effekt.machine.Transformer$.transform$$anonfun$22(Transformer.scala:276)
[error]     at effekt.machine.Transformer$.pure$$anonfun$1(Transformer.scala:533)
[error]     at effekt.machine.Transformer$.transform(Transformer.scala:276)
[error]     at effekt.machine.Transformer$.transform(Transformer.scala:94)

Maybe a regression? @phischu ?