diff --git a/design/mvp/Async.md b/design/mvp/Async.md index f80fb4ca..a09de47b 100644 --- a/design/mvp/Async.md +++ b/design/mvp/Async.md @@ -154,7 +154,40 @@ component-level function that has been [lifted] from Core WebAssembly with the function that does not have the `async` option set (which is the default and only option prior to Preview 3). Thus, the sync/async distinction appears only independently in how a component-level function is *implemented* or -*called*. +*called*. This lack of distinction helps to avoid the classic ["What Color Is +Your Function?"][Color] problem. + +Functions *may* however be annotated (in both WIT and component binaries) with +`async` as a *hint*. This hint is intended to inform the default language +bindings generation, indicating whether to use a source-level `async` function +or not in languages that have such a distinction (e.g., JS, Python, C# and +Rust). In the absence of such a hint, a bindings generator would be forced to +make a uniform decision for what to do by default for all functions or require +manual programmer directives. However, because `async` is just a hint, there is +no prohibition against non-`async`-exported functions calling imported `async` +functions. This does mean that non-`async` functions may end up blocking +their caller, but (1) any loss in performance is the callee's "fault", (2) the +caller can still lower `async` if they want to (overriding the default hint), +(3) any *transitive* caller an lower `async` to avoid blocking. + +For example, given this interface: +```wit +interface filesystem { + resource file { + constructor(); + is-closed: func() -> bool; + read: async func(num-bytes: u32) -> result>; + from-bytes: static func(bytes: list) -> file; + from-stream: static async func(bytes: stream) -> file; + } +} +``` +a bindings generator in a language with `async` would only emit `async` +functions for `read` and `fetch`. Since in many languages `new` expressions +cannot be async, there is no `async constructor`. Use cases requiring +asynchronous construction can instead use `static async` functions, similar to +`from-stream` in this example. + ### Task @@ -709,11 +742,9 @@ time as applications are built with more components. ## TODO Native async support is being proposed incrementally. The following features -will be added in future chunks roughly in the order list to complete the full +will be added in future chunks roughly in the order listed to complete the full "async" story, with a TBD cutoff between what's in [WASI Preview 3] and what comes after: -* `nonblocking` function type attribute: allow a function to declare in its - type that it will not transitively do anything blocking * `subtask.cancel`: allow a supertask to signal to a subtask that its result is no longer wanted and to please wrap it up promptly * zero-copy forwarding/splicing diff --git a/design/mvp/Binary.md b/design/mvp/Binary.md index 915afcc3..04f71ffa 100644 --- a/design/mvp/Binary.md +++ b/design/mvp/Binary.md @@ -270,8 +270,7 @@ Notes: * All parameter labels, result labels, record field labels, variant case labels, flag labels, enum case labels, component import names, component export names, instance import names and instance export names must be - unique in their containing scope, considering two labels that differ only in - case to be equal and thus rejected. + [strongly-unique] in their containing scope. * Validation of `externdesc` requires the various `typeidx` type constructors to match the preceding `sort`. * (The `0x00` immediate of `case` may be reinterpreted in the future as the @@ -383,8 +382,8 @@ Notes: of the inferred `externdesc` of the `sortidx`. * `` and `` refer to the productions defined in the [text format](Explainer.md#import-and-export-definitions). -* The ``s of a component must be unique and the ``s of - a component must be unique as well (defined in terms of raw string equality). +* The ``s of a component must all be [strongly-unique]. Separately, + the ``s of a component must also all be [strongly-unique]. * Validation requires that annotated `plainname`s only occur on `func` imports or exports and that the first label of a `[constructor]`, `[method]` or `[static]` matches the `plainname` of a preceding `resource` import or @@ -394,8 +393,6 @@ Notes: `(result (own $R))`, where `$R` is the resource labeled `r`. * Validation of `[method]` names requires the first parameter of the function to be `(param "self" (borrow $R))`, where `$R` is the resource labeled `r`. -* Validation of `[method]` and `[static]` names ensures that all field names - are disjoint. * `` is as defined by [https://semver.org](https://semver.org/) * `` is as defined by the [SRI](https://www.w3.org/TR/SRI/#dfn-integrity-metadata) spec. @@ -514,6 +511,8 @@ named once. [`core:functype`]: https://webassembly.github.io/spec/core/binary/types.html#binary-functype [`core:rectype]: https://webassembly.github.io/gc/core/binary/types.html#recursive-types +[Strongly-unique]: Explainer.md#name-uniqueness + [type-imports]: https://github.com/WebAssembly/proposal-type-imports/blob/master/proposals/type-imports/Overview.md [module-linking]: https://github.com/WebAssembly/module-linking/blob/main/proposals/module-linking/Explainer.md diff --git a/design/mvp/Explainer.md b/design/mvp/Explainer.md index b34146b8..5ab6ef0b 100644 --- a/design/mvp/Explainer.md +++ b/design/mvp/Explainer.md @@ -32,6 +32,7 @@ more user-focused explanation, take a look at the * [Value definitions](#-value-definitions) * [Start definitions](#-start-definitions) * [Import and export definitions](#import-and-export-definitions) + * [Name uniqueness](#name-uniqueness) * [Component invariants](#component-invariants) * [JavaScript embedding](#JavaScript-embedding) * [JS API](#JS-API) @@ -782,8 +783,8 @@ The remaining 4 type constructors in `deftype` use `valtype` to describe shared-nothing functions, resources, components, and component instances: The `func` type constructor describes a component-level function definition -that takes a list of uniquely-named `valtype` parameters and optionally returns -a `valtype`. +that takes a list of `valtype` parameters with [strongly-unique] names and +optionally returns a `valtype`. The `resource` type constructor creates a fresh type for each instance of the containing component (with "freshness" and its interaction with general @@ -2173,16 +2174,17 @@ new identifier `$x`). import ::= (import "" bind-id()) export ::= (export ? "" ?) ``` -All import names are required to be unique and all export names are required to -be unique. The rest of the grammar for imports and exports defines a structured -syntax for the contents of import and export names. Syntactically, these names -appear inside quoted string literals. The grammar thus restricts the contents -of these string literals to provide more structured information that can be -mechanically interpreted by toolchains and runtimes to support idiomatic -developer workflows and source-language bindings. The rules defining this -structured name syntax below are to be interpreted as a *lexical* grammar -defining a single token and thus whitespace is not automatically inserted, all -terminals are single-quoted, and everything unquoted is a meta-character. +All import names are required to be [strongly-unique]. Separately, all export +names are also required to be [strongly-unique]. The rest of the grammar for +imports and exports defines a structured syntax for the contents of import and +export names. Syntactically, these names appear inside quoted string literals. +The grammar thus restricts the contents of these string literals to provide +more structured information that can be mechanically interpreted by toolchains +and runtimes to support idiomatic developer workflows and source-language +bindings. The rules defining this structured name syntax below are to be +interpreted as a *lexical* grammar defining a single token and thus whitespace +is not automatically inserted, all terminals are single-quoted, and everything +unquoted is a meta-character. ```ebnf exportname ::= | @@ -2191,9 +2193,12 @@ importname ::= | | plainname ::=