Is there any meaningful analogue to rethrows
in an async
/await
world, i.e., a function which is async
if and only if a provided closure parameter is async
?
Thank you, fixed
Maybe we can add reasync
later should it be needed? At least the current proposal doesn't seem to clash with that.
It's hard to say. I can certainly imagine situations where it might be useful, but I'm not sure there are enough to justify the complexity cost, which behind the scenes would be quite substantial — we'd essentially have to rig up a complete task just to call the function, then throw it away. The thing is that many higher-order functions probably need to think carefully about how they ought to work with an async function — guaranteeing sequential use is not necessarily what clients would actually want.
The most important use case would probably be withFoo
functions that introduce a scoped value, and I'd really prefer to address those with a more targeted coroutine feature — they're problematic for a lot of other things besides async
.
This design currently provides no way to prevent the current context from interleaving code while an asynchronous function is waiting for an operation in a different context. This omission is intentional: allowing for the prevention of interleaving is inherently prone to deadlock.
This should also be in the reference doc once it's included/accepted. It took a lot of cross-reading to find this sentence that makes sense of a lot of design decisions on the other threads. It's also easily surprising.
Rationale : This order restriction is arbitrary, but it's not harmful, and it eliminates the potential for stylistic debates.
Praise be.
Why is async specified after the func declaration, rather than before, e.g. async func f()?
It's the same place where throws
is specified, because it has a similar role in the type system.
Doug
Good explanation! I wonder though why:
await other.asyncFunction(otherActor: self)
In rust, one would have:
other.asyncFunction(otherActor: self).await
and optionally:
other.asyncFunction(otherActor: self).await?
Which is quite handy as other.asyncFunction(otherActor: self)
returns a Future? await makes this the type returned by the Future? With .await
you can chain on this? With rust if this is a Result<Success, Error> type, then ? resolves it to Success or returns Error from the "block".
Will await other.asyncFunction(otherActor: self)
need parentheses to chain on its results?
Async is an adjective, and throws is a verb, so adjective-object-verb makes sense. How/why does the type system factor into this?
async
and throws
are both part of the type of a function. I.e, if you have
func foo() async throws {}
let bar = foo
then the type of bar
is () -> () async throws
. OTOH, if you had something like:
private func foo() {}
public let bar = foo()
then the type of bar
is just () -> ()
(i.e., private
is not part of the type).
Unrelated, but what's that language? It doesn't seem to be English.
Subject, rather.
Or, async
is an adverb, being an abbreviation for “asynchronously”: () async -> Int
is a function that asynchronously returns an integer.
You can find a detailed discussion of this in the asynchronous functions proposal. The short answer is that await
is like try
and doesn't need to be pedantically placed on the exact asynchronous operation, as long as it logically "covers" it.
Are there any plans on naming conventions for async functions? for example in C# its convention to postfix async function names with "async". Is this something that has been discussed for swift?
It doesn't seem necessary to postfix the name when the async
attributes requires the use of await
at the call site.
I imagine it is similar to other uses of the async/await keywords in other languages, it makes it clear that asynchronous work is done in that function.
Plus from an API consumer point of view, you may not know the implementation of a method and what it is doing, knowing it has asynchronous calls which may be suspended
The fact that you have to await the function, or use it with a local async variable, should be enough to make that distinction. It's the same reason we don't end methods marked with throws
with Throwing
.
In what sense? The compiler telling you?
It’s the same case with throws, if you can only see the public declaration then you know that there is the chance of the function calling asynchronous code.
I guess the difference is that with throws you can override catching/failing gracefully with try!
for asynchronous functions you can’t override that...
Maybe this can continue over [Concurrency] Asynchronous functions? I think it's getting out of a roadmap thread.
(Moderator note: this post and the chain of posts it responds to were originally in the roadmap thread)