Here's a neat trick with `async let` I didn't realize. You can use it to avoid blocking on synchronous work.
@mattiem please let me unsee it 😄
@a_grebenyuk It is really verbose!
@mattiem what can I say, there is no lack of ways to move work to the background. But my favorite continues to be performSelectorInBackground:withObject:, of course.
@a_grebenyuk I’m partial to Thread.detached

@mattiem but, to be serious for a second, having a convenient way of turning any sync method into an async one would be cool, which this is not (convenient).

How about this lol?
(wait) no it doesn't work simply like that

@mattiem I'm not posting to the forum thread more, but I think it's a good demonstration that maybe, just maybe, moving work to the background needs to be a bit more verbose for the sake of clarify.

"clarity at the point of use is your most important goal." (which is long forgotten)

https://www.swift.org/documentation/api-design-guidelines/#fundamentals

Swift.org

Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.

Swift.org

@a_grebenyuk yeah.

I haven't thought really deeply about this. But I'm pretty sure callee-defined correctness/safety is very good, but caller-defined background work is what's missing.

(and yes, it needs to be clear, even if the compiler can prove it to be safe)

@mattiem oops, it doesn't compile. This does:

@a_grebenyuk Right. I think a little sugar could make this quite nice.

However I found a bug that makes this harder to use, and seems to apply to closure literals too

https://github.com/swiftlang/swift/issues/76727

async let + sending doesn't seem to work ¡ Issue #76727 ¡ swiftlang/swift

Description I was trying to get around returning a non-Sendable type from a synchronous function. I thought I'd be able to use sending to deal with this, but it doesn't seem to work. Reproduction c...

GitHub
@mattiem I would prefer to use none of these options. If you look at this with no Swift Concurrency baggage, you would expect it to run synchronously and return a value immediately since there are no suspension points.
@mattiem take this with a grain of salt as I'm no expert, but in other languages I encountered, such as C# and JavaScript, async methods with no suspension points run synchronously or until the first suspension point.
@a_grebenyuk Yes and there’s a possibility that’s how it ends up working eventually in this case. I’m not 100% sure yet…
@mattiem @a_grebenyuk and that’s what I don’t like 😂 there is an await, you shouldn’t have to assume that it will be immediate and sync. Imo that’s a core principle we shouldn’t break.
@alexito4 @mattiem it is OK to assume that it will be async and dispatched on a global task executor suitable for running background work? It works both ways.
@a_grebenyuk @mattiem I partially agree, but in my view, it is not the same at all—by far. There is an await; it’s there for a reason.
@alexito4 @mattiem that's a fair point. I wonder if there is some middle ground. The main challenges you run into are with how you model isolation which this contrived example doesn't demonstrate. It's a tough call. I think it's unlikely it'll be possible to change at this point because it will be a 180 and not just on this part.
@a_grebenyuk @mattiem Yeah, there are a few axis to take into account that are hard to balance and figure out. I wish we had had more time to polish these things. I’m just hesitant to lose what makes Swift concurrency such a step forward compared to the rest. It’s already hard enough to help people not reach for unstructured concurrency just because it looks like what we had before. 😂

@alexito4 @a_grebenyuk I think you two are really on to something with this tension.

Today, “await” does not mean “won’t block”. It does not even mean “will be async”!

I really believe that the language is 90% of the way there. Providing a clearer mental model for non-experts PLUS some nice way for callers to be in control of blocking work are missing pieces.

@mattiem @alexito4 @a_grebenyuk that is an interesting point. Seems like an await should NOT be required in this case kind of like Actors calling into themselves.
@jasongregori @alexito4 @a_grebenyuk It is not for synchronous methods. But if async and isolation does not change, there is guaranteed to be no suspension on function call and return, which can be important.