01:07
<Kris Kowal>
I’ve finished a deck for tomorrow, should time permit. I added this to the end of the meeting as it shows where I think we’re converging. https://drive.google.com/file/d/1_juf8l8PCrVHA4iA1G4BwQ1JsuXMjOVa/view
06:53
<Jack Works>
I’ve finished a deck for tomorrow, should time permit. I added this to the end of the meeting as it shows where I think we’re converging. https://drive.google.com/file/d/1_juf8l8PCrVHA4iA1G4BwQ1JsuXMjOVa/view
I like this. Where does the module descriptor go?
07:11
<Kris Kowal>
Module descriptors cease to be necessary. When implementing a Compartment in user code, module instances replace module descriptors. User-mode Compartments aren’t able to address modules from the host compartment by name, but import reflection replaces that role.
07:13
<Kris Kowal>
e.g., defer import fs from 'fs'; new Compartment{{ modules: { fs } }).import('fs') is a possible solution with a user-code Compartment implementation.
07:14
<Kris Kowal>
(where defer import is import reflection. I haven’t seen a syntax I like for that yet, so just riffing here.)
07:23
<Kris Kowal>
Actually, for inter-compartment linkage, we would have to implement module-descriptors in user code.
19:29
<Kris Kowal>
Are any champions going to seek advancement for module proposals at the next plenary?
19:30
<Luca Casonato>
We are planning to seek stage 2
19:32
<Kris Kowal>
I propose that I repurpose the slot I’ve reserved for compartments to deliver a module harmony report, based on where we are as of this morning. My impression is that we need more work on module harmony before we have a proposal that can advance to Stage 2.
19:33
<Kris Kowal>
In my opinion, none of our proposals should advance until we have a shared foundation, and as far as I’m concerned, that shared foundation could be bundled into any proposal seeking stage 2 or greater.
19:34
<Kris Kowal>
By the shared foundation, I mean the additions to the abstract module record hierarchy on which we all likely depend.
19:37
<guybedford>
Kris Kowal: I'm not sure we should let specification editorial details block individual proposals. As long as each proposal is semantically sound, and we are tackling the shared interaction problems, I don't think we need to converge on sharing exact spec text between proposals especially at this stage.
19:38
<Kris Kowal>
For import reflection, I think the syntax pivot is good. I can see import module and import static module. I would be okay with import static module reifying the literal WASM Module object provided that it can be passed to a new Module(wasmSource, importHook, importMeta) when first-class modules come.
19:40
<Kris Kowal>
My understanding is that stage 2 requires tentative spec text. I’m asking that any proposal that advances have tentative spec text that is sufficient for any other module proposal to build upon.
19:40
<Kris Kowal>
I could be wrong. This is my first stage advancement rodeo.
19:41
<Kris Kowal>
But I believe the guiding principle is right: we should not paint ourselves into a corner that would preclude advancement of other proposals, or produce avoidable scar tissue.
19:41
<Kris Kowal>
But I’ll qualify that: spec text scar tissue does not bother me. Reified object scar tissue does.
19:42
<guybedford>
Right, although Stage 2 is not an implementation stage
19:42
<guybedford>
Only at Stage 3 does scarring start to occur!
19:43
<guybedford>
In our current specification we defined the mechanics of the reflection, but we have left the actual reflection object being returned to be entirely defined by the host for now
19:43
<guybedford>
through a HostResolveModuleReflection hook
19:43
<guybedford>
our hope is that this is clear enough for stage 2, without being too prescriptive yet
19:43
<guybedford>
we would hope to refine for stage 3 some further invariants around the resolution and exact JS reflection object
19:44
<guybedford>
but for now we just treat it as host defined
19:44
<guybedford>
I would be interested to hear if that mitigates your concerns, the spec text PR is up at https://github.com/tc39/proposal-import-reflection/pull/21 and should be landing soon
19:44
<Kris Kowal>
I’ll give it a read.
19:45
<Kris Kowal>
The invariant I would hope to preserve would be new Module(x, …rest) would work for any x reflected by import static module ....
19:45
<Kris Kowal>
And I would cut it as fine as differentiating import module from import module static.
19:47
<Kris Kowal>
I think it is important that import module x from 'x.any' should always produce x instanceof Module whereas there’re more degrees of freedom for import static module x from 'x.any'.
19:47
<guybedford>
as mentioned in the meeting, we are only interested in the import module being the import static module case you describe
19:47
<Kris Kowal>
I’m interested in both existing.
19:47
<guybedford>
we don't have a use case for the module instance reflection
19:47
<Kris Kowal>
Deferred execution is the motivating case for module instance reflection.
19:48
<guybedford>
specifically - what would the import hook be for an implicit instance reflection?
19:48
<guybedford>
deferred execution is not a use case of reflection either, and we have mentioned before this is separate specification work
19:48
<Kris Kowal>
import instance reflection would inherit the surrounding module instance’s import hook.
19:49
<Kris Kowal>
In my current mental model, these occupy overlapping syntactic space that should be coherent when we have solutions to both problems.
19:49
<guybedford>
it sounds very much like a deferred import
19:49
<Kris Kowal>
It is.
19:49
<guybedford>
That is Yulias area not ours
19:50
<guybedford>
I think it can be achieved but it is a separate specification to what we are working on with module reflection
19:50
<guybedford>
"reflection" by its nature is about a higher order import
19:50
<guybedford>
not an instance import
19:50
<Kris Kowal>
I do not mean to suggest that your proposal should solve both motivating use cases.
19:51
<Kris Kowal>
I do suggest that we are responsible for ensuring that these merge without conflict.
19:51
<guybedford>
it is our collective responsibility to not conflict eachother yes :)
19:51
<Kris Kowal>
I suggest that in the end we should have syntax for both cases.
19:52
<guybedford>
that's fine, and nothing is precluded
19:52
<guybedford>
specifically we have further constrained import reflection to module import reflection
19:52
<guybedford>
other proposals for other types of imports like assets or deferred execution can easily coexist
19:52
<Kris Kowal>
import module x from 'x.js' meaning x instanceof WASM.Module would preclude import module x from 'x.js' alternately meaning x instanceof Module.
19:53
<guybedford>
right but it doesn't preclude import defer x from 'x.js'
19:53
<Kris Kowal>
I agree that is possible.
19:53
<Kris Kowal>
In a universe with both, are we creating another footnote in WAT.js?
19:54
<guybedford>
if there is issue with the module term not being clear enough, we can consider other options
19:54
<guybedford>
the hope was too avoid too much of a bikeshed of course
19:54
<Kris Kowal>
import module x from 'x.wasm';
x instanceof Module; // false WAT?
19:54
<guybedford>
I hope we could consider this mostly aesthetic as opposed to a primary stage 2 concern
19:55
<Kris Kowal>
I’ll grant this is aesthetic. What stage do aesthetics become a concern?
19:55
<Kris Kowal>
Soft concern for 2, hard concern for 3?
19:58
<guybedford>
From what I believe, stage 2 is expected to be complete specification but can still have open questions
19:58
<Kris Kowal>
I’ll also grant that import defer x from 'x.any' has a nice ring to it.
19:59
<guybedford>
we'll make sure to highlight these points, this has been useful
20:35
<littledan>
I think we still have a number of foundational questions to answer, for all of the proposals we're discussing. A number of unresolved points of disagreement just came up in that meeting. I'm fine with things moving to Stage 2 as long as this is to be interpreted explicitly as "we agree that we want to move forward as a committee in this area, and have one concrete idea of how it might work, but we're still open to resolving these foundational questions in multiple ways"
20:36
<nicolo-ribaudo>
From what I believe, stage 2 is expected to be complete specification but can still have open questions
Stage 3 is complete specification, for stage 2 you need a draft
20:36
<littledan>
I mean, module blocks seems to be one of these proposals which has these unresolved foundational questions, and it's already at Stage 2! But this is largely because it hadn't yet occurred to us that module blocks might be referrer-less, which Caridy is now advocating
20:37
<littledan>
I don't tend to agree with people who insist that all foundational questions be addressed by Stage 2. It's just too common for us to find that we need to revisit foundational issues during Stage 2. I think it's more that, Stage 2 indicates a level of interest/resolve to work things out, together with concreteness on some possibility
20:37
<littledan>
the bikeshed is definitely not a Stage 2 blocker
20:39
<littledan>
I think we should at least wait until Yulia is back to conclude that deferred module evaluation is separate from Guy's and Luca's proposal. I've heard multiple suggestions that these are really the same space. So if Stage 2 were to be taken to mean, "these are definitely separate"... I wouldn't be ready to say that yet.
20:41
<littledan>
Concretely, I hope we can all get more space to decide whether module blocks and reflective modules are ModuleSource or Module values. My expectation was that they were both Module, but Guy was proposing that reflective modules be ModuleSource, and Caridy was proposing that module blocks be ModuleSource
20:41
<littledan>
I think we can iterate on this question after Stage 2 but before Stage 3
20:43
<littledan>
I was disappointed that asset references fell out of what Guy and Luca are proposing initially. I'd be interested in hearing more about what's behind that decision, and how soon you'd like to follow up with asset references, since they seem quite useful.
20:52
<littledan>
guybedford: Luca Casonato I'd be happy to have a call with you some time soon to discuss all this more if you're interested
21:55
<Kris Kowal>
Same
21:56
<Kris Kowal>
And I’m putting together a review to call out at least where I think we’re headed tentatively where it doesn’t match. Emphasis on tentative.
21:56
<Kris Kowal>
If I read the room right, I should hurry up and put together some spec text for first class modules (Module and ModuleSource) and shoot for the two.
22:02
<Kris Kowal>
And I think Caridy and I both suggest module {} instanceof Module and static module {} instanceof ModuleSource. Serializing ModuleSource is uncontroversial. Serializing Module is controversial. By the end of the call, I think we had agreement that Module, if serializable, is intentionally cherry picking the serializable subset of the instance. However, Caridy, Guy, Shu, and I all have misgivings. I have made peace with my misgivings.
22:05
<Kris Kowal>
My feeling is that trusting the sender and receiver to have identical importHook behavior is possible but fragile. But, if we have blocks, static blocks, Module and ModuleSource to work with, I think that the ecosystem will have everything it needs to come up with more sensible protocols for sending modules to workers.
22:07
<Kris Kowal>
That is to say, I predict that worker.import(module {}) will look good in examples but will otherwise have limited utility. But, that’s okay with me.
22:39
<guybedford>
@littledan thanks for the feedback, we see module reflection as laying down an approach that asset reflection and deferred execution can follow in, as opposed to the original more abstract view of a generical mechanic. Trying to be practical and use case focused while treating generalization as a possibility but not to over-generalize. We are keen to see asset references and deferred module loading move forward, we are just trying to focus our efforts in a way that keeps scope clear in the staging process. We currently are underspecifying what exactly the shape of the reflection object is though, and treating this as a detail to be refined as opposed to prescribing it at this point. The way we do this for now is to entirely delegate it to a host hook, then the hope for Stage 3 would be to follow-up with an exact definition for JS that will hopefully have progressed by then. We need the host hook regardless for Wasm though.
22:39
<guybedford>
all good points, will do our best to address the various nuances!
22:39
<guybedford>
Definitely agreed feedback from Yulia is needed to progress in many of these discussions at this point
22:43
<Kris Kowal>
guybedford Am I correct that new Module(wasmModule, importHook, importMeta) where wasmModule instanceof WebAssembly.Module is a sensible way import reflection for WASM and first-class modules would compose?
22:44
<Kris Kowal>
That implies that the WASM module can both import and export.
22:44
<Kris Kowal>
Or is it only sensible to link WASM modules manually?
22:44
<guybedford>
Kris Kowal: that is definitely an option, and something to be discussed further
22:45
<guybedford>
We don't currently have a strong opinion on this
22:45
<guybedford>
definitely keen for more feedback
22:45
<Kris Kowal>
I would say that is less an option and more a requirement, in my opinion.
22:46
<Kris Kowal>
Unless web assembly modules are indeed merely resources.
22:47
<Kris Kowal>
And I think that decision pivots on whether there’s one or more sensible ways to interpret WASM as a participant in a module graph.
22:48
<Kris Kowal>
If there’s more than one way, I would lean more in the “web assembly modules are assets / resources that we want vetted for CSP, but require further programming to participate in a JS module graph” direction.
22:49
<Kris Kowal>
But if there’s one way that always works, I’d lean more toward putting them on equal footing with static module blocks and ModuleSource instances.
22:53
<guybedford>
From a loader perspective - if we used synthetic module wrappers that would involve using dynamic import to reentrantly load the dependencies. By making Wasm first-class module records they could participate in the module graph equally in the same execution algorithm as opposed to being treated as having reentrant dependencies which would otherwise deadlock for cycles
22:53
<guybedford>
Wasm doesn't strictly need cycles, but the point stands that it would involve user instrumentation for loader support using reentrant dynamic imports that could deadlock
22:54
<guybedford>
a lot of the questions are about expectations and how much work they will be to support in loaders certainly
22:54
<Kris Kowal>
That’s a lot to unpack.
22:54
<Kris Kowal>
I don’t think literal deadlock is on the table in any framing.
22:55
<Kris Kowal>
I also don’t think reentrance is on the table.
22:57
<Kris Kowal>
importHooks are recursive but non-reentrant. They would only run under dynamic import during the load phase, for growing the working set of module records.
22:58
<Kris Kowal>
I think WASM modules being inherently acyclic is handy, but I also think it’s possible to fully virtualize even ESM, including cycles.
23:01
<guybedford>
There are a bunch of complexities making them first class to delve into, perhaps we can go through the exercise some time
23:01
<Kris Kowal>
I think we agree actually that WASM modules ideally participate in module graphs on equal footing with module sources. But, if there’s no sensible default behavior, virtualized module sources are certainly option. Caridy would point out though that virtual module sources don’t serialize and probably would also lose their CSP metadata.
23:02
<guybedford>
definitely could workshop some example workflows around loader instrumentation and Wasm
23:02
<Kris Kowal>
So ideally we find a good default behavior.
23:02
<guybedford>
and work through tradeoffs
23:02
<guybedford>
ideally having Dan and Caridy present for that would help
23:02
<Kris Kowal>
That would be a good exercise.
23:04
<guybedford>
I don't get the feeling it is too pressing right now
23:05
<guybedford>
or needed before this coming meeting
23:05
<guybedford>
but if it's something on your critical path there happy to arrange anytime
23:08
<Kris Kowal>
I think that’s necessary to answer the question of whether WebAssembly.Module should be reified as a module source or a resource. I’m pretty sure we need to know the answer before stage 2 since that constitutes a big difference in what you’d be proposing.
23:11
<Kris Kowal>
That is, if import reflection is import module x from 'x.wasm', that’s only coherent if x is a module source and requires no further programming to participate in a module graph.
23:19
<Kris Kowal>

