| 07:50 | <yulia> | thanks kris, you represented it really well -- listening to the feedback section now |
| 08:17 | <yulia> | I'm curious, does the re-entrancy problem discussed, or the potential of it, also exist in dynamic import? because by the time you can trigger a lazy module that operates on an already imported module, is if you are at the ancestor module that imports both. that means that C has already evaluated, and it's state is set. B is similar to an async dynamic import, but without the async tick. Why does the re-entrancy hazard come up only in the case where there is no async tick? |
| 08:19 | <yulia> | I think I don't quite understand what the hazard is, curious to hear more |
| 08:20 | <yulia> | as for providing a low level api, yes this is also a possibility. I think there is benefit to having syntax however, because even within firefox we had 3 separate implementations and that is just in one code base. One used common js, one used our JSM loader, and one was iirc a mix of the two |
| 08:21 | <yulia> | I can also write mark directly about this, I just haven't had time |
| 13:45 | <Kris Kowal> | Reentrancy can only occur when one module’s stack runs on another module’s stack. Even with dynamic import today, there is no such possibility. |
| 13:48 | <Kris Kowal> | So the shape of a reentrancy hazard in composition with deferred (synchronous) import would necessarily involve a callback. We haven’t yet successfully formulated a case where there’s an observable behavior difference, but we’re betting that there is one. I think we’re less sure that it constitutes a hazard. |
| 13:49 | <Kris Kowal> | And we’re looking for composition hazards, not security hazards. |
| 15:57 | <guybedford> | Kris Kowal: calling a function in a cycle to a module that is not already executed sounds like the same issue to me? |
| 16:00 | <guybedford> | a.js -> b.js -> a.js something like import { bfn } from './b.js'; export function afn () {}; and import { afn } from './a.js'; export function bfn () {}; afn('called before executed') |
| 16:56 | <Kris Kowal> | Similar. With a cycle, every module necessarily participates in the cycle voluntarily. The question is whether a set of modules can be correct in isolation and break when a deferred import gets introduced. |
| 17:35 | <guybedford> | Acutally is it even the same with the cycle stuff since what one is executing is an interior function as opposed to the outer evaluation scope |
| 17:35 | <guybedford> | I can appreciate that is a difference, thanks for explaining! I think I've got it... |
| 17:35 | <guybedford> | that said, I think this is very much a fundamental tradeoff of the concept of sync deferred evaluation itself, as opposed to being a design concern |
| 17:44 | <Kris Kowal> | Do you take design concern in this case to mean a point on which multiple avenues are possible that fulfill the requirements of deferred evaluation? |
| 17:46 | <Kris Kowal> | Also, I take for granted that if there is a hazard inherent to deferred evaluation, this hazard is intrinsic to CommonJS, and nobody’s told me about a bad experience yet. |
| 17:50 | <guybedford> | right, and specifically for a synchronous framing of the problem |
| 17:53 | <Kris Kowal> | It afflicts async CommonJS too, to the extent CommonJS can be async. |
| 17:54 | <Kris Kowal> | That is to say, bundling. |
| 18:04 | <guybedford> | so you'd include async stacks as reentrant too in this scenario? |
| 18:04 | <Kris Kowal> | Definitely not. |
| 18:42 | <yulia> | So the shape of a reentrancy hazard in composition with deferred (synchronous) import would necessarily involve a callback. We haven’t yet successfully formulated a case where there’s an observable behavior difference, but we’re betting that there is one. I think we’re less sure that it constitutes a hazard. |
| 18:44 | <yulia> | i was looking at the examples, and I am wondering if you replace the deferred import acces with import(...).then(x => x.callMe()) |
| 18:44 | <yulia> | (im making dinner, will probably only respond tomorrow) |
| 18:59 | <Kris Kowal> | That’s definitely not a hazard, since the module initialization of (presumably) x.js has run to completion by the time x’s namespace is seen in a new event. For there to be a reentrance hazard, there must be a program lower on the synchronous stack that can be rendered incorrect by interleaving the initialization of another module in a stacked callframe. |
| 19:02 | <Kris Kowal> | However, as far as hypothetical interleaving hazards are concerned, const x = import('x.js', { sync: true }) would be equally worrying to deferred execution. |
| 19:03 | <Kris Kowal> | For values of worry between “eventually proven to not be worth worrying about” to “sometimes but rarely breaks working programs” |