Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

["Request"] reuse Raise instance for recover #3334

Closed
kyay10 opened this issue Dec 21, 2023 · 1 comment
Closed

["Request"] reuse Raise instance for recover #3334

kyay10 opened this issue Dec 21, 2023 · 1 comment

Comments

@kyay10
Copy link
Collaborator

kyay10 commented Dec 21, 2023

Related to #3126 and #3052.

The idea is to provide some way for recover, when called within a Raise, to reuse that Raise object not only for performance reasons, but also by re-exposing all the APIs that the original Raise had. This would theoretically work by capturing the CE like what fold does, with perhaps some mechanism to access the underlying Raise instance that a custom Raise implementation is using.
This has the issue, however, that leaks won't be detectable if they happen within a recover, and then they're invoked before the outer raise finishes. For example:

either<Int, Int> {
  lateinit var f: (String) -> Nothing
  recover({ f = { raise(it) } }) {}
  f("foo") 
}

Currently, this gets detected as a leak, but I can't imagine a way for that to work if the Raise gets reused.

@kyay10
Copy link
Collaborator Author

kyay10 commented Jan 18, 2024

I experimented a little with this, and I'm quite sure that this isn't possible. It comes down to the idea that any 2 Raise instances that we have in scope could actually be the same ones. This is due to Raise being declared as in. Even if it was invariant, the reusing mechanism would thus have to be invariant and hence wouldn't be very helpful.
Consider this code:

either<Any, Unit> {
  foo()
}
context(Raise<Int>, Raise<String>)
fun foo() = recover<Int, _>({
  raise("bar")
} { error: Int ->
  // CCE if we're reusing raise instances
}

Note also that re-exposing APIs is unnecessary when we get context receivers. Any "performance" that could be gotten out of this is surpassed by the runtime errors it would cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant