Allow go statements in certain circumstances #150
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We don't currently allow
go
statements when compiling functions because there's no structured concurrency in Go; goroutines are executed independently (there's no hierarchy; no concept of ownership), and we are unable to suspend execution of related goroutines when another goroutine explicitly yields.The compiler only needs to compile a subset of functions in the program; those that yield, those that may be on the call stack of a coroutine that yields, or those that contain a function literal that yields or may end up on the call stack of a coroutine that yields. All other functions are allowed to use
go
.This PR relaxes the restrictions a bit so that certain functions are now allowed to use
go
.The major use case we unlock is to allow patterns like this, which seems to come up a lot:
If the compiler determines that the
coroutine
function literal yields explicitly, or may end up on the call stack of a coroutine that yields explicitly, it needs to compile both the inner function literal and the outer function (since #135). We currently reject thego
statement in the outer function, even though it may not interact with any coroutines.This PR relaxes the restriction; we allow
go
statements in this one instance. The goroutine could still mutate state from the outer function which is then read/mutated within the inner function literal. Given that we do not support serializing synchronization primitives at this time (e.g. channels, mutexes), the assumption is that the user isn't doing anything unsafe and that it's fine to allow thego
statement. It prints a warning just in case.