From 22c4776f9fddef47a6ce3f309e4eafa2fbdc3a65 Mon Sep 17 00:00:00 2001 From: JJ Date: Sun, 28 Jan 2024 01:32:52 -0800 Subject: docs: host mdbook --- docs/book/ASYNC.html | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 docs/book/ASYNC.html (limited to 'docs/book/ASYNC.html') diff --git a/docs/book/ASYNC.html b/docs/book/ASYNC.html new file mode 100644 index 0000000..af56864 --- /dev/null +++ b/docs/book/ASYNC.html @@ -0,0 +1,285 @@ + + + + + + Async System - The Puck Programming Language + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Asynchronous Programming

+
+

! This section is a draft. Many important details have yet to be ironed out.

+
+

Puck has colourless async/await, heavily inspired by Zig's implementation.

+
pub func fetch(url: str): str = ...
+
+let a: Future[T] = async fetch_html()
+let b: T = a.await
+let c: T = await async fetch_html()
+
+

Puck's async implementation relies heavily on its metaprogramming system.

+

The async macro will wrap a call returning T in a Future[T] and compute it asynchronously. The await function takes in a Future[T] and will block until it returns a value (or error). The Future[T] type is opaque, containing internal information useful for the async and await routines.

+
pub macro async(self): Future[T] =
+  ... todo ...
+
+
pub func await[T](self: Future[T]): T =
+  while not self.ready:
+    block
+  self.value! # apply callbacks?
+
+

This implementation differs from standard async/await implementations quite a bit. +In particular, this means there is no concept of an "async function" - any block of computation that resolves to a value can be made asynchronous. This allows for "anonymous" async functions, among other things.

+

This (packaging up blocks of code to suspend and resume arbitrarily) is hard, and requires particular portable intermediate structures out of the compiler. Luckily, Zig is doing all of the R&D here. Some design decisions to consider revolve around APIs. The Linux kernel interface (among other things) provides both synchronous and asynchronous versions of its API, and fast code will use one or the other, depending if it is in an async context. Zig works around this by way of a known global constant that low-level functions read at compile time to determine whether to operate on synchronous APIs or asynchronous APIs. This is... not great. But what's better?

+ +

Threading

+

It should be noted that async is not the same as threading, nor is it solely useful in the presence of threads...

+

How threads work deserves somewhat of a mention...

+

References:

+ +

Is async worth having separate from effect handlers? I think so...

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + -- cgit v1.2.3-70-g09d2