Open peterhuene opened 6 months ago
In terms of parsing I think that's easy enough to fix with a bit more lookahead on the wit-parser
side of things, but another aspect to consider here is round-tripping this construct through the binary encoding of components. I think that may be possible by perhaps exporting an instance type and then using that as the type of the exported concrete instances (or something like that).
Regarding how the WIT<-->binary roundtrip could work (which I think might run into some trouble trying to use imports/exports on first consideration): one alternative (but maybe bad) idea is to add and use an implements
annotation on imports and exports, which is an idea that has come up for other reasons separately.
The original idea of implements
is that when you have an import like (import "foo" (implements "wasi:http/handler") (instance ...))
, the implements
attribute is neither part of the name (which is the plainname
foo
) nor the type (which is (instance ...)
); it's a third field that gives you a sortof "hint" about the semantic contract of foo
. Because it's not a name nor a type, the implements
annotation doesn't participate in validation (all typing rules ignore it), and also I think include
would fail if you attempt to union two worlds with the same plainname
, even if they have the same implements
(they don't get unified, whereas they would if they had the same interfacename
). Instead, implements
could be useful as a hint to developer tooling in some contexts to provide helpful suggestions (say, to fill an autocomplete list if you're writing WAC in an IDE).
So, building on this C-M idea: maybe the WIT-level meaning of this new syntactic form @peterhuene is suggesting (which I agree seems useful) is that import foo: wasi:http/handler
turns into (import "foo" (implements "wasi:http/handler") (instance ...))
. Thoughts?
That seems plausible to me yeah, the validation of the implements
tag would need to happen during WIT decoding-from-wasm but that seems tractable and isn't much more difficult than other forms of extra validation at that layer already happening.
FTR, I made the same observation. If you want WIT to scale, then there really ought to be a declaration form for naming interface types. (And as Luke is aware, I strongly believe that the off interpretation of "interface" in WIT is at odds with doing this in the natural manner. ;) )
Capturing a point made earlier by @dicej for posterity: as soon as you add this feature, you also want a complementary extension to WIT to be able to refer to the plainname
identifiers from later use
s, so that types can be shared as much as with interfacename
s.
Currently the
extern-type
rule in the WIT grammar is:This means that both the
import-item
andexport-item
rules in a world may only have named function or inlined interface items.For example:
However, it may be desirable to have a single interface definition that is imported or exported under different names in a world or to simply import or export a "known" interface with a different kebab name.
The former is currently not possible in the grammar, but it is possible with copy-and-paste:
This obviously duplicates the type information on every inline interface definition.
What I propose with this issue is to add
use-path
as a case to theextern-type
rule.This would allow for the following:
and also for:
Note: there may be ambiguity introduced by extending the
extern-type
rule in the currentwit-parser
implementation as right now it allows lexingfoo: bar
as a package name made up of three tokens (<id>
,':'
,<id>
); a hypotheticalimport foo: bar:baz/qux
in a world might be difficult for it to parse as it will likely see that as an import of a package path with nested namespaces. Thewac
parser lexes package paths as individual tokens and therefore prohibits whitespace in the path, so that would lex as<import-keyword>
,<id>
,:
,<package-path>
rather than<import-keyword>
,<package-path>
.