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

Lift a simple function into an operation safely. #879

Merged
merged 1 commit into from
Jan 8, 2024
Merged

Lift a simple function into an operation safely. #879

merged 1 commit into from
Jan 8, 2024

Conversation

cowboyd
Copy link
Member

@cowboyd cowboyd commented Jan 6, 2024

Motivation

There is the potential for a function, if it is a continuation, to cause the scope in which it is called to be destroyed. In this case, nothing after that function should ever be called. However, because of the way lift() is currently implemented, this will not be the case.

Approach

This unpacks the lift() function just a bit to return an operation with a single instruction that immediately returns the result of invoking the function. However, because there is a yield point in the computation, it is an opportunity to not continue which will happen if corresponding frame is closed as a result of calling the function.

You can see in the test case how when the spawned producer closes the signal, it cause its parent to finish up and return, meaning that the producer should shut down immediately and not continue executing.

At the same time, it removes the named types since they don't really add much clarity when you look at them from your language server.

@cowboyd cowboyd requested a review from neurosnap January 6, 2024 03:08
lib/lift.ts Outdated
*[Symbol.iterator]() {
return yield () => {
return shift(function* (k) {
k({ ok: true, value: fn(...args) });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be k.tail since you don't care about the return value of k?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!

There is the potential for a function, if it is a continuation, to
cause the scope in which it is called to be destroyed. In this
case, nothing after that function should ever be called. However,
because of the way `lift()` is currently implemented, this will not be
the case.

This unpacks the `lift()` function to be a single instruction that
immediately returns value of invoking the function. However, because
there is a `yield` point in the computation, it is an opportunity to
not continue which will happen if corresponding frame is closed.

At the same time, it removes the named types since they don't really
add much clarity when you look at them from your language server.
@cowboyd cowboyd merged commit bb95749 into v3 Jan 8, 2024
3 checks passed
@cowboyd cowboyd deleted the safe-lift branch January 8, 2024 14:19
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

Successfully merging this pull request may close these issues.

2 participants