or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
Reading notes: Async/await in Swift
tags:
reading-club
https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md
Leave questions, observations, discussion topics below.
Composition of effects
It stands out to me that one of the motivations is: "we added syntax to make error handling nice, but callbacks didn't allow us to reap any benefits from it". Composition of language features seems like a big problem for most languages, and they call it out explicitly here.
Also in terms of composition: it seems they've done the same thing we've done by separating "fallibility" and "asyncness". In JavaScript-style async/await these two are the same: "asyncness" always implies "fallibility" (
resolve
vsreject
in JS). Swift seems to mirror a lot of the choices we've made - at least on the surface.nikomatsakis: Interesting; I was having a conversation about this on moro. The danger if you ignore errors is that you can spawn a task that yields a
Result<(), E>
and never realize that it resulted inErr
, and hence fail to take down your scope. Making the API more tailored to Result avoids that danger, but it bakes in "error".yosh: Structured concurrency RFC should talk about this?
tmandry: Swift lets you coerce(?) an infallible function to fallible, so their structured concurrency doesn't have this problem.
JavaScript
The "pyramid of doom"-style callback nesting is identical to how Yosh used to write async code in JS (:
await covers all subexpressions
nikomatsakis: Really interesting that
await
covers all async functions "inside" the await, so that e.g.works even if
server.redirectURL
is async.No futures
tmandry: Interesting that they eschewed the Future model completely. You always must have
await
to call an async function in Swift. A singleawait
can also cover multiple calls in an expression. It marks suspension points but isn't itself a suspension point.I think this means that all combinator-style interfaces happen on tasks.
guswynn: didnt really understand the motivation here? seem concerned about "futures being big", but the size is fixed based on the compiler-generated generator, regardless of if you are returning a type or building
async
into the type system?tmandry: Part of it is consistency with
throws
and thetry
effect. Also Swift cares less about performance, more about reliability and predictability and ease of use.All futures are send?
This seems like perhaps unlike us, Swift doesn't distinguish between concurrency and parallelism: all futures are multi-threaded, so all futures must be thread-safe. This doesn't seem to be the case for non-async Swift tho?
This may be the same point Tmandry makes in the previous section tho :P
tmandry: That's right, but they do some interesting stuff in the actors RFC to propagate execution contexts. Since actors are serial queues this allows you to skip synchronization if you're already running on that queue.
tmandry: Also they can't split mut references to their enclosing context across multiple sub-tasks.
guswynn: question: does swift do anything to prevent overlapping mutable access?
Encourage people to write code using models like actors. Also copy-on-write collections.
Async protocols and closures just work
The swift equivalent of async-fn-in-trait just works…likely because swift is willing to just box as aggressively as possible.
Similarly, async closures are part of this proposal. Again, boxing and what not avoids typical hrtb lifetime problems we see with "closures that return futures" we see in rust.
pnkfelix: recursive functions probably come out of this design as well, as guswynn pointed out to me in zoom chat
nikomatsakis: Would be good to compare and see what problems fall out.
..some discussion around HRTB problems and maybe we know how to fix them now?
Examples… wanting to write things like…
tmandry: Also Swift Arcs everything if it's shared.
Async operator overloading
As far as I can tell, is scoped to functions, not protocol methods. I (guswynn) am also curious to see how operator overloading plays out in practice. Will async versions of libraries using actors/the structured concurrency proposal be able to keep the same api boundary as sync versions?
niko: Interesting that they think you want
map
to be parallel/concurrent in an async context. Doesn't sound very robust. Example: Could parse something and get a sequence of commands.Yosh: wrote a blog post on why concurrent iteration semantics are not the right default for Rust: https://blog.yoshuawuyts.com/async-iteration/
Felix: Map where order matters feels wrong. But would be better to opt in to parallel iteration.
Felix: Guy Steele talk about how iterators are wrong https://www.youtube.com/watch?v=ftcIcn8AmSY or https://www.youtube.com/watch?v=dPK6t7echuA
await
motivation is interestingYosh thinks this is a really neat motivation that we might want to consider adapting for our conversations around "why should
.await
be annotated"?nikomatsakis: It's interesting because
await <expr>
is intentionally "non-specific" about where the interruptions can occur.