00:33 | <shaylew> | I think Variable.wrap ends up being a very different thing from delimited snapshots -- delimited snapshots operate on sections of the stack that contain (possibly) multiple variables, without the caller needing to know which variables are involved, whereas Variable.wrap is a convenience method for something you can already do without any kind of snapshots (global or delimited) as long as you know the variable(s) you want to operate on |
00:49 | <Justin Ridgewell> | Can you write example code of how delimited stacks would work? |
01:02 | <shaylew> | So, the system from the paper has "stack marks" as a different thing from "variables" because it already has the marks as part of delimited control... but in JS, without delimited continuations, I think you can just use a variable as a stack mark and get away with it. So it ends up looking something like...
with the only difference being that when you capture a partial snapshot it captures all variables inside the most recent |
01:06 | <shaylew> | You're probably going to ask "why would someone want this?" and one answer is: I went rifling through the literature for this because of Signals, which really seem like they want to capture and restore the signal-related suffix of the context when running a memoized Computed... but where it doesn't seem to be helpful (and might cause problems) for this to capture or clobber the parts of the async context that were set up completely outside of any Computed |
01:15 | <shaylew> | There are a bunch of framework features in reactivity systems that all boil down to "save this when you create a Computed and restore it when you start rerunning it later on", and -- because Computeds are memoized -- it seems like it's basically always a bug for some sort of dynamic context (be it AsyncContext or manually managed with try/finally) to pass into a computed that's rerunning. When multiple callers all call computed.get() in some order, we want to be sure that the answer we saved into the computed didn't depend on which caller was first. If you have multiple frameworks doing their own extensions, they can save/restore their own dynamic context using try/finally... but you run into problems if two frameworks have different extensions and don't know how to properly mask off each others'. Delimited snapshots nail this use case so well that I thought I'd try to float them and see if they seemed to help with any of the other ongoing AsyncContext mysteries |
01:32 | <shaylew> | (the signals framework features in question are stuff like... "ownership tree to implement hierarchical cleanup", "scoped error handlers to implement ErrorBoundary", "suspense context", "Context/Provider pattern for implicit parameters") |
22:59 | <Justin Ridgewell> | @Stephen Belanger Please message me with your email so that I can add you to the meetings! |
22:59 | <Justin Ridgewell> | You were always meant to be invited, and I thought you were 😄 |