diff --git a/design/mvp/WORLD.md b/design/mvp/WORLD.md new file mode 100644 index 00000000..8f098745 --- /dev/null +++ b/design/mvp/WORLD.md @@ -0,0 +1,125 @@ +# WIT + `world` + +As it exists today [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) is a format for describing the interface of a singular [instance](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#instance-definitions). Toolchains like [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen) consume `*.wit` files as *imports* or *exports* to generate *guest* or *host* components implying **4** ways to consume an interface: + +| {guest,host}⋅{export, import} | export | import | +| -------- | -------- | -------- | +| **guest** | _guest export_ | _guest import_ | +| **host** | _host export_ | _host import_ | + +Furthermore, a single component may refer to 0..N interfaces in its imports and exports. + +The `world` syntax described below allows collecting *N* _imports_ and *N* _exports_ into a single definition reducing this number of perspectives to **2**: +1. As a *guest* **targeting** the `world` + + From the perspective of a guest the *imports* declared in a `world` describe the **maximum** set of imports that the component may `import`, whereas the *exports* describe the **minimum** set of imports that the component must `export`. + +2. A a *host* **supporting** the `world` + + From the perspective of a host, the *imports* declared in a `world` describe the **minimum** set of functions that must be supported by the host and supplied as imports to components running on that host, whereas the exports declared describe the **maximum** set of functions that the host may call in response to host events. + +Thus, there are inherently two opposing perspectives on each `world`: the **host** and **guest**. + +> NOTE: As a developer, assuming the *guest* or *host* perspective is inherent in whether we are embedding a WASM runtime or compiling to WASM. so a world effectively gives us 1 thing to say, and it implies all the rest, i.e. (imports and exports). +> +> Because the [Component Model](https://github.com/WebAssembly/component-model) allows one component to [instantiate]() and link other components, components can technically take either the host or guest perspective for a given `world` (although it will be far more common for components to take the guest perspective). Native host runtimes traditionally only take the host perspective, but in theory a native runtime could implement a component that is imported and instantiated by a wasm component, with the native runtime thereby taking the guest perspective. + +In the examples shown below, because *import* and *export* in the syntax go in the same direction as they are defined in a guest component, we can say that a `world` is **written** from the *guest* perspective. + + +--- + +The lexical structure of the following syntax is identical to that of [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#lexical-structure) with the following additions: + +- keywords ```world import export``` +- a new token `quoted-string` + +## `world` +A `world` declaration defines a set of imports and exports. From a component-model POV a `world` is syntax for a [componenttype](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#type-definitions), e.g.: + +``` +// wasi:http/proxy +world proxy { + import frontend: "wasi:http/handler" + export backend: "wasi:http/handler" +} +``` + +By way of metaphor, a `world` is like a function type: + * `world` imports and exports are like parameters and results + * `world` hosts are like the callers of a given function type + * `world` guests are like functions that have a given function type + * The rules for when a given guest is compatible with a given host are like traditional function subtyping + +> Given any component `.wasm`, one should be able to derive a `WIT` file containing a `world` that represents the syntax for that `.wasm`'s component type. + + +Conceretely, the structure of a `world` declaration is: + +``` +world-item ::= 'world' id '{' world-items* '}' . + +world-items ::= import-item | export-item . +``` + +### `import` + +An `import` declaration states that a component type depends on an externally provided [function](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-func), [value](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#types), instance of an interface type, or component type. + +For example, consider the following `import` declarations: + +``` +world { + // Import instance of "wasi:filesystem" interface and give it name "fs" + import fs: "wasi:filesystem" + + // Import function with functype and give it name "some-func" + import some-func: func(arg: string) -> result<_, _> + + // Import the inlined interface and give it name "foobar" + import foobar: interface { + foo: func() + bar: func() + } +} + +// ... +``` + +Concretely, the structure of an `import` declaration is: + +``` +import-item ::= 'import' id ':' import-type . +import-type ::= id | extern-type . +extern-type ::= wit-url | func-type | value-type | instance-type | component-type . + +instance-type ::= 'interface' '{' interface-items* '}' . + +component-type ::= 'world' '{' world-items* '}' . +``` + +> NOTE: `wit-url` is lexically a `quoted-string` describing a [URL](https://url.spec.whatwg.org/) resolving to a `*.wit` document. + +### `export` + +An `export` declaration states that a component type can provide a instance of a [function](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-func), [value](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#types), instance of an interface type, or component type. + +For example: + +``` +world { + // Export an instance of the "wasi:http/handler" interface. + export frontend: "wasi:http/handler" +} + +// ... +``` + +Concretely, the structure of an `export` statement is: + +``` +export-item ::= `export` id `:` export-type . +export-type ::= id | extern-type . +``` + +> NOTE: `extern-type` as specified in `import`. \ No newline at end of file