-
Notifications
You must be signed in to change notification settings - Fork 89
Import name projections don't support exports by interface name #301
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
Comments
Interesting question! Could one solution be to say that, if you are wanting to import the, let's say, (import "unlocked-dep=<ns:foo>" (instance
(export "wasi:http/incoming-handler" (instance
(export "handle" (func ...))
))
)) Hence, we're using nested instance types and subtyping to project out just the subset of the Do you think that could work? What's kindof neat about this approach is that is supports arbitrary subsets of a component's exports while still maintaining that they came from the same instance and share resource types. |
That's the ideal solution at the component model level, but WIT cannot express that (i.e. an instance exporting an instance), which is what source bindings generation is based off of and that ultimately controls the component type one can build in the guest languages that use WIT for "componentization". If we ditched WIT to describe the resulting component type, then we could encode a more complex import. The way this is implemented currently is that every interface export of a dependency is treated as its own import of that interface, with the projection of That's solely based off of limitations in WIT. It also makes for less than ideal bindings generation, as the individual imports don't group well. |
Gotcha, makes sense. Since we haven't yet extended WIT to express locked/unlocked deps at all (mea culpa), perhaps the right fix here is to consider what the right new WIT syntax is for locked/unlocked deps and then see how this use case fits into the WIT syntax so that it can be encoded as a component-level import like I showed above. Does that sound right to you? |
I think so? I don't think developers would author WIT with dependencies in it (at least by hand; tools that know about dependencies might insert these automatically), but if the intention is to always be able to see a (conforming*) component's type described by WIT and the component has dependencies, then we'll need a way to express those dependencies in WIT. * obviously WIT supports only a subset of the component model, so the component can't express types outside of WIT representation |
Spitballing: world type-of-dep {
export wasi:http/incoming-handler;
export foo: func() -> string;
}
world my-components-type {
unlocked-dep foo:bar@{>=1.0.0 <1.1.0}: type-of-dep;
locked-dep bar:[email protected]: type-of-dep;
} Or something like that (with syntax for all the information conveyable via It would be nice if we could support this in bindings generation too, so bindings would get a |
I think you're right that WIT-with-dependencies is not something most devs would ever want or need to author. We're probably already on the same page on this, but just to be explicit to for anyone else's benefit and to see if there's any mismatch: I'm assuming devs are using some build tool with a build-config (like
Cool, that looks pretty reasonable. Using Lastly, an idea: if we ever expect devs to manually author these |
I'm confused by the distinction here. Wouldn't both That said, probably moot as I think we would just not have a type specifier at all (see next).
Agreed, we can probably just remove the type specifier entirely and reference the dependency solely by package name. The WIT parser could just treat it like any other package reference and get the type of that package (resolved via filesystem or registry), rather than spell it all out. The key differentiator with this package reference, though, is that it would be to an implementation component and not another WIT package. |
Great, agreed with the latter point. I do expect that the explicit
In the common But maybe I'm missing something about the scenario here? |
Agreed. It would import an instance that itself may export instances, which is why I used a It would be expected that said world would not express any imports because ultimately it's representing an instance type and not a component type, but purely as a workaround for the limitation of |
Ohhh, I see, thanks. I think we're missing a feature in WIT here to achieve expressive parity with the C-M which is: nested interfaces. In theory, we could just allow Does that make sense? |
Oh, and one addition to that: the reason to do via nested interfaces (vs. a |
Definitely.
So I think we may also want it translated to an import of an instance and not just an import of a component, depending on context; to me, the distinction is the intention of "I don't care how my dependency was instantiated" (instance) and "I'm the one instantiating my dependency" (component). The output of a tool that is authoring a single component (e.g. |
Yes, I think you're right, these are the two intentions that the developer wants to express. My impression is that, when you mention a type directly in an import, you should get exactly that type. Rather, it's only when you mention a component implementation that we have the question of whether you want to import its full component-type or just its exported instance-type. I was thinking maybe we say that
you're importing a component-type for both, and if you want an automatically-derived instance-type you write:
which is very explicit. Since mostly noone will write this by hand, perhaps this explicitness is good? |
Currently the projection rule for import names looks like:
This prevents projections for exports using the
interfacename
format, as these cannot be expressed simply as alabel
.Say component
foo:bar
exports an instance with namebar:baz/qux
(i.e. ininterfacename
format) and we wanted to import this instance from another component, but reference a possible implementation using anunlocked-dep
import rather an import of an interface name. We're unable to express this becausebar:baz/qux
cannot be represented as a projection.One possible solution:
Extend the
projection
rule as follows:Or using some other delimiter to denote that the segment is an interface name and not a label.
The text was updated successfully, but these errors were encountered: