Stream: wit-bindgen

Topic: When to use imported types versus exported types?


view this post on Zulip Randy Reddig (Apr 13 2024 at 14:37):

This is a question related to implementing a Component Model bindings generator (specially wit-bindgen-go):

Let’s say you have an interface that defines a resource type “fd” and a world that both imports and exports that interface, and a second exported interface “utils” that contains functions that accept an fd argument.

Which fd type does utils actually use? Is the CM spec ambiguous or is there a heuristic? Should the choice be represented in the wit-parser Resolve struct?

view this post on Zulip Randy Reddig (Apr 13 2024 at 14:41):

For imported functions, this is easy—use the imported fd type.

view this post on Zulip Notification Bot (Apr 13 2024 at 16:37):

Randy Reddig has marked this topic as resolved.

view this post on Zulip Notification Bot (Apr 13 2024 at 16:37):

Randy Reddig has marked this topic as unresolved.

view this post on Zulip Alex Crichton (Apr 13 2024 at 16:52):

What ends up happening here is a bit subtle and it's generally related to WIT conventions. The CM itself has no ambiguity, the problem arises when WIT is mapped back to the component model. To answer your question the cases are:

view this post on Zulip Alex Crichton (Apr 13 2024 at 16:53):

there's also implicit insertion of interfaces to handle here too, for example wasm-tools component wit ./my-wit will show the "elaborated" version of a world. For example if you do export utils; that'll implicitly insert import fd;. If you have export fd; export utils;, however, then no implicit insertion happens and utils uses the exported fd.

view this post on Zulip Randy Reddig (Apr 13 2024 at 16:56):

Interesting, thanks. Is (or was) it the intention to allow WIT to express explicitly which fd to use?

view this post on Zulip Randy Reddig (Apr 13 2024 at 16:57):

Would it make sense for this logic to live in the wit-parser crate, so the Resolve structure can express whether a type is imported or exported?

view this post on Zulip Randy Reddig (Apr 13 2024 at 17:01):

Thinking about this a little more: if a component exports a type, but there is no exported constructor nor any exported functions that return that type, then is the type actually exported?

view this post on Zulip Randy Reddig (Apr 13 2024 at 17:04):

(I was down this rabbit hole thinking about structural types like record that might include an exported resource. Resolving those types would have a similar challenge, e.g. which fd to use.)

view this post on Zulip Alex Crichton (Apr 13 2024 at 17:21):

Yes the intention is to eventuall enable WIT to describe this all more explicitly as a sort of "power user" syntax, there's related discussion on https://github.com/WebAssembly/component-model/pull/308 and I think one or two other locations too.

Would it make sense for this logic to live in the wit-parser crate, so the Resolve structure can express whether a type is imported or exported?

Definitely! In retrospect this is a major design flaw of wit-parser today. The interface fd is mistakenly represented as a single interface in Resolve when in fact it should be duplicated for when it's both imported-and-exported.

if a component exports a type, but there is no exported constructor nor any exported functions that return that type, then is the type actually exported?

I think this only comes up with resources since all other types are "nominal" and can be constructed at any time. In such a situation as you describe the type isn't useful since no one can create it, but it's still an exported type and can participate in type-checking and such.

This PR proposes to change how use works inside WIT worlds, based on some initial discussion in wit-bindgen/#822. Currently, use can be used with the same syntax in both interfaces and worlds. For...

view this post on Zulip Randy Reddig (Apr 13 2024 at 17:46):

I was wondering if it would be possible to fix this discrepancy with resource types by making them duck-typed, and adding a new canon function that resolves a duck-typed resource to a locally-defined resource type.

view this post on Zulip Alex Crichton (Apr 13 2024 at 17:47):

While it might fix this particular issue, I believe that duck-typed resources would erode many guarantees you currently get with resources and perhaps create a lot of other conundrums, so I don't think it's quite so simple

view this post on Zulip Alex Crichton (Apr 13 2024 at 17:47):

I could be wrong though! That's probably best discussed in an issue

