Changing the spelling of @execution(caller) nonisolated, an explicit transitional spelling for the accepted future default behavior of nonisolated async functions, to nonisolated(nonsending)
Authors have incorporated an explanation of their rationale and alternatives considered in the revised proposal text. We will have a focused re-review for this change running from now until April 4, 2025.
Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as the review manager by DM. When contacting the review manager directly, please put "SE-0461" in the subject line.
What goes into a review?
The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:
What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available here.
There's a fairly extensive alternatives considered section on the syntax naming choices that have been discussed throughout the review process: swift-evolution/proposals/0461-async-function-isolation.md at main · swiftlang/swift-evolution · GitHub. In particular, there are a few different options I've thought about for the argument to nonisolated, and there may be more that I haven't considered. Please give the section a read!
nonisolated(...) makes a lot of sense as a transitional state. I don't have a strong preference for ..., and as explained in the naming alternatives nonisolated(nonsending) beats few other unsatisfying alternatives. So, it is at least good enough.
Though, I must note that nonisolated(nonsending) looks weird when function has sending arguments:
Needing both @concurrent and nonisolated for functions in actors and GAITs seems redundant to me. IMO, @concurrent on its own is sufficient to non-ambiguously communicate developer's intentions. I'd prefer @concurrent to imply nonisolated:
actor MyActor {
var value = 0
@concurrent
func canRunAnywhere() async {
// cannot access 'value' or other actor-isolated state
}
}
I agree with this. I felt strongly about @exeuction not implying nonisolated when @execution was the base attribute for both behaviors, but now that they're spelled differently, I can't think of any reason not to have @concurrent on its own be sufficient.
I also agree, however I could see some confusion arising when it comes to the @concurrent vs nonisolated distinction when it comes to async and synchronous functions, respectively:
actor A {
// error: nonisolated is redundant here.
// fixit = remove nonisolated.
@concurrent
nonisolated func runAnywhere() async {}
// error: @concurrent cannot be applied to synchronous function.
// fixit = replace @concurrent with nonisolated.
@concurrent
func syncRunAnywhere() {}
}
Maybe we'd just allow nonisolated to still be used with @concurrent though.