We should take into account though that the typealias approach is the most consistent with present day Swift â given how default literal types can be influenced, the distributed actor system default can be set, and we're also looking to offer the same typealias way of setting the default global executors (DefaultExecutorFactory
) -- though that one is pending review still (pitch here).
So the "typealias or not" part of the discussion is somewhat bigger than this specific proposal, it also has impact on the way global executors would be configured (in fact, this proposal already had impact on those, as they moved to the typealias approach).
I think this proposal is good, and the use of private
/ fileprivate
to control how wide the impact the typealias has is quite nice.
I'm somewhat unsure about the unusual spelling of the nonisolated
type(alias). We're doing this trick in order to make it look like we're using the keyword in type position, but it's not the keyword and therefore not a special rule etc. It does mean we can write it in type position though, including:
... where A == nonisolated
// meaningless, unlikely to compile and give false impression
// of "working" in realistic code examples that actually use `A`
func hm() -> nonisolated { ... } // just silly
or other similarly nonsensical signatures. These are a bit silly, and arguably harmless, and perhaps In practice probably most if not all such nonsensical spellings would fail to compile, so at least we're safe from compiling code which looks like it may "conditionalize on isolation".
Will we regret this if at some point we'd have some way of having meaningfully "only if nonisolated" expressiveness in the type system? I'm not sure we'll have such, but it is giving me a pause if we're just using Never
to express this.
--
Exploring ideas if we can get rid of the nil also meaning nonisolated in other contests and use nonisolated instead as a value.
A stated goal of choosing nonisolated
as the spelling is to reduce the number of ways we can spell "nonisolated
", and the remaining elephant in the room of the ways to spell it is: isolated (any Actor)? = nil
, or nil
specifically.
Since we know conditionalizing code on where A == nonisolated / Nonisolated
isn't realistically a thing... I am wondering if another option to think about here is to make use of the nonisolated
as one would expect -- as a value, and extend the custom string representation of (any Actor)? to handle the nil appropriately?
//struct Nonisolated {
// fileprivate init() {}
//}
typealias Nonisolated = (any Actor)?
// typealias nonisolated = Nonisolated
let nonisolated: Nonisolated = nil
extension Optional: CustomStringConvertible where Wrapped == any Actor {
public var description: String {
switch self {
case let .some(act): "\(act)"
default: "nonisolated"
}
}
}
Which does have the problem of A == Nonisolated
now meaning (any Actor)?
but perhaps we could warn about "actually using" that type in locations other than the DefaultIsolation
.
The isolated parameters use-case though flows nicely with this then. It is true however that this is rarely spelled out explicitly, so tbd how much we care about it:
func call(isolation: isolated (any Actor)? = #isolation) {
print("#isolation = \(String(describing: isolation))")
}
await call() // #isolation = Swift.MainActor
await call(isolation: nonisolated) // #isolation = nonisolated
In this world though we'd have to spell the typealias using the uppercase:
typealias DefaultIsolation = Nonisolated
which isn't the same as the keyword, but looks somewhat expected, and it is the same actual "word" just uppercased because it is in type position.
It does probably mean that we'd want to reserve this type's use to only be in the specific DefaultIsolation... so, in this world, would we warn or error about the following?
func call(isolation: isolated Nonisolated = #isolation) {
// error: don't actually use this type in signatures?
Sadly we can't eat the cake and have the cake, i.e. typealias nonisolated = Nonisolated
AND let nonisolated: nonisolated = ...
.
Either way, I am wondering if we can do something about the nil
"nonisolated" while we're trying to solve this default isolation type. If not, then not, and we'll keep sticking around with that nil
-- maybe we can do that custom string description independently of this idea though, might be nice in itself?
edit: The more I looked at this written up the more I had the same concern, that we're pretending a value looking like a keyword for other purposes. So this would have the same problems really. So it's back to the original question if we're happy to do trickery with reusing the same exact word for other purposes, or not.
Either way, I'm in support of the proposal's typealias approach and would just want to make sure we're really confident about that nonisolated
won't cause us trouble and confusion down the line. Maybe along the way we can do something about the nil
spelling as well.