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

Add a prospective vision for improving the approachability of data-race safety. #2621

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hborla
Copy link
Member

@hborla hborla commented Nov 23, 2024

Pitched on the forums at https://forums.swift.org/t/prospective-vision-improving-the-approachability-of-data-race-safety/76183. Please leave design feedback there, and editorial feedback here!


The current execution semantics of async functions also impede programmer’s understanding of the concurrency model because there is a significant difference in what `nonisolated` means on synchronous and asynchronous functions. Nonisolated synchronous functions always run in the isolation domain of the caller, while nonisolated async functions always switch off of the caller's actor (if there is one). It's confusing that `nonisolated` does not have a consistent meaning when applied to functions, and the current behavior conflates the concept of actor isolation with the ability for a function to suspend.

Changing the default execution semantics of nonisolated async functions to run wherever they are called default better facilitates progressive disclosure of concurrency. This default allows functions to leverage suspension without forcing callers to cross an isolation boundary and imposing data-race safety checks on arguments and results. A lot of basic asynchronous code can be written correctly and efficiently with only the ability to suspend. When an async function needs to always run off of an actor, the API author can still specify that with an annotation on the function. This provides a better default for most cases while still maintaining the ease of specifying that an async function switch off of an actor to run.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

Changing the default execution semantics of nonisolated async functions to run wherever they are called default better facilitates progressive disclosure of concurrency.


When an async function needs to always run off of an actor, the API author can still specify that with an annotation on the function.

to what annotation(s) is this referring?


Changing the default execution semantics of nonisolated async functions to run wherever they are called default better facilitates progressive disclosure of concurrency. This default allows functions to leverage suspension without forcing callers to cross an isolation boundary and imposing data-race safety checks on arguments and results. A lot of basic asynchronous code can be written correctly and efficiently with only the ability to suspend. When an async function needs to always run off of an actor, the API author can still specify that with an annotation on the function. This provides a better default for most cases while still maintaining the ease of specifying that an async function switch off of an actor to run.

Many programmers have internalized the SE-0338 semantics, and making this change several years after SE-0338 was accepted creates an unforuntate intermediate state where it's difficult to understand the semantics of nonisolated async function without understanding the build settings of the module you're writing code in. We can alleviate some of these consequences with a careful migration design. There are more details about migration in the [automatic migration](#automatic-migration) section of this document, and in the [source compatibility](https://github.com/hborla/swift-evolution/blob/async-function-isolation/proposals/NNNN-async-function-isolation.md#source-compatibility) section of the proposal for this change.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

it's difficult to understand the semantics of nonisolated async function

should perhaps be 'semantics of a...' or '...functions'

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