Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,11 @@ knows only its arity, and a bare or partially applied reference is the same adap
any number of times, or call it for a fresh coroutine, as it would a zero-argument `async def`
(`asyncio.run(job())`): `_pf_Async.__call__` is `async def __call__(self): return await self`.
Python 3.14's `asyncio.run` accepts any awaitable, but 3.12 and 3.13 want a coroutine, so code that
must run on them calls the value.
must run on them calls the value. Cold also means an `extern` whose Python call starts work at once
(a call returning an `asyncio` Task or Future, or a JS promise under Pyodide) now starts it at the
await: two such calls bound with `let` and awaited afterwards run one after the other, where they
used to overlap, and awaiting one twice makes the call twice. A program overlaps work by handing it
to `Async.parallel` (or `race`) together, which starts every element before awaiting any.

**Async combinators — the `Async` module.** `async { }` builds an `Async a`; the module is the rest
of what F#'s `Async` offers that `asyncio` can supply, typed once
Expand Down Expand Up @@ -962,7 +966,9 @@ holds (a lifetime detail a façade hides). The cookbook's `browser/` entry is th
`Dom` module a program imports, with a counter page as its consumer. Two things fall out of work
already done: a click handler is an ordinary one-parameter Pyfun function (Python calls it with the
event, §6's calling convention), and a JS `Promise` is awaitable under Pyodide, so an extern over a
JS async API is typed `-> Async a` and awaited with `let!` like any other, no bridge to build.
JS async API is typed `-> Async a` and awaited with `let!` like any other, no bridge to build. Since
an `Async` is cold (§8), the JS call is made at the await, so requests meant to overlap go to
`Async.parallel` together.
Signalling for a peer-to-peer transport is the program's problem, not the language's.

**Derived codecs — `Decode.auto` and `Encode.auto`.** A program that speaks to itself over a wire
Expand Down
5 changes: 5 additions & 0 deletions docs/src/learn/18-async.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ The block runs twice, once for each `let!`. A Python coroutine can only be await
await runs it again from the start. F# calls this a *cold* async. It means you can keep an `Async` in
a variable, pass it to a function that retries it, or put the same one in a list twice.

It also means nothing starts early. Two `let!` lines in a row run one after the other, because the
second value has not started by the time the first finishes. When you want several things to run at
the same time, such as two web requests, hand them to `Async.parallel` together, which you will meet
in a moment.

## Running one at the top level

An `Async` value has to be awaited somewhere, and at the top level there is no enclosing `async`
Expand Down
5 changes: 5 additions & 0 deletions docs/src/notebooks/18-async.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
"await runs it again from the start. F# calls this a *cold* async. It means you can keep an `Async` in\n",
"a variable, pass it to a function that retries it, or put the same one in a list twice.\n",
"\n",
"It also means nothing starts early. Two `let!` lines in a row run one after the other, because the\n",
"second value has not started by the time the first finishes. When you want several things to run at\n",
"the same time, such as two web requests, hand them to `Async.parallel` together, which you will meet\n",
"in a moment.\n",
"\n",
"## Running one at the top level\n",
"\n",
"An `Async` value has to be awaited somewhere, and at the top level there is no enclosing `async`\n",
Expand Down
Loading