Follow-up question: Is this example coherent in your mental model:

import module x from 'x.wasm';
await import(x);
23:20
<Kris Kowal>
Oh, I know the answer already. That depends on the same exercise.
23:22
<guybedford>
yes exactly that is the question I think
23:22
<Kris Kowal>
(I don’t think the example is coherent, but if your answer is yes, that would put WASM modules on equal footing with module blocks and imply that a WebAssembly.Module is linkable without further programming.)
23:23
<guybedford>
coherency is exactly the question there
23:23
<guybedford>
if we want Wasm and JS to work the same
23:23
<guybedford>
or if there will be this difference
23:24
<Kris Kowal>
I’m sure that your motivating use case is adequately addressed just by carrying CSP into WebAssembly.Module and never incorporating it in a JS module graph.
23:26
<Kris Kowal>
I guess it would be gross but not broken if import module x from 'x.wasm' was completely different than import module y from 'y.js'.
23:27
<Kris Kowal>
But if that’s the case and a WASM module can’t participate in a JS graph, you wouldn’t need anything from 262. WASM could just as well be a module that exports a CSP vetted default WebAssembly.Module.
23:44
<guybedford>
the problem is how you obtain the WebAssembly.Module, also this is a feature Wasm modules themselves in the ESM integration want to be able to get ahold of
23:45
<guybedford>
Wasm wants to be able to import its own records
23:45
<guybedford>
that's an important aspect of the component model
23:46
<guybedford>
there are also further static benefits and static security benefits over arbitrary URL fetching
23:46
<Kris Kowal>
I’m reading https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration
23:47
<guybedford>
See also https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#ESM-integration
23:48
<Kris Kowal>
Oh, wow. This depends on as notation.
23:48
<Kris Kowal>
Oh, I’m going to assume this just isn’t synced with your most recent work.
23:49
<guybedford>
yes exactly
23:50
<Kris Kowal>
Am I right that esm-integration answers the question that WASM does have a sensible way to integrate in a JS graph?
23:51
<Kris Kowal>
I’m reviewing your draft rn, and I noticed that your primary motivating case is the cases where the default integration isn’t sufficient.
23:51
<guybedford>
yes although the esm integration is currently awaiting our progress on reflection to move forward
23:51
<Kris Kowal>
Is it dependent?
23:52
<guybedford>
in some sense the solution space is dependent in that this is what is needed ergonomically right now
23:56
<Kris Kowal>
Well, I understand your conundrum better now.
23:58
<Kris Kowal>
Let’s assume import module x from 'x.any' produces x such that x instanceof ModuleSource and import defer x from 'x.any' produces x such that x instanceof Module.
23:58
<shu>
there is an inferior solution the wasm folks can choose without our involvement at all, by making the default kind of thing returned by import 'x.wasm' a WebAssembly.Module instead of an instance
23:58
<shu>
it breaks symmetry down the road, however
23:59
<Kris Kowal>
Right, I was about to propose that strawman until I started reading esm-integration, which suggests there is a reasonable default interpretation of a WASM module as it participates in a JS graph, importing and exporting.