SE-0304 (4th review): Structured Concurrency

This general problem – of being able to distinguish an initializer purely with a marker – has come up before in an evolution proposal, though unfortunately I can't recall which one. IIRC we didn't settle it into an idiom at the time, and that the "a single value enum" overload suggestion was rejected (as was the uglier "defaulted bool" i.e. Task(detached: true)).

This potential solution is well known, but types have a cost (they need to be documented, single-case enums are weird at first glance and are kind of a "trick" solution, albeit a mild one compared to other overloading tricks), and I think there needs to be more justification why Task(.detached) { ... } is better than Task.detached { ... }, beyond stylistic preference or claims of better discoverability.

6 Likes

You might be thinking of SE-0104, but that was for methods rather than initializers.

Wait, a Task is a struct? Previously in these discussions Douglas said they have reference semantics.

How is this struct a reference type?

From the current implementation, Task is a struct that wraps a reference.

So it technically has value semantics but that doesn’t matter because any copy of it will still have the same Handle reference?

You are right. (But I am not sure if we should call it "having value semantics"...

Somewhat of a tangent, but...

the distinction that I've seen in these forums in the past is to differentiate between "has value semantics" and "is a value type." Whether a type is a value type is relatively trivial to determine based on the category of its declaration (enum, struct, tuple, etc.), but determining whether a type has value semantics is potentially much more complicated and heavily implementation-dependent. Consider Array which also wraps a reference internally but still "has value semantics."

Of course, what it even means, precisely, to "have value semantics" isn't something that is entirely clear yet, and might not even make sense to talk about at the level of a type as a whole, so right now we're still mostly in "know it when you see it" territory.

3 Likes

Right, structs aren't necessarily value semantic. Two easy example are UnsafeBufferPointer and Array<YourClass>. Both are structs, but neither have what we'd traditionally consider values semantics for their "contained" values.

4 Likes

Just want to thank you all for working so hard to get this right.

I haven't been participating in this discussion, but have skimmed new content in the thread from time to time. It's clearly complicated, important, and will have a big impact on many users of Swift for years to come.

So, thank you.

8 Likes
Terms of Service

Privacy Policy

Cookie Policy