view this post on Zulip Randy Reddig (Apr 13 2024 at 17:48):

OK!

view this post on Zulip Randy Reddig (Apr 13 2024 at 17:48):

I’ve been thinking about duck-typed resources as a way to resolve the ambiguity between WIT/CM for resource types or any type that includes resource

view this post on Zulip Randy Reddig (Apr 15 2024 at 20:22):

Definitely! In retrospect this is a major design flaw of wit-parser today. The interface fd is mistakenly represented as a single interface in Resolve when in fact it should be duplicated for when it's both imported-and-exported.

Where would it make sense for the wit-parser crate to represent the imported vs exported attribute? At the type (and function) level, or at the interface level?

It seems like this could be a backwards-compatible change to wit-parser, in the sense that it would potentially duplicate interfaces/types/functions, with an additional attribute to signal whether they’re imported or exported?

view this post on Zulip Alex Crichton (Apr 15 2024 at 20:26):

I think this would be best represented at the interface level right now since that's the unit of import/export, and yeah I agree it should largely be backwards-compatible and would end up probably deleting more code downstream of wit-parser than would need to be added to wit-parser

view this post on Zulip Randy Reddig (Apr 15 2024 at 20:30):

To simplify the carrying of state, could we also add the attribute to TypeDef and Function?

view this post on Zulip Alex Crichton (Apr 15 2024 at 20:32):

I think that'd be reasonable yeah

view this post on Zulip Randy Reddig (Apr 15 2024 at 20:33):

I can file an issue on wasm-tools repo describing this. That work?

view this post on Zulip Randy Reddig (Apr 15 2024 at 20:33):

I’d implement it, but I don’t feel confident enough in my Rust chops

view this post on Zulip Alex Crichton (Apr 15 2024 at 20:35):

mind opening an issue to start off? I've been meaning to track this for awhile

view this post on Zulip Randy Reddig (Apr 15 2024 at 23:29):

https://github.com/bytecodealliance/wasm-tools/issues/1497

We propose to move logic from wit-bindgen into the wit-parser crate that determines whether an interface, type, or function in a Resolve structure is either imported or exported, and label those st...

view this post on Zulip Mossaka (Joe) (May 13 2024 at 17:38):

Circuling back to this issue:

world exports-use-from-interface {
  use a.{fd}
  export b: func(f: fd);
}

it seems strange to me taht the WIT parser resolve to import the entirety of interface a even though we only specify a.{fd}.

view this post on Zulip Alex Crichton (May 13 2024 at 17:42):

In an actual component that exports b it should only import the parts of a it actually needs, but at the WIT layer (e.g. Resolve) there's no way to represent a partial interface so the only option is to have an import for the whole interface

view this post on Zulip Mossaka (Joe) (May 13 2024 at 18:54):

Thanks, that makes sense, @Alex Crichton . I'd like to stress the proposal that adds attribute to TypeDef and Function more. Imo, adding direction to Interface is suffice to differentiate what type to use in exported functions. Is there any particular reason for adding direction to Function and Types?

view this post on Zulip Alex Crichton (May 13 2024 at 18:57):

Sorry I'm not sure I quite understand, can you clarify what you mean about direction and the "adds attribute" part?

view this post on Zulip Mossaka (Joe) (May 13 2024 at 19:18):

Alex Crichton said:

Sorry I'm not sure I quite understand, can you clarify what you mean about direction and the "adds attribute" part?

Oh sorry, yes I can clarify. I was referring to this issue where it proposes to add an attribute to the InterfaceFunction, and TypeDef structs to indicate whether it is imported or exported. I assumed the name of that attribute to be direction.

We propose to move logic from wit-bindgen into the wit-parser crate that determines whether an interface, type, or function in a Resolve structure is either imported or exported, and label those st...

view this post on Zulip Alex Crichton (May 13 2024 at 19:31):

ah ok yeah no definitely makes sense to add still!


Last updated: Dec 23 2024 at 12:05 UTC