effekt icon indicating copy to clipboard operation
effekt copied to clipboard

No supertype allowed in handler return

Open marzipankaiser opened this issue 1 year ago • 3 comments

The following program gives the annotated error:

interface Done {
  def done(): Nothing
}

def main() = {
  try {
    do done()
  } with Done {
    def done() = ()   // Error: Expected Nothing but got Unit.
  }
}

Is this the behaviour we want?

Note that this also disallows, e.g., a hole instead of do done().

marzipankaiser avatar Sep 24 '24 12:09 marzipankaiser

What would you expect, otherwise? The answer type of the handler is Nothing unless you upcast it there.

We could of course compute the join of the different handlers and the answer type.

b-studios avatar Sep 24 '24 12:09 b-studios

I'll bump this and add the following example:

effect emit[A](value: A): Unit
effect fork(): Bool
effect fail(): Nothing

def select[A] { stream: () => Unit / emit[A] }: A / {fork, fail} =
  try {
    stream()
    do fail()
  } with emit[A] { value =>
    if (do fork()) {
      return value
    } else {
      resume(())
    }
  }

We should compute the join of the handlers and the answer type, yes.

phischu avatar Mar 06 '25 12:03 phischu

As a workaround, the following does typecheck:

def select[A] { stream: () => Unit / emit[A] }: A / {fork, fail} = {
  def body(): A / emit[A] = {
    stream()
    do fail()
  }
  try {
    body()
  } with emit[A] { value =>
    if (do fork()) {
      return value
    } else {
      resume(())
    }
  }
}

After inlining body we are back to the original which does not.

phischu avatar Mar 10 '25 11:03 phischu