-
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
(Re-)Consider multi-return vs unit #41
Comments
#49 raises an interesting case where having an empty return (returning (I haven't forgotten about this issue; I just haven't had time to think and discuss more about it yet.) |
Recently I found myself trying to debug an invalid component but the way that it was invalid meant that I couldn't print it with `wasmprinter`. This commit removes all the type management in `wasmprinter` which is currently needed for the `start` function of components (and other since-removed items I believe historically) to allow printing more components, namely those that even may be invalid. In general I personally think it's best for `wasmprinter` to print as much as possible, even if it's invalid, and leave validation primarily to the parsing phase later. This commit does effectively "break" the implementation of printing modules with `start` functions, however. The `(result ..)` production is never printed any more since the type information here is not tracked. This is tracked at WebAssembly/component-model#41 for updates to the `start` function.
Here's a third argument in favor of multi-return that I recently realized: To support runtime instantiation of components (going beyond the declarative all-up-front instantiation we currently have), I've been imagining that we'd define a new canonical built-in |
So if we were to switch to multi-return, then an empty result type list would be the way to express what is today So if Lastly, if the result list is to be exactly symmetric with the param list, that implies that a result list can contain an arbitrary mix of named and unnamed values. For parameters, this seemed fine because parameter names can always be ignored, falling back to positional parameter rules. But with results, we'll often need to synthesize a source-language value (e.g., to return to a JS caller) which means defining how to interpret these mixed-name types (as opposed to all-named (
Option 1 seems simpler and more regular, but if we consider the components-as-functions use case in the preceding comment, components can't express multiple unnamed params/results because of the uniqueness constraints on import/export names. More-generally, parameter/result name uniqueness seems like it could be broadly useful and simplifying for the same reason as import/export name uniqueness. Thus, I actually lean toward option 2, which gives each param/result a unique name (with that name possibly being the empty string) while preserving the pragmatic performance goal that scalar return values are not needlessly and annoyingly object-wrapped in JS and all the other dynamic languages. So that's what I'm thinking a coherent switch to multi-return entails. What do folks think? (Sorry for the churn and flip-flopping here!) |
Recently I found myself trying to debug an invalid component but the way that it was invalid meant that I couldn't print it with `wasmprinter`. This commit removes all the type management in `wasmprinter` which is currently needed for the `start` function of components (and other since-removed items I believe historically) to allow printing more components, namely those that even may be invalid. In general I personally think it's best for `wasmprinter` to print as much as possible, even if it's invalid, and leave validation primarily to the parsing phase later. This commit does effectively "break" the implementation of printing modules with `start` functions, however. The `(result ..)` production is never printed any more since the type information here is not tracked. This is tracked at WebAssembly/component-model#41 for updates to the `start` function.
I think the above makes a lot of sense to me. I don't have any objections with the other proposed changes. Regarding option 2 from above:
Is my understanding of this, and the following paragraph you wrote, correct with the following summary?
If so, I think that option gives the most flexibility too. |
Yep! Thanks for clarifying. Thus, you can write both |
Writing this up, I realized we probably don't want to have |
Recently I found myself trying to debug an invalid component but the way that it was invalid meant that I couldn't print it with `wasmprinter`. This commit removes all the type management in `wasmprinter` which is currently needed for the `start` function of components (and other since-removed items I believe historically) to allow printing more components, namely those that even may be invalid. In general I personally think it's best for `wasmprinter` to print as much as possible, even if it's invalid, and leave validation primarily to the parsing phase later. This commit does effectively "break" the implementation of printing modules with `start` functions, however. The `(result ..)` production is never printed any more since the type information here is not tracked. This is tracked at WebAssembly/component-model#41 for updates to the `start` function.
In #29, we had an unresolved comment thread about whether we should make component-level function results symmetric with parameters. The question was independent (pre-existing) of #29, so that PR merged and this issue represents the continued discussion.
One interesting new technical argument just came up via @peterhuene's work: Component-level
start
sections calling functions that return "nothing" technically always returnunit
. If we treatedunit
uniformly (pushed a newunit
value into the value index space), then the "linearity" requirement (each value must be consumed exactly once) would mean we have to consume thatunit
... which would then produce a newunit
(ad infinitum). Thus, we have to special-caseunit
in the validation rules (so it doesn't push a value index) which is irregular and adds validation complexity. It's not a massive problem, but it does add a point to the multi-return column (which can return an empty list of values).The text was updated successfully, but these errors were encountered: