-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add @feature and @since gates to WIT #332
Changes from 1 commit
e0e2cf9
d7f4917
8c066b4
8d34a70
a6c9c98
ca34dcc
efbde41
86453cf
3ebfc04
8d75db5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -934,7 +934,46 @@ include-names-item ::= id 'as' id | |
## Item: `interface` | ||
|
||
Interfaces can be defined in a `wit` file. Interfaces have a name and a | ||
sequence of items and functions. | ||
sequence of items and functions, all of which can be gated on an `id` or a | ||
semantic version. | ||
|
||
For example, the following interface has 4 items, 3 of which are gated: | ||
```wit | ||
interface foo { | ||
a: func(); | ||
|
||
@since(version = "0.2.1") | ||
b: func(); | ||
|
||
@since(version = "0.2.2") | ||
@feature(name = "fancy-foo") | ||
c: func(); | ||
|
||
@feature(name = "fancier-foo") | ||
d: func(); | ||
} | ||
``` | ||
The `@since` gate indicates that `b` and `c` were added as part of the `0.2.1` | ||
and `0.2.2` releases, resp. Thus, when building a component targeting, e.g., | ||
`0.2.1`, `b` can be used, but `c` cannot. An important expectation set by the | ||
`@since` gate is that, once applied to an item, the item is never modified | ||
incompatibly going forward (according to general semantic versioning rules). | ||
|
||
In contrast, the lone `@feature` gate on `d` indicates that `d` is part of the | ||
`fancier-foo` feature that is still under active development and thus `d` may | ||
change type or be removed at any time. An important expectation set by the | ||
lukewagner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
`@feature` gate is that toolchains will not expose `@feature`-only-gated items | ||
by default unless explicitly opted-into by the developer. | ||
|
||
Together, these gates support a development flow in which new features start | ||
with a `@feature` gate while the details are still being hashed out. Then, once | ||
the feature is stable (and, in a WASI context, voted upon), the `@since` gate | ||
can be added. To enable a smooth transition, both gates can be present at the | ||
same time, exposing the feature by when the target version is greater-or-equal. | ||
After a suitable transition period (during which producer toolchains bump their | ||
default target versions to enable the feature by default), the `@feature` gate | ||
can then be removed. Thus, in the above example, the `fancy-foo` feature gate | ||
could be removed from `c` once `0.2.2` is the default target version. | ||
|
||
Specifically interfaces have the structure: | ||
|
||
|
@@ -943,9 +982,15 @@ Specifically interfaces have the structure: | |
```ebnf | ||
interface-item ::= 'interface' id '{' interface-items* '}' | ||
|
||
interface-items ::= typedef-item | ||
| use-item | ||
| func-item | ||
interface-items ::= gate interface-definition | ||
|
||
gate ::= since-gate? feature-gate? | ||
since-gate ::= '@since' '(' 'version' '=' '"' <valid semver> '"' ')' | ||
feature-gate ::= '@feature' '(' 'name' '=' '"' id '"' ')' | ||
|
||
interface-definition ::= typedef-item | ||
| use-item | ||
| func-item | ||
|
||
typedef-item ::= resource-item | ||
| variant-items | ||
|
@@ -970,6 +1015,7 @@ named-type-list ::= ϵ | |
named-type ::= id ':' ty | ||
``` | ||
|
||
|
||
## Item: `use` | ||
|
||
A `use` statement enables importing type or resource definitions from other | ||
|
@@ -1626,3 +1672,45 @@ standalone interface definitions (such `wasi:http/handler`) are no longer in a | |
`use`s are replaced by direct aliases to preceding type imports as determined | ||
by the WIT resolution process. | ||
|
||
Unlike most other WIT constructs, the `@feature` and `@version` gates are not | ||
represented in the component binary. Instead, these are considered "macro" | ||
constructs that take the place of maintaining two copies of a single WIT document. | ||
In particular, when encoding a collection of WIT documents into a binary, a target | ||
version and set of feature names is supplied and determines whether individual | ||
gated items are included or not. | ||
|
||
For example, the following WIT document: | ||
```wit | ||
package ns:[email protected]; | ||
|
||
interface i { | ||
f: func() | ||
|
||
@since(version = "1.1.0") | ||
g: func() | ||
} | ||
``` | ||
is encoded as the following component when the target version is `1.0.0`: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My impression is that the main intention for Given that would it perhaps make more sense to change this example to showcase the gating in that regard? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to talk through the workflow you're planning for how There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh my assumption has been that when 0.2.1 is released everyone updates on their own schedule. If guest languages update before runtimes that's ok because a runtime would see an 0.2.1 import but realize it has an 0.2.0 version and would work ok. The only bad case would be when you use something only available in 0.2.1 and run it on an 0.2.0 runtime. Given that there's no need for languages to pull in 0.2.1 WITs but pretend they're 0.2.0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there perhaps value in an intermediate state in which:
|
||
```wat | ||
(component | ||
(type (export "i") (component | ||
(export "ns:p/[email protected]" (instance | ||
(export "f" (func)) | ||
)) | ||
)) | ||
) | ||
``` | ||
If the target version was instead `1.1.0`, the same WIT document would be | ||
encoded as: | ||
```wat | ||
(component | ||
(type (export "i") (component | ||
(export "ns:p/[email protected]" (instance | ||
(export "f" (func)) | ||
(export "g" (func)) | ||
)) | ||
)) | ||
) | ||
``` | ||
Thus, `@since` and `@feature` gates are not part of the runtime semantics of | ||
components, just part of the source-level tooling for producing components. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be putting the cart before the horse a bit since we're a ways away from 1.0, but maybe it's worth discussing now anyway: what would an example of a traditional semver patch version be in the WIT context? I've spent a bit trying to think of an example, and I can't seem to think of one, except for something trivial like a comment typo fix.
I generally take a patch bump to mean "the interface is exactly the same as before, but the implementation has changed in some non-semantically-affecting way". But a WIT file is all interface, no implementation. So it seems impossible to make a patch-only change? Ex: if I have
local:[email protected]
, except for (maybe?) comments, I believe the*.wit
forlocal:[email protected]
must be identical to be valid semver.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that patch versions don't seem to immediately have a real use case for an interface-only language like WIT. Comments are indeed to main, and I think important, use case for them in this context though: just as implementation code, comments can contain bugs, and the use of patch versions allow us to fix those.