2023-02-01 [16:14:11.0083] reading through it, it kind of seems like the conclusion of this page is roughly identical (modulo placeholder choice, perhaps) to the JS proposal? [17:42:22.0845] Huh, I assumed that the range operator| was supposed to subsume pipeline [20:17:21.0192] > "Scala is unique in that it only provides _, but that placeholder refers to a different parameter on each use. So _ > _ is a binary predicate that checks if the first parameter is greater than the second. Boost.HOF does the same with its unnamed placeholders [boost.hof.unnamed]." [20:17:26.0600] Wild! [20:19:41.0362] honestly kinda like scala's `_` [20:32:18.0467] > <@bakkot:matrix.org> honestly kinda like scala's `_` I mean, PFA would do this with `?`, though doing that with operators required other syntax. [21:15:31.0166] Notes editors: let’s remember to remove the >> and add a blank line between different speakers (and text that you want to render in different paragraphs in general). I did this for some topics but I think we can also do it on-line as well. [22:10:40.0115] scala has something like 18 meanings for `_`, it's very confusing until you've internalized all the relevant contexts [00:50:16.0351] > <@haxjs:matrix.org> At least wikipedia article also use ID as the abbr for identifier or identity ( https://en.wikipedia.org/wiki/Identifier ) What are you talking about? [00:50:43.0811] So wikipedia is probably not a good source to go for here. [01:27:58.0851] `_ ? _ : _` [03:04:01.0694] > <@ljharb:matrix.org> at any rate i feel very strongly against "Id" but "identifier" or "code" seem fine to me ljharb: Could you clarify how you feel about "ID", an acronym of "identity document"? [04:32:39.0479] This _should_ now be OK for day 1 & 2. [04:32:44.0145] > <@littledan:matrix.org> Notes editors: let’s remember to remove the >> and add a blank line between different speakers (and text that you want to render in different paragraphs in general). I did this for some topics but I think we can also do it on-line as well. * This _should_ now be OK for day 1 & 2. [04:33:56.0845] I think we should also keep the practice of starting every paragraph with the acronym, even if it's a continuation of the current speaker. To make it super clear that it is a continuation and not a missing acronym. [04:34:04.0829] * I think we should also keep the practice of starting every paragraph with the acronym, even if it's a continuation of the current speaker. To make it super clear that it is a continuation and not a missing acronym. [05:44:57.0315] > <@pipobscure:matrix.org> What are you talking about? check the page history, someone changed ID to Id yesterday. 🫥 [05:46:33.0645] > <@aclaymore:matrix.org> I think we should also keep the practice of starting every paragraph with the acronym, even if it's a continuation of the current speaker. To make it super clear that it is a continuation and not a missing acronym. Good point, we usually do that and I hadn’t made that fix [05:53:11.0497] One point to note there, the transcriptionist introduces many unnecessary or unnatural newlines This affects the grammar checking a lot, and is very tedious to clean up(and sometimes to even notice) [06:00:43.0404] yep hopefully that can get sorted at some point. I would say "surely that is an easy part of the software to change" but we all know not to assume the ease of making code changes to software :D [06:00:52.0833] * yep hopefully that can get sorted at some point. I would say "surely that is an easy part of the software to change" but we all know not to assume the ease of making code changes to software :D [06:02:12.0731] a post-meeting script that replaces newlines where the previous line has text which does not end in punctuation might cover the majority of the occurrences. [06:03:04.0018] Yes, we complained about these new lines to the transcriptionist, and I will also follow up with the company after this meeting to see if there is any possible fix. [06:05:21.0266] > <@haxjs:matrix.org> check the page history, someone changed ID to Id yesterday. 🫥 Sorry if that wasn’t clear from the tone. That was me in order to point out how unreliable Wikipedia is for topics where there is controversy. It’s ok as a lookup for common knowledge stuff, but wherever there is ongoing discussion wikipedia is useless. [06:06:53.0345] Even years of interwebs experience still let me forget that tone doesn’t always translate well. /blush [06:07:12.0923] > <@pipobscure:matrix.org> Sorry if that wasn’t clear from the tone. That was me in order to point out how unreliable Wikipedia is for topics where there is controversy. It’s ok as a lookup for common knowledge stuff, but wherever there is ongoing discussion wikipedia is useless. * Even years of interwebs experience still let me forget that tone doesn’t always translate well. /blush [06:11:38.0324] Yeah I am pretty baffled, what does vandalizing Wikipedia have to do with what we are discussing? [06:13:36.0650] > <@littledan:matrix.org> Yeah I am pretty baffled, what does vandalizing Wikipedia have to do with what we are discussing? I resent that (vandalizing?). That was an entirely valid edit. Also you do have to explain why the change is an improvement. So… But it does go to show that some sources (i.e. wikipedia) can’t really be valid precedent in this argument. [06:15:44.0148] OK, I think we all know Wikipedia can be edited… not sure what that proves [06:16:18.0107] The bigger point here is, we should be able to collectively bikeshed something and be able to draw a conclusion based on treating all delegates as equal and respecting all the points raised. This is what we are having trouble doing here. [06:21:25.0219] I think our unanimity model is getting a little frustrating here because folks feel like threats of blocks are being used in a way that makes other delegates feel like their point will be ignored (which would violate the original goal of our consensus-seeking in the first place). This equality/inclusion/process question is a bigger issue than the actual contents of the arguments (since anything will work technically). [06:51:13.0055] Luckily we could ensure that doesn't happen. Scala evolves with a very different process [06:51:21.0683] And values different things [06:52:07.0796] But as someone who wrote it in some capacity professionally for four years, the _ seems like a more natural placeholder [06:55:11.0014] Compiled languages have it so much easier in many ways... [07:00:19.0678] > <@littledan:matrix.org> I think our unanimity model is getting a little frustrating here because folks feel like threats of blocks are being used in a way that makes other delegates feel like their point will be ignored (which would violate the original goal of our consensus-seeking in the first place). This equality/inclusion/process question is a bigger issue than the actual contents of the arguments (since anything will work technically). I would support the change to a consensus model that doesn't require 100% agreement. I don't like that one veto stops something. [07:01:28.0344] I think all other TC's use a true consensus model. [07:10:41.0802] It feels like there needs to be a very clear model of what kind of dissent and by how many parties constitutes a breakage of consensus. [07:14:26.0633] re: async contexts, I am assuming that the behavior is, whenever a function is scheduled to be run on a subsequent microtask tick or turn of the event loop, the host is required to snapshot the current async context bits and then restore them before running the function? [07:14:42.0457] If not one, how many? To be honest, I feel the problem is not 100% or 80%. [07:14:43.0402] i.e. this isn't just for literal `async` but also for stuff like `addEventListener`? [07:14:48.0451] * i.e. this isn't just for literal `async` but also for stuff like `addEventListener`? [07:14:57.0812] > <@msaboff:matrix.org> I would support the change to a consensus model that doesn't require 100% agreement. I don't like that one veto stops something. I agree. The failure mode we have is very unfortunate, and this case highlights it. I think this indicates a need for us to reconsider our process. [07:15:08.0650] though event listeners are kind of an odd case, because they run _sync_ if you dispatch an event manually, so I'm not totally clear what's supposed to happen there... [07:15:19.0066] > <@bakkot:matrix.org> re: async contexts, I am assuming that the behavior is, whenever a function is scheduled to be run on a subsequent microtask tick or turn of the event loop, the host is required to snapshot the current async context bits and then restore them before running the function? yes, there will be a responsibility for the host environment to make sure the event-scheduling APIs it introduces (like `setTimeout`) use something similar to `AsyncContext.wrap` for their callbacks [07:15:23.0864] bakkot: that's been my understanding as well [07:15:38.0642] i'm kind of confused by justin's example saying the propagation point is at the await pause [07:15:43.0902] there is a decent list of proposals that were blocked by a lone objector, including some of the folks discussing changing the process here, fwiw. would we revist all of those if there were a process change? [07:15:49.0057] it can't work if it's _just_ promise reactions [07:16:04.0382] right, but those are the hardest to polyfill [07:16:38.0221] > <@shuyuguo:matrix.org> i'm kind of confused by justin's example saying the propagation point is at the await pause the await pause is the point where you are scheduling a thing to be run on a subsequent tick, so that seems consistent? [07:16:55.0580] bakkot: that's the second one, i thought there was a handler scheduled earlier [07:16:59.0731] i might be mixing slides? [07:17:22.0709] anyway my point is just the host hooks i added for incumbent are only for JS callbacks [07:17:31.0650] this needs host event loop hook-ins as well [07:17:49.0103] * there is a decent list of proposals that were blocked by a lone objector, including some of the folks discussing changing the process here, fwiw. would we revist all of those if there were a process change? [07:17:50.0239] * anyway my point is just the host hooks i added for incumbent are only for JS callbacks [07:18:17.0761] indeed, as this slide is saying [07:19:02.0060] I will ask the question about event listener dispatch I guess [07:19:20.0285] are folks here aware of the V8 methods `v8::Context::{Get,Set}ContinuationPreservedEmbedderData`? [07:19:40.0756] that's not quite enough [07:19:52.0807] we have that, yes, but you need more muxing [07:19:53.0084] I know, but I'm trying to gauge context [07:20:00.0726] > <@bakkot:matrix.org> I will ask the question about event listener dispatch I guess good to ask. Though presumably all APIs could be wrapped in userland anyway. So technically nothing also stopping hosts doing that? [07:21:09.0059] Ashley Claymore: the event listener question is less "how is this implemented" and more "what is the thing you want here" - I'm trying to get at the mental model, not the implementation [07:21:38.0824] I disagree with Justin's example: i think web platform built-ins should do the `wrap` for you. It's more like if you have JS code which queues callbacks, that you want `wrap`. [07:22:07.0935] that becomes a lot easier if/once `AsyncWrap` is standardized [07:22:15.0978] > <@bakkot:matrix.org> Ashley Claymore: the event listener question is less "how is this implemented" and more "what is the thing you want here" - I'm trying to get at the mental model, not the implementation https://github.com/legendecas/proposal-async-context/issues/19 many events are emitted by runtimes asynchronously [07:22:43.0641] > <@benjamn:matrix.org> that becomes a lot easier if/once `AsyncWrap` is standardized Yes, obviously the platform can't do anything if we don't add AsyncContext :) I was just nit-picking [07:22:53.0651] Chengzhong Wu: right, and others are emitted synchronously (e.g. by a manual `dispatchEvent`) [07:24:00.0526] so: if you register an event listener while within an async context, and then an event is dispatched async by the browser, presumably you want the listener to see the original context. but what if the event is dispatched sync, by `dispatchEvent`? sync dispatch is basically just a weird sort of function call, so it seems like it's the _current_ context, not the original one? [07:24:10.0550] not clear to me which context you want there [07:25:09.0901] Unfortunately the answer might depend on the event [07:25:10.0726] sync function calls should just inherit the current context, leading to the same behavior? (pls clarify) [07:25:20.0235] * sync function calls should just inherit the current context, leading to the same behavior? (pls clarify) [07:25:25.0656] and there may be up to three answers for different task types [07:25:40.0593] this would be part of the DOM/HTML/Node.js integration with AsyncContext [07:25:42.0959] Yeah, that's the point of an alternative option `captureAsyncContext` of `addEventListener` [07:25:47.0195] > <@benjamn:matrix.org> sync function calls should just inherit the current context, leading to the same behavior? (pls clarify) sorry: the same behavior as what? [07:26:11.0798] > <@legendecas:matrix.org> Yeah, that's the point of an alternative option `captureAsyncContext` of `addEventListener` well, there are separate questions about whether we want to give programmatic control, and what the default should be for each event. [07:26:14.0579] the event should be dispatched with the context you bound/wrapped, whether that happens synchronously or async [07:26:40.0499] > <@benjamn:matrix.org> the event should be dispatched with the context you bound/wrapped, whether that happens synchronously or async this is definitely sometimes not true. It is really not the right answer for the unhandled rejection event, for example (we are discussing this in an issue) [07:26:54.0325] I think we have to look event by event to figure this out [07:27:01.0009] sorry I think we must be talking past each other or about slightly different things [07:27:05.0231] > <@benjamn:matrix.org> the event should be dispatched with the context you bound/wrapped, whether that happens synchronously or async I guess I don't know what those words mean [07:30:53.0095] calling a wrapped synchronous function would also let you change a context synchronously [07:30:58.0936] OK I think I understand now [07:35:16.0497] the fact that not all callbacks will necessarily automatically inherit the context in which the callback was added (depending on the API which adds the callback) is a little bit awkward, since the whole point of this is that you want to define a context which is available when your callback runs _even though your callback is getting registered to run by code you don't control_ [07:35:18.0689] is there any precedent for an API like this? [07:35:31.0823] it's a stage 2 concern, but I'm very skeptical that this is the right representation [07:35:47.0102] * it's a stage 2 concern, but I'm very skeptical that this is the right representation [07:36:28.0076] * the fact that not all callbacks will necessarily automatically inherit the context in which the callback was added is a little bit awkward, since the whole point of this is that you want to define a context which is available when your callback runs _even though your callback is getting scheduled by code you don't control_ [07:37:03.0182] * the fact that not all callbacks will necessarily automatically inherit the context in which the callback was added (depending on the API which adds the callback) is a little bit awkward, since the whole point of this is that you want to define a context which is available when your callback runs _even though your callback is getting registered to run by code you don't control_ [07:38:42.0336] https://github.com/legendecas/proposal-async-context#prior-arts [07:39:05.0436] These are javascript precedents. C# also implements similar APIs [07:39:20.0894] Reactivity libraries with dependency tracking like SolidJS also have similar though more domain specific APIs [07:39:46.0443] https://learn.microsoft.com/en-us/dotnet/api/system.threading.asynclocal-1?view=net-7.0 [07:41:53.0843] here's the link from Mark from the jitsi chat: https://github.com/endojs/endo/blob/markm-fluid-scopes/packages/eventual-send/src/async-contexts/6-async-context-transpose.js [07:42:32.0541] thanks for the links, Chengzhong Wu and Ashley Claymore [07:42:36.0538] > <@bakkot:matrix.org> the fact that not all callbacks will necessarily automatically inherit the context in which the callback was added (depending on the API which adds the callback) is a little bit awkward, since the whole point of this is that you want to define a context which is available when your callback runs _even though your callback is getting registered to run by code you don't control_ thinking about this more, I guess the fix is, if you are passing a context to someone else you manually `.wrap` the function first [07:42:36.0782] I have no idea how a JS engine would implement that super fancy context splitting that Shu was alluding to [07:42:49.0966] this is a bit distinct from weak maps/references [07:43:08.0420] always impressed by all JS engines' optimization ideas [07:44:32.0185] Someone might be able to get a published paper out of optimizing this :D [07:45:23.0634] "This one weird trick to get zero overhead async contexts" [07:46:24.0578] v8 has zero overhead async contexts [07:46:27.0742] thinking about this even more, I am tempted to say that automatic wrapping happens _only_ when you can't do it yourself, i.e. only for syntactic `yield` and `await` (and friends, like `using await`, of course) - in every other case (including manual calls to `.then`) you can just wrap the continuation yourself, and not have to worry about whether the scheduler you're using happens to do wrapping for you [07:46:30.0137] the trick is that sometimes you can't get the stack! [07:46:49.0486] > <@bakkot:matrix.org> thinking about this more, I guess the fix is, if you are passing a context to someone else you manually `.wrap` the function first * thinking about this even more, I am tempted to say that automatic wrapping happens _only_ when you can't do it yourself, i.e. only for syntactic `yield` and `await` - in every other case (including manual calls to `.then`) you can just wrap the continuation yourself, and not have to worry about whether the scheduler you're using happens to do wrapping for you [07:47:30.0249] * thinking about this even more, I am tempted to say that automatic wrapping happens _only_ when you can't do it yourself, i.e. only for syntactic `yield` and `await` (and friends, like `using await`, of course) - in every other case (including manual calls to `.then`) you can just wrap the continuation yourself, and not have to worry about whether the scheduler you're using happens to do wrapping for you [07:47:41.0502] https://github.com/wintercg/proposal-common-minimum-api/blob/main/asynclocalstorage.md [07:48:36.0527] > <@bakkot:matrix.org> thinking about this even more, I am tempted to say that automatic wrapping happens _only_ when you can't do it yourself, i.e. only for syntactic `yield` and `await` (and friends, like `using await`, of course) - in every other case (including manual calls to `.then`) you can just wrap the continuation yourself, and not have to worry about whether the scheduler you're using happens to do wrapping for you I mostly agree, with the exception of `.then`. The biggest problem with context passing and Promises is that you would need to potentially wrap _every_ `.then` callback in the event one of them throws. This is far more arduous than wrapping the single entrypoint of an event handler. [07:48:57.0168] If it works with `await`, it should work with `.then` on native `Promise` implementations. [07:49:29.0337] > <@rbuckton:matrix.org> I mostly agree, with the exception of `.then`. The biggest problem with context passing and Promises is that you would need to potentially wrap _every_ `.then` callback in the event one of them throws. This is far more arduous than wrapping the single entrypoint of an event handler. only if you have a bunch of `.then` calls, which isn't so common, and even then if you factor out a helper to do the wrapping it seems not so arduous? [07:49:42.0240] but I am maybe open to it; something to talk about more [07:50:11.0115] I disagree. If you are still using `.then` today when async/await exists, you are likely doing something far more complex than a single `.then` continuation. [07:50:32.0286] tons of people do that with fetch - `await fetch(…).then(x => x.json())` [07:50:37.0222] it's pretty common [07:50:37.0482] > <@bakkot:matrix.org> only if you have a bunch of `.then` calls, which isn't so common, and even then if you factor out a helper to do the wrapping it seems not so arduous? * I disagree. If you are still using `.then` today when async/await exists, you are likely doing something far more complex than a single `.then` continuation. [07:51:01.0679] I am OK with the people doing the `fetch` thing having to refactor their code or do a manual wrap [07:51:08.0065] but yes sometimes things get more complicated [07:52:29.0183] i haven't been following, but it seems pretty important to preserve the sugar-ness of await over promises. [07:52:35.0577] my main concern with automatically wrapping in `.then` is, the rule "you have to wrap any callback, whereas syntactic continuations get wrapped for you" is much easier to learn than "Promise.then automatically wraps, but [some other subset of schedulers] does not" [07:53:05.0097] > <@ljharb:matrix.org> i haven't been following, but it seems pretty important to preserve the sugar-ness of await over promises. it's still preserved either way, the sugar just gets a little more complicated [07:53:10.0890] in the `.json` case, it will probably be fine that it doesn't keep the context, unless `.json` has been patched [07:53:19.0802] oohh I think I like that WinterCG proposed API better [07:53:33.0066] that's fine as long as the non-await usage isn't made more complicated - altho i guess it might be in order to use the new functionality without the sugar, as is the case with `class` [07:53:45.0857] Can someone link to the YouTube playlist? [07:53:48.0831] for the minutes [07:54:00.0310] * that's fine as long as the non-await usage isn't made more complicated - altho i guess it might be in order to use the new functionality without the sugar, as is the case with `class` [07:54:10.0109] It will also be difficult to explain why `await x; doSomethingWithContext()` would work, but `x.then(() => doSomethingWithContext())` wouldn't. Especially when many editors have refactorings for that, which now become potentially unsafe operations. [07:55:11.0405] > <@rbuckton:matrix.org> It will also be difficult to explain why `await x; doSomethingWithContext()` would work, but `x.then(() => doSomethingWithContext())` wouldn't. Especially when many editors have refactorings for that, which now become potentially unsafe operations. that seems pretty straightforward to explain, for people using async contexts? "if you pass a callback, you need to wrap it" is not a hard rule to learn [07:55:31.0221] and if you're _not_ using an async context in your own function body you don't need to learn anything [07:55:50.0239] > <@littledan:matrix.org> Can someone link to the YouTube playlist? done [07:56:19.0742] I appreciate the investigation into performance from v8 and the security review from SES. From our side, we see use cases for this but need to do a more thorough review. No outstanding concerns from us right now [07:56:26.0008] what is mark talking about? [07:56:33.0725] * I appreciate the investigation into performance from v8 and the security review from SES. From our side, we see use cases for this but need to do a more thorough review. No outstanding concerns from us right now [07:56:36.0841] is this the AsyncContext spec draft or 262? [07:58:06.0185] the other side of this, it will be difficult to explain why `x.then(doSomethingWithContext)` would work, but `setTimeout(doSomethingWithContext)` would not. so that implies `setTimeout` needs to automatically wrap as well. and then now you have the same problem but with `s/setTimeout/setEventListener/`, and so on [07:58:21.0707] This becomes one more thing to consider when wrapping code in an `AsyncContext`, especially if that code calls into a third-party package that might use `.then`. [07:58:22.0120] > <@rbuckton:matrix.org> It will also be difficult to explain why `await x; doSomethingWithContext()` would work, but `x.then(() => doSomethingWithContext())` wouldn't. Especially when many editors have refactorings for that, which now become potentially unsafe operations. * the other side of this, it will be difficult to explain why `x.then(doSomethingWithContext)` would work, but `setTimeout(doSomethingWithContext)` would not. so that implies `setTimeout` needs to automatically wrap as well. and then now you have the same problem but with `s/setTimeout/setEventListener/`, and so on [07:58:50.0229] since this is only stage 1, can we word the proposal (in its repo and the proposals list) in terms that don't lock us into any API decisions? something like "hooks for associating state with async call stack frames"? [07:59:16.0195] > <@bakkot:matrix.org> the other side of this, it will be difficult to explain why `x.then(doSomethingWithContext)` would work, but `setTimeout(doSomethingWithContext)` would not. so that implies `setTimeout` needs to automatically wrap as well. and then now you have the same problem but with `s/setTimeout/setEventListener/`, and so on IIRC, `setTimeout`, `setImmediate`, `process.nextTick` were discussed in the slides as other potential places to automatically flow state. [07:59:40.0924] > <@rbuckton:matrix.org> This becomes one more thing to consider when wrapping code in an `AsyncContext`, especially if that code calls into a third-party package that might use `.then`. does it? if you pass a callback to the library you need to wrap it. but you need to _anyway_ because the third-party package might schedule the callback to get called in some way _other than_ `.then`, like event listener dispatch or something. [07:59:46.0277] Justin Ridgewell: ^ [08:00:10.0589] i.e., if you're passing a callback to another library, you need to wrap it anyway, because you can't trust that the library is going to do the scheduling using one of the automatically-wrapping APIs (or even schedule it at all - some libraries do deliberately invoke zalgo) [08:00:20.0942] so making the rule "you always need to wrap callbacks" is much simpler [08:00:43.0698] * i.e., if you're passing a callback to another library, you need to wrap it anyway, because you can't trust that the library is going to do the scheduling using one of the automatically-wrapping APIs (or even schedule it at all - some libraries do deliberately invoke zalgo) [08:02:09.0733] > <@bakkot:matrix.org> so making the rule "you always need to wrap callbacks" is much simpler I don't agree its simpler. Simpler is not having to wrap callbacks for things that are, categorically, async continuations. [08:02:58.0864] if you are passing a callback to another library, you don't know that it's categorically an async continuation. [08:03:14.0706] it's just a callback. whether it's an async continuation depends on how _that library_ consumes the callback. [08:03:47.0392] so if you want to preserve the async context, you need to mark it as an async continuation, by wrapping it [08:03:52.0125] Simpler is knowing that `asyncIterable[Symbol.asyncIterator]().map(element => { /*has outer context*/ })` will work, but since there's no explicit `await`, how would I know? [08:06:01.0357] Regardless of whether `.then` automatically wraps, I could write a `Symbol.asyncIterator` implementation that does not in fact wrap the callback using the top-of-stack callback; that's up to the implementation of `Symbol.asyncIterator`. [08:06:06.0294] I also think not supporting this in `.then` would make it far less useful to quite a few of the use cases this is intended to support. [08:06:41.0481] I'm pointing at the async iterator helpers proposal's built-in capabilities here. [08:07:34.0508] Right, but my point is that the async iterable is something someone hands you, and you can't trust that it's only going to use the scheduling APIs you expect it to on the way to its ultimate call to `Promise.prototype.then`. [08:08:26.0594] And the whole point of this API is that you shouldn't have to coordinate with other people's code about how they choose to schedule your callback. If you could coordinate, you could just have the other code thread the state through. [08:08:38.0418] * And the whole point of this API is that you shouldn't have to coordinate with other people's code about how they choose to schedule your callback. If you could coordinate, you could just have the other code thread the state through. [08:09:29.0972] There was some fascinating investigation into a sort of "borrowing" model for ArrayBuffers in https://gist.github.com/domenic/a9343fa787ba54b4ba3a60882c49cc32#file-readme-md [08:09:42.0720] Which is why I think we should not encourage you to write patterns which rely on other people's code using particular APIs to do scheduling. [08:10:08.0236] i.e., we should not make some APIs do wrapping of callbacks automatically. [08:10:39.0628] This is a different primitive; it couldn't be implemented in `transfer`. It'd be better IMO. Anyway, done is better than perfect, we already had Stage 3 on this current thread [08:10:55.0337] > <@bakkot:matrix.org> i.e., we should not make some APIs do wrapping of callbacks automatically. huh, have you considered arguing this to the Node.js APM ecosystem? [08:11:25.0482] littledan: nope [08:11:43.0624] well... I think the implicit wrapping is just a sort of requirement to make any of this work in practice. [08:11:51.0182] It's still stated as possible solution in the readme. [08:12:03.0721] implicit wrapping of syntactic `await`/`yield` continuations, absolutely [08:12:18.0031] implicit wrapping of explicit callbacks, I don't see it. you can wrap those yourself. [08:13:31.0103] I think it'd be worth looking at existing use cases to see whether your suggestion would be viable... [08:13:37.0094] indeed you _have to_ wrap those yourself if the callback is going to thread through someone else's code, because you can't trust that they're going to do the scheduling using one of those automatically wrapping APIs [08:13:45.0320] I mean, cases, where this is already deployed [08:14:00.0920] `yield` is something we'll need to discuss: https://github.com/legendecas/proposal-async-context/issues/18 [08:14:24.0784] For `await` and `Promise.p.then`, I think we have to do them automatically [08:14:36.0192] `await` should just be a sytnax on top of promises [08:14:56.0745] (And also if you force me to take away the fast path for `await promise` because I have to patch `.then`, I will riot) [08:14:57.0310] I think bakkot's arguments would need to be made to host environments, since we just don't own much of what would need to make these decisions [08:15:13.0085] > <@jridgewell:matrix.org> (And also if you force me to take away the fast path for `await promise` because I have to patch `.then`, I will riot) My point is that you don't have to patch `.then` [08:15:21.0158] As the platform, I do [08:15:25.0356] ... why? [08:15:35.0399] Assuming there's implicit wrapping in syntactic `await`s [08:15:41.0328] The whole `console.log` use case in the slides [08:15:53.0521] > <@bakkot:matrix.org> Assuming there's implicit wrapping in syntactic `await`s sure, I agree, in theory we could fork the semantics here [08:15:57.0209] I have to preserve across any promise usage, because anything else will break an important API for us [08:16:00.0200] what I don't understand is the motivation [08:16:11.0191] > <@jridgewell:matrix.org> I have to preserve across any promise usage, because anything else will break an important API for us I think bakkot is saying, you could go patch that [08:16:21.0772] > <@jridgewell:matrix.org> I have to preserve across any promise usage, because anything else will break an important API for us Can you give an example? [08:16:22.0701] I think he's saying I don't [08:16:50.0539] by "you" I mean, either the program or the Vercel environment [08:17:02.0163] Vercel's platform [08:17:05.0003] https://docs.google.com/presentation/d/1yw4d0ca6v2Z2Vmrnac9E9XJFlC872LDQ4GFR17QdRzk/edit#slide=id.g18e6eaa50e1_0_164 [08:17:16.0275] I have to preserve this start time across any user code per request [08:17:24.0840] Let's slow down; I think you're talking past each other [08:17:34.0497] It doesn't matter if they use `setTimeout`, `p.then()`, or `await`, it's all got to work [08:18:15.0123] Justin Ridgewell: right, and that would still work? [08:18:16.0522] I am confused [08:18:35.0447] You need to wrap your handlers before you hand them to other people [08:18:47.0504] How? If I force my users to wrap their `p.then()` callbacks, then it's not seamlessly working [08:18:49.0410] and as long as you do that, the handlers run in your context, regardless of how other people are scheduling them to run [08:19:01.0501] * and as long as you do that, the handlers run in your context, regardless of how other people are scheduling them to run [08:19:18.0570] `console.log` isn't a callback I pass around, it exists in the global scope [08:19:57.0983] I can't wrap it per requests, because the global value will change per request [08:20:16.0708] They don't store an access to the current value, they just access the property on the shared `console` object [08:20:18.0187] > <@bakkot:matrix.org> You need to wrap your handlers before you hand them to other people If you automatically associate context for .then, you are saving users a significant amount of complexity and boilerplate. If you are calling into questionable code, the presence of automatic context copying doesn't prevent you from manually wrapping the callback yourself. [08:21:03.0761] * I can't wrap it per requests, because the global value would change per request [08:21:12.0565] Justin Ridgewell: oh, sorry, I missed that it is crucial to this example that you are patching global state and expecting that to be respected. I am not convinced that's something worth designing for. [08:21:54.0539] > <@rbuckton:matrix.org> If you automatically associate context for .then, you are saving users a significant amount of complexity and boilerplate. If you are calling into questionable code, the presence of automatic context copying doesn't prevent you from manually wrapping the callback yourself. "calling into questionable code" meaning calling into... any code? [08:22:55.0236] if you aren't calling into other people's code, you don't need async contexts at all. and if you are, you need to wrap. I don't see how any work is saved here. [08:23:40.0487] Other use cases are distributed trace, where request handlers are, eventually, resolved by combing other requests. That's not 'global state' like `console.log`, but still a global singleton to make a request [08:24:12.0911] > I am not convinced that's something worth designing for. This would be a significant change from the way Node works, and would be a huge burden [08:24:22.0409] And it's also going to force me out of my promise fast path [08:24:36.0257] My two proposals won't play nice with each other [08:24:41.0909] > <@jridgewell:matrix.org> I can't wrap it per requests, because the global value would change per request hm, also, I'm confused about this example. assuming that `addEventListener` doesn't automatically wrap callbacks passed to it, how does this work if the dev code, instead of using `await`, had added an event listener which would do the `console.log` at some later time? [08:24:56.0354] I think `transferAndFixLength is better than `transferToFixedLength` [08:24:58.0795] I think it has to work for promises [08:25:08.0934] * I think `transferAndFixLength` is better than `transferToFixedLength` [08:25:33.0523] > <@michaelficarra:matrix.org> I think `transferAndFixLength` is better than `transferToFixedLength` "fix" as a verb there is pretty overloaded [08:25:38.0143] > <@bakkot:matrix.org> "calling into questionable code" meaning calling into... any code? I don't believe people should or do compose code in a perfectly defensive way all the time [08:25:57.0670] Devs cannot escape our context on our platform, so any future point in which they would trigger an event listener would already have restored the request context [08:26:08.0102] the same overload as `Fixed`, no? [08:26:13.0068] littledan: while true, I also believe that a refactoring from scheduling with promises to scheduling with some other mechanism should be transparent to consumers of your code. [08:26:25.0086] yeah, Bloomberg's use case also has requirements that we strictly not allow "escape". [08:26:28.0963] that is, we should not design the language such that such a refactoring is by-default not transparent. [08:26:50.0157] In APMs OTOH, they would simply not work if everyone had to update all of their code... they are just based around implicit wrapping [08:27:03.0792] like, this was proven out historically, leading to its development [08:27:39.0924] APMs have used decorators in the past to get around that though [08:28:07.0995] shu: please try to give a little more time between a name change and a stage 3 advancement next time; we may have been able to come up with a better name if we had more time [08:28:08.0511] well, although that'd still need changes [08:28:09.0495] > <@jridgewell:matrix.org> Devs cannot escape our context on our platform, so any future point in which they would trigger an event listener would already have restored the request context If you hand your callback to someone else, and there is literally no way they could schedule the callback to run with a different context than the one which existed when you handed the callback to them, I am also fine with that [08:28:36.0456] > <@michaelficarra:matrix.org> shu: please try to give a little more time between a name change and a stage 3 advancement next time; we may have been able to come up with a better name if we had more time Why didn't you put yourself on the queue? [08:28:40.0214] but that does lock us into, _every_ way of scheduling a task in the host must automatically wrap the callback passed to that context [08:28:40.0881] Michael Ficarra: technically there wasn't a name change [08:28:46.0499] littledan: because it didn't matter enough [08:28:52.0656] eventListener, unhandled promise handler, everything [08:29:12.0449] you can AsyncContext.wrap the callback in such case [08:29:21.0779] Chengzhong Wu: well, that's my argument [08:29:23.0989] > <@bakkot:matrix.org> If you hand your callback to someone else, and there is literally no way they could schedule the callback to run with a different context than the one which existed when you handed the callback to them, I am also fine with that * you can AsyncContext.wrap the callback in such case [08:29:39.0749] if some ways of scheduling require you to wrap, they all should [08:29:49.0050] but if no ways of scheduling require you to wrap, that's fine too [08:30:02.0850] Promises are a way for our users to later schedule a task, we do not control where they create promises or where the chain `.then()` [08:30:03.0468] Michael Ficarra: `transfer` was always named transfer, but because of the "preserve resizability" semantics change, to get the original "fixed length" behavior, i added a new method [08:30:04.0611] I am just not enthusiastic about _some_ callback-taking scheduling APIs wrapping [08:30:08.0149] But the default behavior can be that people can get the host defined context when using host apis. [08:30:14.0460] * But the default behavior can be that people can get the host defined context when using host apis. [08:30:18.0531] this meeting is the first meeting i presented the new method [08:30:28.0356] So in order for us to guarantee they cannot escape our context, the `promise.then()` must preserve context [08:30:30.0757] littledan: I don't think we need to introduce a formal process around it. If I think the name was *bad* I would have blocked advancement. [08:30:36.0032] > <@michaelficarra:matrix.org> littledan: because it didn't matter enough OK, in this case, I don't see your advice for waiting more for Stage 3 as something actionable for me if I ran into a simlar case [08:30:44.0245] Things that obviously schedule an async task should preserve async context [08:30:44.0379] shu: true, but I had reviewed the proposal with the earlier name [08:31:04.0075] > <@jridgewell:matrix.org> So in order for us to guarantee they cannot escape our context, the `promise.then()` must preserve context yes, and also every other possible way of scheduling a callback [08:31:04.0256] Michael Ficarra: yeah also fair, it was kind of last minute there [08:31:05.0693] which I am fine with, if it's viable [08:31:07.0079] Michael, this is exactly what we introduced the "note dissent that's non-blocking" part for [08:31:07.0928] Note: Summary needs writing for previous item [08:31:24.0780] > <@bakkot:matrix.org> yes, and also every other possible way of scheduling a callback I agree, that's the behavior that I want [08:31:25.0080] > <@littledan:matrix.org> Michael, this is exactly what we introduced the "note dissent that's non-blocking" part for so I'm wondering what's not going to work about that [08:31:47.0345] Key word is _scheduling_ here [08:31:59.0831] "addEventListener" counts as scheduling, of course [08:32:01.0909] and `onMessage` [08:32:04.0894] It doesn't [08:32:17.0777] There's not obvious point where the callback would be invoked [08:32:17.0965] ok then I don't understand what you're saying [08:32:53.0530] I can make a thing which looks exactly like a promise but which uses `addEventListener` to schedule the callback to run [08:32:54.0646] > <@littledan:matrix.org> so I'm wondering what's not going to work about that To me, the value of advancing today outweighed the value of potentially coming up with a slightly better name. If it had not, I would have spoken up formally. [08:32:57.0487] `await` schedules a task to happen as soon as the promise settles (same for `.then()`), `setTimeout` schedules to run after X ms, etc [08:32:59.0909] there is no fundamental difference btween these things [08:33:19.0005] There is [08:33:35.0425] It exists only in imperative user code, not as part of the language [08:33:50.0312] What is "it" in that sentence? [08:34:10.0558] Whatever calls your registered listener [08:34:59.0607] "this callback gets called when the user clicks a button" is exactly the same kind of thing as "this callback gets called when the network request completes [and therefore settles the `fetch` promise]" [08:35:38.0118] like, `XMLHttpRequest`'s `onload` is not a different kind of thing from `fetch`'s `.then` [08:35:49.0568] That invocation isn't done automatically per the scheduling [08:36:11.0593] Node has a long history of how this works, and I'm really hesitant to break with their precedent [08:36:40.0398] If there is a meaningful difference between `XMLHttpRequest`'s `onload` and `fetch`'s `.then`, I am not yet seeing it [08:37:14.0835] and in the absence of such a difference, I do not think those should behave differently wrt AsyncContext [08:37:40.0785] I am OK with both "both of those APIs wrap" and "neither API wraps", but not only one of them doing so [08:38:28.0939] The difference is the promise instance? [08:38:33.0594] I could see the point that `setImmediate`, `setTimeout`, `setInterval`, and even `process.nextTick` not automatically flow context, but `AsyncContext` is an async control-flow capability. `await` and `then` are explicitly async control-flow operations. The Timers API's aren't _precisely_ async control flow, though async control flow has been implemented on top of them in the past. [08:38:36.0009] The fact that it exists in ecma262 [08:39:29.0110] The internal event listener that fetch uses doesn't need extra work, because the promise it returns is responsible for scheduling continuations [08:39:29.0823] Why are promise instances relevant? [08:39:30.0420] I'm fairly certain `AsyncContext` must _at least_ support both `await` and `.then` to be truly viable. [08:40:14.0111] Why is "it exists in ecma262" relevant, or even something you could reasonably ask a developer to know? [08:40:16.0606] > <@bakkot:matrix.org> Why are promise instances relevant? Promise instances are reified async control flow operations. [08:40:46.0274] More to the point: Justin Ridgewell , you said that for your abstraction to work, there _must_ not be a way to escape the context. if `onload` is a way to escape the context, then... ??? [08:40:48.0288] That's a great way to put it [08:40:58.0337] so are callbacks! [08:41:24.0196] "Promises are sugar for callbacks" is at least as important as "await is sugar for Promises" [08:41:29.0092] Callbacks aren't _explicitly_ async control flow. [08:41:58.0025] > <@bakkot:matrix.org> "Promises are sugar for callbacks" is at least as important as "await is sugar for Promises" That's a false equivalence. Promises are sugar for CPS, of which callbacks are a part, not the entirety. [08:42:27.0979] Sure, sugar for CPS, then. But `onload` is CPS also. [08:42:48.0720] No, onload is reactivity. It isn't expressly intended to solve async control-flow. [08:43:08.0973] I do not understand the distinction you're drawing here. [08:43:12.0778] `Promise` is expressly intended to solve async control flow. [08:44:24.0318] backing up a step from whether something is or is not "explicitly" async control flow, my position is that it is not reasonable to ask developers to intuit that XHR's `.onload` is a fundamentally different _kind of thing_ than `fetch`'s `.then`, especially since we've spent most of the last decade going around telling everyone that the latter is sugar for the former. [08:44:41.0936] so I am not OK with designs which require developers to intuit this difference. [08:45:33.0299] ljharb: I'd like to try to have a call to resolve the `Id` issue, are you available during the break today? [08:45:40.0112] but I am OK with both possible designs which treat those as the same kind of thing - making `onload` wrap, or making `then` not wrap. [08:45:57.0482] I think your definition of CPS is is _far_ more broad than what is generally accepted. [08:46:11.0711] again, I am not super committed to the definition of terms here. [08:46:40.0173] > <@pchimento:igalia.com> ljharb: I'd like to try to have a call to resolve the `Id` issue, are you available during the break today? absolutely, thanks [08:46:42.0501] the thing which is important to me is the bit about whether or not developer should know to treat `.onload` as a different kind of thing from `.then` [08:46:57.0944] and, specifically, whether developers _who aren't doing anything with async contexts at all_ should have to know that [08:47:10.0591] I think that whether `onload` should wrap should be up to WHATWG. TC39 doesn't spec `onload`, however. What we do specify is `Promise`. [08:47:45.0992] > <@ljharb:matrix.org> absolutely, thanks can we aim for the first half of the break? [08:47:47.0813] refactoring my library from `fetch` to `XHR` should not break _consumers_ of my library just because they happened to be using async contexts. [08:48:16.0959] yup, just shoot me a link, i'm open [08:48:34.0774] That would already have consequences [08:49:17.0930] * again, I am not super committed to the definition of terms here. [08:50:03.0391] For example, you would have to manually handle error propagation. If not, then there are observable differences in whether that error is a rejection, an unhandled promise rejection, or some other host-defined error-handling mechanism. [08:51:25.0789] By using `Promise`, you get a lot of async control flow functionality for free. Automatically flowing an `AsyncContext` across async control flow is more free functionality. [08:51:29.0796] OK, so assume I am manually handling error propagation. [08:52:07.0418] You, as the library author, could also manually `AsyncContext.wrap` the incoming callback to support context flow. [08:52:09.0429] As the library implementor, I should not have to care about whether or not I am flowing an `AsyncContext`. That is, as I understand it, literally the entire point of this feature. [08:52:30.0464] * As the library implementor, I should not have to care about whether or not I am flowing an `AsyncContext`. That is, as I understand it, literally the entire point of this feature. [08:52:54.0611] I've created https://meet.jit.si/identifier. not all the champions will be there but Justin, Richard, and I will [08:54:52.0031] Please join the fun AsyncContext discussion at #tc39-async-context:matrix.org ! [08:55:48.0029] > <@bakkot:matrix.org> As the library implementor, I should not have to care about whether or not I am flowing an `AsyncContext`. That is, as I understand it, literally the entire point of this feature. That's not entirely true. If you, as a library author, are using language-specified async control flow capabilities (`await`, `Promise`, `AsyncContext`), then yes it should be transparent. As a library author you should also be able to explicitly escape the current context, which is also achievable with `AsyncContext.wrap`. [08:57:08.0524] In fact, if you were wrapping your XHR `onload` in a `new Promise(...)`, having `.then` do async control flow for you would be a win, because you still get `AsyncContext` flow for free. [08:57:22.0728] * In fact, if you were wrapping your XHR `onload` in a `new Promise(...)`, having `.then` do async control flow for you would be a win, because you still get `AsyncContext` flow for free. [08:57:25.0526] littledan: MatrixError: [403] You are not invited to this room. (https://matrix-client.matrix.org/_matrix/client/r0/join/%23tc39-async-context%3Amatrix.org) 🥺 [08:57:31.0597] The thing that Justin Ridgewell said earlier was that they are trying to "guarantee they cannot escape our context" [08:57:58.0473] which means that "some subset of things will preserve the context transparently" is not good enough [09:00:39.0076] I think it will always be possible for a library to run a callback in a pre-captured context? but the user can always wrap their callback to force it back. [09:00:56.0350] > <@bakkot:matrix.org> which means that "some subset of things will preserve the context transparently" is not good enough I'm not refuting that. My position is that `await` and `Promise` must support automatic flow _at a minimum_ to be viable. [09:01:16.0084] It means any API or syntactic surface the user code has available to them cannot allow them to escape an AsyncContext that was created when invoking the user code the first time [09:01:35.0349] I am still confused about what you mean by "viable", since, while I grant that those are _necessary_ for the thing Justing wants, they are certainly not _sufficient_ [09:01:42.0733] built-ins like Promise and syntax like await must preserve this [09:01:47.0229] by "viable" do you mean something like "convenient"? [09:01:53.0506] > <@littledan:matrix.org> Please join the fun AsyncContext discussion at #tc39-async-context:matrix.org ! I think we need to transfer it to the TC39 space first, then open up registrations to any space members [09:01:55.0848] > <@shuyuguo:matrix.org> littledan: MatrixError: [403] You are not invited to this room. (https://matrix-client.matrix.org/_matrix/client/r0/join/%23tc39-async-context%3Amatrix.org) 🥺 Sorry about that, please try again [09:02:06.0005] > <@jridgewell:matrix.org> I think we need to transfer it to the TC39 space first, then open up registrations to any space members no, you literally just left it private [09:02:29.0749] the only other feature in the language async calling is FinalizationRegistry callbacks, which should also capture at creation [09:02:44.0997] > <@mhofman:matrix.org> built-ins like Promise and syntax like await must preserve this no one should have to know that XHR or setTimeout are not "built in" in the same sense that Promise is [09:02:48.0233] anything else is a host API, that can be virtualized by the environment executing the user code [09:03:29.0870] I'm not asking that they do, I'm saying the onus is on the host to preserve this guarantee, whatever "host" is (virtual or browser, etc.) [09:04:45.0522] If we want it to be a guarantee we can write it down, but it sounds like the designers of the feature do not think it should be a guarantee, so I don't understand the model we're going for here [09:04:46.0204] > <@bakkot:matrix.org> by "viable" do you mean something like "convenient"? No, I mean an `AsyncContext` that doesn't support `.then` would not be useful for my purposes and I don't know that I would be willing to support Stage 2 without it. Limiting it only to `await` makes it barely usable and results in a terrible DX for the most common case outside of `await` itself. [09:05:14.0509] How can we transfer #tc39-async-context:matrix.org to the TC39 space? [09:05:25.0854] i think i can do it if you add me as an admin to the channel [09:06:04.0212] Done [09:07:17.0953] > <@rbuckton:matrix.org> No, I mean an `AsyncContext` that doesn't support `.then` would not be useful for my purposes and I don't know that I would be willing to support Stage 2 without it. Limiting it only to `await` makes it barely usable and results in a terrible DX for the most common case outside of `await` itself. that is: the thing you mean is "without this it will be too inconvenient to be practical", not "without this it will lack some guarantee I rely on", right? [09:07:20.0828] give me a bit, i should have it done by 10 [09:08:43.0401] I am open to arguments of that form, but those would incline me in the direction of making it a requirement for hosts that _any_ method of registering a callback which might get run out of the current microtask tick must wrap the callback with the async context which was present when the callback was registered [09:08:54.0183] (like I said, I'm ok with "all" or "none", just not "some") [09:09:11.0364] * I am open to arguments of that form, but those would incline me in the direction of making it a requirement for hosts that _any_ method of registering a callback which might get run out of the current microtask tick must wrap the callback with the async context which was present when the callback was registered [09:10:04.0707] > <@bakkot:matrix.org> that is: the thing you mean is "without this it will be too inconvenient to be practical", not "without this it will lack some guarantee I rely on", right? Then yes. Requiring manual wrap for `.then` is too inconvenient to be practical, and too confusing for users who have been told for years that `async`/`await` is a syntactic transformation over `.then`. Adding something new to `await` would break that mental model. [09:10:17.0569] Who has permissions to add rooms to the TC39 space? [09:10:23.0952] We'd like to add the existing async context room [09:11:08.0298] Jordan said he'd do it just above [09:12:30.0279] (I wouldn't mind if all delegates had these sorts of permissions) [09:13:02.0373] sorry, I had missed this comment. thanks, Jordan! [09:14:04.0961] > <@bakkot:matrix.org> (like I said, I'm ok with "all" or "none", just not "some") I don't imagine "all" is practical either, not without running afoul of shu's performance concerns. My position is that it should be considered on a case-by-case basis by hosts whether async context should automatically flow. Perhaps we can provide guidance on what cases make sense, but I'm not sure we could mandate "all". [09:15:39.0705] But within ECMA-262, it should _at least_ flow through the built-in control-flow objects we have (namely built-in `Promise` and `Generator` objects). [09:18:58.0472] If we can't mandate "all", we can't do the "cannot escape context" thing Justin said is a requirement [09:19:39.0371] "cannot escape the context" is something which a particular *environment* can give semantics to [09:19:44.0368] it is not a meaningful thing at our level [09:19:56.0669] we just have a couple cases to decide on [09:20:16.0638] it is certainly meaningful within Bloomberg, and has been implemented with this case-by-case approach [09:21:05.0805] If we're not worried about whether or not it's _possible_ to escape the context, then it's just a question of ergonomics, and that's something which we can discuss - I continue to be of the opinion that requiring _every library author in the world_ to think about AsyncContexts is worse ergonomics than making people who are doing fancy things with `.then` _and also_ with AsyncContexts think about AsyncContexts. [09:21:16.0247] * If we're not worried about whether or not it's _possible_ to escape the context, then it's just a question of ergonomics, and that's something which we can discuss - I continue to be of the opinion that requiring _every library author in the world_ to think about AsyncContexts is worse ergonomics than making people who are doing fancy things with `.then` _and also_ with AsyncContexts think about eAsyncContexts. [09:21:28.0854] * If we're not worried about whether or not it's _possible_ to escape the context, then it's just a question of ergonomics, and that's something which we can discuss - I continue to be of the opinion that requiring _every library author in the world_ to think about AsyncContexts is worse ergonomics than making people who are doing fancy things with `.then` _and also_ with AsyncContexts think about AsyncContexts. [09:21:59.0219] I am a lot more OK with making people who are explicitly using AsyncContexts think about them than making everyone else think about them. [09:22:34.0143] > <@bakkot:matrix.org> I am a lot more OK with making people who are explicitly using AsyncContexts think about them than making everyone else think about them. This just isn't the way they are used; the AsyncContext flows through a whole environment automatically and this is the entire point. [09:22:58.0013] > <@bakkot:matrix.org> If we can't mandate "all", we can't do the "cannot escape context" thing Justin said is a requirement Our platform only has so many ways for devs to do async tasks, so just having `await`/`Promise`/`setTimeout`/`setInterval` is sufficient for us to guarantee our platform contexts is preserved [09:23:12.0941] The dev could have their own contexts inside ours, but it'd be impossible for them to escape ours [09:24:01.0662] > <@littledan:matrix.org> This just isn't the way they are used; the AsyncContext flows through a whole environment automatically and this is the entire point. Only if we require of hosts that every mechanism of scheduling callbacks flows AsyncContexts, including event listeners and unhandled promise rejection handlers and so on. [09:24:39.0291] it's not something we require, it's something we allow [09:24:40.0691] That's what I keep saying - if it is in fact a requirement that it flows through the whole environment automatically, then the _ergonomic_ differences between Promise.prototype.then and addEventListener just aren't relevant. [09:25:09.0867] maybe we should shift this conversation to the AsyncContext room? [09:25:15.0955] And if it's not a requirement that the context flows automatically, then library authors now have to think about async contexts all the time. [09:25:16.0635] Sure. [09:25:31.0829] I also opened https://github.com/legendecas/proposal-async-context/issues/22 for anyone who wants to follow along. [09:26:59.0594] > <@bakkot:matrix.org> And if it's not a requirement that the context flows automatically, then library authors now have to think about async contexts all the time. Yes. Actually, having just one mechanism here as opposed to several should simplify things for library authors who are already living this reality in environments with a version of this feature. [09:28:04.0903] Let's continue the conversation in the async contexts room? [09:28:38.0664] Also, as `AsyncDisposableStack` is another case of a reified async control-flow mechanism (representing an imperative version of `using await`), I would also expect that the async context would automatically flow to the registered `[Symbol.dispose]()` method or `adopt`/`defer` callbacks when the stack itself is disposed. [09:29:49.0995] Not when the stack is disposed manually, surely? [09:43:37.0226] Why would that not be the case? That would certainly be the case if calling `dispose()` on the synchronous `DisposableStack`, would it not? [09:58:08.0008] Though it could be that the automatic capture might need to occur at the point the resource is registered. I admit, it is something that will need to be investigated. [09:58:15.0026] * Though it could be that the automatic capture might need to occur at the point the resource is registered. I admit, it is something that will need to be investigated. [10:02:17.0398] My connection may have dropped [10:03:06.0935] Sorry, it looks like I just lost my internet connection [10:03:31.0385] rbuckton: would you be able to reconnect? [10:05:24.0679] I just restarted the router and am waiting for a connection [10:05:58.0997] It does not look like it will be back up quickly. I can try to connect from my phone if someone else can run the slides [10:11:20.0481] https://tc39.es/proposal-symbol-predicates/ [10:17:00.0827] Rob Palmer: Is there a plan to come back to the demoting import assertions to stage 2 in this meeting? [10:19:50.0066] msaboff: We want to discuss import assertions tomorrow, but we're still drafting what would be proposed. [10:20:09.0934] can't see the screen, is that only me? [10:21:00.0906] I am now back online, my apologies for the interruption. [10:21:10.0993] I can see [10:21:42.0923] reconnected and now i also see [10:24:56.0488] shu: current semantics is the class declaration is decorated, and potentially replaced, affecting both the local and exported binding. [10:25:09.0101] then what's the footgun? [10:25:24.0111] the footgun as daniel says depends on the local being undecorated but the export being decorated [10:25:41.0770] The biggest reason why we did not change this back in stage two was the potential do decorate _both_ the export _and_ the class separately. [10:25:59.0347] oh okay i think i get it, let me try [10:26:27.0217] the reason we have export-decorator ordering is for the _possibility_ of distinguishing decorated export-only or decorated local-only [10:26:32.0164] do you figure I could write a codemod to move the `export` keyword before the decorators before this topic finishes while also fixing up the notes [10:26:34.0738] it can't be that hard [10:26:43.0659] and you're saying, not only is there no demand for that distinguishing, it is a footgun to distinguish [10:26:56.0019] The investigation I did into "export decorators" led to the conclusion that it isn't something that could have any kind of meaningful semantics. [10:27:01.0749] Yes. [10:27:41.0532] that's not the only reason tho. it's also because of some who believe the decorator "should" come next to the thing it's decorating, instead of an unrelated keyword being injected between them [10:28:16.0117] in GNOME, we had a strong use case for the local binding being the decorated class, not the undecorated one. although we seem to have managed to rewrite things so it doesn't matter. I gave more details in https://github.com/tc39/proposal-decorators/issues/441 [10:28:28.0092] > <@shuyuguo:matrix.org> the reason we have export-decorator ordering is for the _possibility_ of distinguishing decorated export-only or decorated local-only * that's not the only reason tho. it's also because of some who believe the decorator "should" come next to the thing it's decorating, instead of an unrelated keyword being injected between them [10:29:10.0021] by the local binding, do you mean the binding within the class? [10:29:23.0371] littledan: no, the unexported binding [10:29:25.0647] within the module [10:29:43.0039] > <@shuyuguo:matrix.org> littledan: no, the unexported binding yeah I guess that part is clear [10:29:55.0926] I assumed the binding would be decorated either way, and "export decorators" would be decorators that applied specifically _to exports_ in some way [10:30:11.0741] yes, that [10:30:11.0865] okay i just don't have an intuition here [10:30:22.0678] bakkot: ah okay [10:31:07.0649] oh, I meant the binding within the class. disregard my comment then [10:31:09.0216] We definitely had at least 8 months of plenary discussion about decorator/export ordering [10:31:21.0336] in addition to the breakout groups that Jordan mentions [10:31:33.0763] and in addition to extensive discussion in the regular decorator calls [10:31:37.0489] i remember the breakout yes [10:32:13.0394] That doesn't mean it's bad to bring up! [10:32:14.0547] > <@bakkot:matrix.org> I assumed the binding would be decorated either way, and "export decorators" would be decorators that applied specifically _to exports_ in some way (e.g. as jrl says on the queue, make the binding writable from the outside which would be kind of neat I guess) [10:33:08.0175] man I don't care that much about this question but the idea that `export` is the same kind of thing as `async` is _wild_ to me [10:33:15.0118] what happens to export default? [10:33:29.0705] rbuckton: ^^ [10:33:50.0416] `@dec export default class {}` [10:33:51.0505] Justin Ridgewell: it's a strawperson (meaning in the hypothetical sense) footgun [10:34:11.0404] like, nothing has this footgun today, but if we started distinguishing semantics depending on where the decorator appears, then it becomes a footgun [10:35:39.0866] does anyone know offhand of a library which is using `@dec export class {}` style decorators so I can develop my codemod against it [10:36:08.0928] bakkot: it's a good question, i added a q item [10:36:15.0727] is anyone actually advocating for the distinct semantics? Or is this just about syntax placement? [10:38:11.0555] `nest`, apparently [10:38:16.0894] https://github.com/nestjs/nest [10:38:17.0995] > <@leobalter:matrix.org> is anyone actually advocating for the distinct semantics? Or is this just about syntax placement? We are stating that the one major reason that changing the syntax was blocked some time back was to allow for the potential of "export decorators", which we do not believe to be a viable option. If that is no longer a blocking concern, then we want to discuss changing the ordering. [10:38:41.0502] Fwiw, Babel's most used decorators versions is the "legacy" one, which has decorators before `export`. The new versions have a `decoratorsBeforeExport` option to choose, and according to GitHub search it's set to `true` and `false` more or less the same number of times [10:38:51.0923] https://github.com/nestjs/nest/blob/master/sample/33-graphql-mercurius/src/app.module.ts [10:39:01.0659] Thanks for the clarification, rbuckton. So this seems like only about syntax ergonomics [10:39:24.0706] https://github.com/search?q=decoratorsBeforeExport%3A+true&type=code and https://github.com/search?q=decoratorsBeforeExport%3A+false&type=code [10:39:33.0317] wait what [10:39:44.0933] that it's set the same number of times is a pretty strong counterargument to "nobody's demanded a different ordering in 8 years" imo [10:39:57.0598] i... would've figured we definitely don't have appetite to add keywords for such scoped semantics like "writable namespace exports"? [10:40:57.0651] "we want syntax for more static analyzability" is pretty true of a lot of things that don't meet the syntax bar, no? [10:41:08.0695] Well, but most people are using the legacy version that _only_ supports decorators before exports. I'm saying this based on how much issues/discussions we get about decorators, but also searching for `babel legacy: true` on GitHub gives a lot of results -- https://github.com/search?q=babel+legacy%3A+true&type=code [10:41:32.0325] all decorators [10:41:34.0014] regarding Symbol predicates: i'd love some committee feedback on https://github.com/tc39/proposal-symbol-predicates/issues/9. Namely, to me, a predicate never throws and only returns a boolean - and in this case, eg "isRegisteredSymbol" is asking "is this a symbol and also a registered one". michael seems to read it as asking "is this symbol a registered symbol", implying it should throw on non-symbols. does anyone have thoughts on this? Please add them to the issue! [10:41:35.0486] all decorators meet that bar [10:41:51.0846] oh sure. most people don't have the choice tho [10:42:02.0137] it's telling that when _given_ the choice, it's about an even split [10:46:13.0350] side question: in matrix, now that there are threads, how do i find threads i have unread messages in? [10:46:28.0510] my answer so far is, scroll [10:46:31.0422] I was trying to do this same thing! [10:46:32.0260] which is not... ideal [10:46:46.0653] well guess some messages are staying unread [10:47:05.0226] oh I think I just figured it out [10:47:41.0071] close any open thread if you have one open, then click this button: [10:47:41.0198] Click the thread icon in the top right of the app [10:47:48.0592] in the top right [10:48:03.0794] ooo [10:48:08.0426] i can click on `< Threads` [10:48:21.0585] and when you still can't find it, right click on the room and Mark as read [10:49:34.0756] there's also a "back" left chevron in the upper left corner of a thread window that takes you there [10:49:35.0205] oh, also this is helpful: [10:50:08.0200] the default seems to list every thread, which I can't imagine wanting [10:51:28.0587] I see this in Element: [10:51:30.0230] ugh, it doesn't remember that preference though [10:51:38.0117] Option 2 kills the idea of distinct semantics. Syntax positioning can eventually be set as a linter preference for consistency within user code. [10:51:55.0157] I really like option 2 for this reason. [10:52:05.0819] not to me in this context, where "fixed" is much more likely to mean "unchanging" than "no longer broken" [10:52:26.0917] option 2, however, ensures burden on linters/formatters, and creates style debates, forever [10:52:58.0048] but... it's the same word [10:53:50.0939] the tense makes the difference to me [10:54:09.0941] ok here is a codemod to go from TS-style to ES-style placement https://github.com/bakkot/export-decorated-class-codemod [10:54:13.0512] especially in programming, where (it seems to me that) "fix" is relatively rare but "fixed" is relatively common [10:54:17.0781] thank you to whoever has been fixing the notes while I looked away to write this [10:54:19.0067] * especially in programming, where (it seems to me that) "fix" is relatively rare but "fixed" is relatively common [10:54:40.0557] bakkot: you were supposed to do both at the same time! [10:54:49.0539] I was doing some amount of it [10:54:52.0039] but then kind of forgot [10:55:38.0160] there's also https://hackage.haskell.org/package/base-4.17.0.0/docs/Data-Function.html#v:fix [10:56:55.0036] `export default class C {}` is a default export and a `C` class declaration. [10:57:09.0856] `export default (class C {})` is a default export for an expression [10:57:11.0152] i think `transferAndFixLength` makes it sound like it does a transfer, then does an operation to turn a resizable buffer into a fixed length one [10:57:27.0906] I'm off for the evening, if anyone has any concerns or wants to get a Mozilla opinion, we have iain taking over for the last hour! (acronym is IID) [10:57:31.0529] but that "fixing the length" operation isn't something that exists [10:57:38.0145] option 1 is really nice to avoid confusion from `export` vs `export default`. The @decorator will always be placed without confusion. ljharb the style discussion burden option 2 seems not enough for me to object. It's already in the nature of the language [10:57:45.0054] also it may be ambiguous between what length you're fixing [10:57:48.0208] the receiver or the return value [10:58:27.0945] rbuckton: what about `export default class {}`? [10:58:33.0038] prefer option 1 [10:58:33.0122] * rbuckton: what about `export default class {}`? [10:58:39.0005] > <@ljharb:matrix.org> rbuckton: what about `export default class {}`? declaration [10:58:45.0511] with what binding name, "default"? [10:58:46.0568] With option 1 (decorators only before export), would `export default @dec class A {}` be a valid export of a class expression? [10:58:53.0898] * With option 1 (decorators only before export), would `export default @dec class A {}` be a valid export of a class expression? [10:59:04.0559] and what about `export default @noopDecorator class {}`? [10:59:12.0365] > <@nicolo-ribaudo:matrix.org> With option 1 (decorators only before export), would `export default @dec class A {}` be a valid export of a class expression? oh god [10:59:18.0202] It creates an export binding named `default`, as evidenced by `import { default as Foo } from "module"` [10:59:27.0507] > <@nicolo-ribaudo:matrix.org> With option 1 (decorators only before export), would `export default @dec class A {}` be a valid export of a class expression? I guess we would need a lookahead restriction to disallow it [10:59:38.0166] We would disallow that and require parens. or at least, that would be my preference [10:59:52.0710] > <@bakkot:matrix.org> oh god * We would disallow that and require parens. or at least, that would be my preference [10:59:57.0681] Someone is typing very loudly [11:00:06.0062] sorry, that was me [11:00:12.0264] > <@ljharb:matrix.org> and what about `export default @noopDecorator class {}`? This is very much a declaration. This is clear in the decorator spec. [11:00:15.0098] I guess we already lookahead prevent `class` and `function` in that position, so adding decorators there is presumably easy [11:00:43.0342] > <@littledan:matrix.org> This is very much a declaration. This is clear in the decorator spec. and it makes a local binding `default`? [11:00:55.0317] no you don't get a local binding from anonymous classes [11:01:15.0022] with or without decorators, `export class {}` has no user-observable local binding [11:01:41.0706] ryzokuken: can we do a heat check for both options? [11:02:43.0111] interesting [11:02:44.0656] > <@bakkot:matrix.org> with or without decorators, `export class {}` has no user-observable local binding `export class {}` without either `default` or a name is illegal [11:02:59.0437] the thing I didn't like about the name we went with is that it feels like it drops off without mentioning a noun [11:03:05.0936] We will need very clear wording for a temp check. [11:03:06.0998] sorry, `export default class {}`, of course [11:03:17.0877] "transferTo" needs to be followed by a thing [11:03:21.0546] but it's missing a thing [11:03:32.0278] * "transferTo" needs to be followed by a thing [11:03:33.0684] > <@leobalter:matrix.org> ryzokuken: can we do a heat check for both options? We have 3 options [11:03:56.0116] hey now, my codemod is correct [11:03:57.0458] we'd need a well-defined problem statement for a temp check [11:03:58.0978] it keeps trivia [11:04:06.0881] > <@robpalme:matrix.org> We will need very clear wording for a temp check. I'd like to hear how people support or object to Option 1 and Option 2. The XOR might be discussed after? [11:04:13.0194] it keeps every single character that was in the source [11:04:15.0328] just moves them around [11:04:34.0662] writing correct codemods is not that hard [11:05:05.0663] Please phrase the question as a temp-check compatible question. https://github.com/tc39/how-we-work/blob/main/presenting.md#temperature-checks [11:05:33.0103] Do you want multiple temp checks? [11:05:48.0631] multiple, for each option proposed [11:06:10.0417] presumably TS could retain the ability to parse decorator-before-export, and give a specific helpful message in that case too telling them how to fix it? [11:06:13.0259] The goal is to help me identify what concerns are counted as strong objections [11:06:43.0496] Mark has already said he is strongly opposed to Option 1 [11:07:32.0502] hm, i just got booted from the meeting, is that just me? (probably just me) [11:07:33.0158] * hm, i just got booted from the meeting, is that just me? (probably just me) [11:07:51.0544] could you try reconnecting? [11:08:01.0187] nah it was just my local internet. comcast fun times. [11:08:03.0057] and Mark seems to be ok with Option 2. Perhaps the heat check might just aim to this option [11:09:04.0663] Rob Palmer ryzokuken if the TS team is fine, can we just do a temp check for support/objection to Option 2? [11:09:12.0370] I also apologize for the keyboard noise. I thought Jitsi had NVidia Broadcast set for my input audio, which normally filters that out, but it was not. [11:09:20.0920] we don't have time for it now [11:09:44.0343] this would be a very valuable information from this discussion [11:10:12.0106] leaving a workable path to move it forward [11:10:25.0658] leobalter: You still haven't formed a clear question for the temperature check [11:10:31.0356] I did [11:12:13.0021] We'll do the temp check tomorrow. I encourage the champions (and everyone) to read the guidance on how to request and frame temp checks. We have repeatedly had problems when people request them on-the-fly. It is much better to pre-plan them. https://github.com/tc39/how-we-work/blob/main/presenting.md#temperature-checks [11:12:26.0113] re: the migration path, there are going to be some decorators which cannot be migrated 1-1 is the core issue. The new spec is just less powerful than the old one in some core ways. In these cases, it's likely that teams will try to migrate in parts, and possibly use both specs in different files (using a pragma to distinguish which spec to use) [11:12:44.0823] depending on the size of the codebase, of course [11:13:17.0423] Yeah, but you can codemod one file at a time, surely [11:13:31.0271] minimizing syntax changes minimizes the number of files that _need_ a pragma, because files when the syntax is the same can feature detect based on usage [11:13:34.0277] so is that an argument that this particular ordering is better served by codemods, or not by codemods and by changing the language...? [11:13:42.0220] Rob Palmer: I'm sorry about the last minute request. I did a quick read on the doc. I'm not the one proposing the change, so I'll drop my requests anyway. [11:14:13.0864] bakkot: some of these changes will not be codemoddable [11:14:33.0150] pzuraq: the only change we're discussing is syntax, which is definitely codemoddable [11:14:36.0638] * pzuraq: the only change we're discussing is syntax, which is definitely codemoddable [11:14:39.0911] e.g. transitioning to `accessor` [11:14:58.0071] yes i'd prefer this discussion to be scoped to this particular change [11:15:05.0904] not fully generic ones, or even generic ones about decorators [11:15:16.0293] in that case, yes that one exact change is very codemoddable [11:15:30.0433] unless the fullness of transitioning to ES decorators _is_ the point you're trying to make, which i can appreciate [11:15:40.0137] but i didn't get that point from TS [11:15:43.0389] yes, that is the point I'm trying to make [11:16:05.0620] danielrosenwasser rbuckton pzuraq I don't think I'm available tomorrow. FWIW, option 2 works for me. I +1 the preference for XOR positioning. I also +1 to blocking decorator before ambiguous class expr. [11:16:21.0200] * danielrosenwasser rbuckton pzuraq I don't think I'm available tomorrow. FWIW, option 2 works for me. I +1 the preference for XOR positioning. I also +1 to blocking decorator before ambiguous class expr. [11:16:36.0412] what do you mean by "blocking decorator before ambiguous class expression"? [11:16:45.0997] if we do the XOR thing that implies `export default @dec class A{}` is a declaration, not an expression [11:17:13.0793] * if we do the XOR thing that implies `export default @dec class A{}` is a declaration, not an expression [11:17:24.0466] https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$gTO6aM4DVgUXJaskNyv4jIqimo85LHbMtYxA32NT2-c?via=matrix.org&via=igalia.com&via=mozilla.org [11:17:32.0332] if we do decorators-only-before-export then `export default @dec class A {}` is a default export of a class expression, under some possible ways of writing the spec [11:17:48.0496] in the decorators-only-before-export world that should be illegal, probably [11:18:34.0344] `export default @dec class A {}` [11:19:09.0689] I don't get it, the proposal already does a "lookahead ∉ {... `@` } [11:20:14.0609] * I don't get it, the proposal already does a "lookahead ∉ {... `class`, `@` } [11:20:30.0318] "some possible ways of writing the spec" [11:21:14.0812] if it is already prohibited I assume everyone is happy [11:21:28.0160] actually, we might be wanting the same thing leobalter [11:22:01.0507] yes! I'm just sharing my support or whatever goes as my Salesforce / LWC position [11:22:24.0764] LWC does not use class decorators yet, but the feedback comes in from the team. [11:23:30.0102] > <@pzura:matrix.org> yes, that is the point I'm trying to make for every file, decorators in that file will either be written using TS's old semantics or ES semantics. If you are choosing for that file to use ES semantics, it is not that hard to codemod that file, I would think. if you're changing the semantics for your whole project at once, you can run the codemod for your whole project at once. [11:23:51.0240] I there's migration pain involved in getting the semantics within the decorator right, but the codemod still seems basically trivial. [11:24:05.0639] I do not oppose to option 1 either. Option 2 is just my preference considering the discussion the committee had. [11:24:10.0299] btw what is a codemod [11:24:14.0812] is it "just" a transform [11:24:22.0747] or does it have more bells and whistles attached? [11:24:30.0765] in my case, just a source rewrite [11:24:33.0464] string-to-string [11:24:35.0335] teams will have to remove some decorators and change the invocations of others, and a codemod will not be able to tell based on usage [11:24:50.0393] e.g. a dev will have to manually look at each decorated field to see if it needs `accessor` [11:25:01.0513] yeah, I agree that a codemod cannot help you with the thing where the semantics are different [11:25:07.0582] but neither can any particular choice of syntax here [11:25:21.0571] it can reduce what is going to be a very painful transition [11:25:24.0508] for some teams [11:25:44.0839] on top of the other benefits, e.g. documentation costs [11:26:10.0536] I just don't see the "after going through every decorator in this file and migrating it so it's going to be ES-semantics-compatible, also run a codemod after" as being a noticeable change in the amount of pain [11:26:29.0537] I agree the transition is painful in general but not that this particular thing is more than a trivial additional amount of pain [11:32:34.0182] I suspect people probably _would be_ surprised that `for await` does an `await` on `break`, but this doesn't actually lead to the code doing a different thing than they expect so it's fine [11:32:40.0915] that will not be true of this syntax [11:33:18.0570] > <@bakkot:matrix.org> that will not be true of this syntax Hmm, I think this will "just work" in practice, just like all the stuff around `for await`. [11:33:51.0003] no, because the RHS does not get awaited [11:34:06.0565] like if you see `using await x = y` and assume that `y` is awaited, you will be wrong [11:36:04.0926] i must be dumb because all these arguments still cut both ways to me [11:36:22.0990] but maybe that's fine, that means we just need to choose one? [11:36:38.0713] > <@shuyuguo:matrix.org> i must be dumb because all these arguments still cut both ways to me Yeah I kinda think either one could be learned and work [11:36:58.0106] I think that there are decent theoretical arguments in both directions, and also that people can learn either syntax eventually [11:37:16.0494] which means that I would decide this by, which do we expect to cause less initial confusion, emperically [11:37:30.0593] my expectation is that `async using` will cause less confusion than `using await` [11:37:41.0329] given infinite resources I would run a study but I don't think it's worth running a study [11:38:34.0678] that said I am not, like, absolutely committed to the `async using` syntax. I think it will result in less confusion but it's not the end of the world if more people are confused. [11:38:56.0751] yeah @bakkot's is my exact intuition, but it's also just intuition [11:39:25.0663] more self servingly i don't want to have to explain "well actualy, this is why `await` is not nonsense" to developers [11:40:29.0749] Honestly I don’t know who is being dismissive to user confusion here [11:41:59.0852] +1 to Mark’s “both sides” analysis [11:44:54.0505] sorry if i missed someone already answering this but why is the `for await` case not precedent for `await` not always meaning "await right here"? [11:45:13.0607] peetk: with `for await` all the `await`ing happens scoped to that statement [11:45:19.0819] that is not true for `using await` [11:45:47.0029] that is, right now `await`, including in `for await`, means "there's some awaiting in the rest of this statement" [11:46:44.0250] i see. that's an expanded definition of "right here" tho [11:47:01.0664] not one which causes confusion in practice, though [11:47:23.0668] but I still expect `using await` to cause confusion in practice [11:47:28.0313] is `for await` widely used enough to gauge how confusing it is lol? [11:47:29.0641] no matter how good our theoretical justifications are [11:47:32.0385] Is it expanded? It's performing an await on that line before the block on the next line begins execution [11:47:43.0267] I think so? `for await` sees a fair bit of use IME [11:47:56.0522] fair enough [11:48:31.0834] https://nodejs.org/api/readline.html#example-read-file-stream-line-by-line etc [11:48:46.0560] * https://nodejs.org/api/readline.html#example-read-file-stream-line-by-line etc [11:48:49.0812] my experience is normie devs are not even sure it's valid javascript when they see it but *shrugs* [11:50:13.0653] maybe that's changing these days idk [11:50:36.0232] new syntax always takes a while to catch on, yeah [11:54:00.0189] > <@jridgewell:matrix.org> Is it expanded? It's performing an await on that line before the block on the next line begins execution doing real back of the envelope folk dev psychology here but imo the await would need to be inside the parens to visually cue that an await happens on each iteration, per the proposed interpretive principle [11:55:02.0368] the proposed interpretive principle is "`await` signals that its RHS will do some awaiting", and that's true in the current syntax [11:55:38.0453] at least assuming the body of the loop is considered to be "its RHS", but since it's in the same place as the `for` token and the body of the loop is surely the RHS of the `for`, that seems legit [11:55:58.0494] * the proposed interpretive principle is "`await` signals that it + its RHS will do some awaiting", and that's true in the current syntax [11:56:21.0985] i guess i was responding to a different proposed interpretive principle which was "await means some awaiting happens right here" [11:57:11.0438] I think the body of the loop counts as "right here" [11:57:44.0436] hm that feels kind of intuitive to me actually [11:58:06.0140] hypothetically if the syntax was `using await (bindingExpr) { }`, that seems perfectly clear [11:59:22.0609] that seems really nice, but i think ron had use cases for wanting to do some action which might throw, queue up the result, and then have it disposed at block exit, which i'm not sure would work with that form? [11:59:43.0497] > <@shuyuguo:matrix.org> hypothetically if the syntax was `using await (bindingExpr) { }`, that seems perfectly clear it used to be approximately that (with `try` instead) and we moved away from it [11:59:51.0171] right i know [11:59:54.0412] > <@bakkot:matrix.org> I think the body of the loop counts as "right here" i disagree. the `await` in `for await` has always felt me like sticking an await in a truly random place to vaguely signal that some awaiting happens somewhere, somehow, and i had to learn by rote where actually it happens. [12:00:01.0194] i'm just saying what you said about the for body counting as "Right here" rings true to me [12:00:09.0274] ah sure [12:01:20.0402] i guess to sharpen my point it's not as though this interpretive principle helps people understand what exactly is being awaited, when, at least in the case of `for await`. [12:01:28.0252] hm. I think I would be much, much more surprised if `for await` did awaiting _not_ in that statement [12:01:43.0244] like, I agree you have to learn the rules for where _within_ the statement [12:01:45.0156] there's an interleaving point in an `async function`, that's invoked, even with no `await` present, no? same with the proposed `async do {}`? or is that incorrect because async functions (and async do blocks) run synchronously until the first await, or return? [12:01:48.0030] but the non-locality of `using` is sort of already baked into `using` [12:01:48.0076] but it's scoped [12:03:55.0547] * there's an interleaving point in an `async function`, that's invoked, even with no `await` present, no? same with the proposed `async do {}`? or is that incorrect because async functions (and async do blocks) run synchronously until the first await, or return? [12:04:59.0782] async function's its a bit weird because of the return, but `async do {}` there's no interleaving unless you explicitly `await` in the body [12:05:05.0120] * async function's its a bit weird because of the return, but `async do {}` there's no interleaving unless you explicitly `await` in the body of the `do` [12:05:06.0539] FWIW I'm not sure that enforcing turn boundaries was the right call, but this is perfectly consistent with our overall design so it seems locally reasonble [12:05:39.0664] so `async do { Promise.resolve({}) }` has no interleaving point? it produces a promise? [12:05:53.0456] > <@bakkot:matrix.org> async function's its a bit weird because of the return, but `async do {}` there's no interleaving unless you explicitly `await` in the body of the `do` * so `async do { Promise.resolve({}) }` has no interleaving point? it produces a promise? [12:06:02.0213] > <@ljharb:matrix.org> so `async do { Promise.resolve({}) }` has no interleaving point? it produces a promise? I think it wouldn't; the interleaving point would come if you awaited that [12:06:05.0384] gotcha [12:06:41.0182] ljharb: `async do {}` always produces a promise [12:07:04.0239] `async do {}` is very nearly pure sugar for in immediately invoked async arrow [12:07:20.0054] right, and in my example it'd flatten the promise and end up with a new promise for that arbitrary object [12:07:56.0526] ah, yes, that's right [12:10:26.0894] bakkot: get gilad bracha to be the tiebreaker [12:10:31.0281] need more opinions [12:10:54.0743] gilad is happier not thinking about this kind of question, I believe [12:11:14.0333] which, relatable [12:12:16.0519] i only have envy for that position [12:12:24.0745] but the world still cares [12:12:30.0183] why shouldn't the burden be thrust upon him [12:21:45.0908] i'm 92% kidding here but would people who disprefer `using await` like it better if `using`/`using await` were spelled `will dispose`/`will await dispose` respectively? [12:24:39.0972] umm no? I like `using`. [12:25:32.0455] i meant "would it address the specific 'await means here' concern" (and also it is definitely not a real proposal for many reasons) [12:25:40.0990] We already had two/three-keyword declarations in this proposal. Cutting back to one/two-keywords was a win. [12:26:42.0791] We could potentially use `await using x = ...` instead. I opted against it because of the cover grammar necessary to try to keep LR1, but it's an option. [12:26:43.0928] > <@peetk:matrix.org> i meant "would it address the specific 'await means here' concern" (and also it is definitely not a real proposal for many reasons) Well, I think `await`-doubters would want to see the `await` at the end of the block, hence the async which is always a bit more action-at-a-distance [12:27:07.0095] > <@rbuckton:matrix.org> We could potentially use `await using x = ...` instead. I opted against it because of the cover grammar necessary to try to keep LR1, but it's an option. Yeah,I was wondering about that option too, but I think that wouldn't address the concerns of the people who prefer `async using`. [12:27:13.0713] `await using x = ` is 1:1 the C# syntax. [12:27:43.0114] It indicates what you are awaiting is the `using`, possibly more strongly than `using await` does. [12:27:49.0753] > <@littledan:matrix.org> Yeah,I was wondering about that option too, but I think that wouldn't address the concerns of the people who prefer `async using`. * It indicates what you are awaiting is the `using`, possibly more strongly than `using await` does. [12:28:22.0767] yeah, maybe. Adding more cover grammars seems good to avoid. [12:28:24.0601] But I also chose `using await` to mirror `for await` in ordering. [12:29:26.0519] > <@littledan:matrix.org> yeah, maybe. Adding more cover grammars seems good to avoid. IIRC, bakkot 's position is that the syntax complexity shouldn't matter as long as we achieve the right syntax. bakkot, is that correct? [12:29:47.0591] that's what the priorities of constituencies (sp) would say, i think [12:29:51.0432] * that's what the priorities of constituencies (sp) would say, i think [12:29:59.0403] > <@littledan:matrix.org> Well, I think `await`-doubters would want to see the `await` at the end of the block, hence the async which is always a bit more action-at-a-distance yeah my thinking was that `using` already creates the action-at-a-distance, which is why it feels natural (or at least, not hideously unnatural) for it to project the `await` to also be non-local [12:30:20.0524] > <@littledan:matrix.org> Well, I think `await`-doubters would want to see the `await` at the end of the block, hence the async which is always a bit more action-at-a-distance * yeah my thinking was that `using` already creates the action-at-a-distance, which is why it feels natural to me (or at least, not hideously unnatural) for it to project the `await` to also be non-local [12:30:26.0831] > <@rbuckton:matrix.org> IIRC, bakkot 's position is that the syntax complexity shouldn't matter as long as we achieve the right syntax. bakkot, is that correct? not that it should matter literally zero - it is important not to force engines to do infinite lookahead, for example - but as long as the thing is reasonably implementable, yes [12:33:12.0454] `await [NLT] using [NLT] BindingIdentifier` wouldn't require infinite lookahead. The only problem is a recent editorial change I made to use an early error to forbid _BindingPattern_ to avoid differing uses of the `Using` production parameter, though that's also easily changed. [12:34:03.0086] (though the NLT between `await using` isn't strictly necessary, I'd still they rather not be split across multiple lines) [12:34:11.0411] * (though the NLT between `await using` isn't strictly necessary, I'd still they rather not be split across multiple lines) [12:36:23.0120] right, I think `await using x` would be acceptable from a spec-complexity point of view, if we thought that was best for users of the language [12:36:39.0307] that is, if we thought that was best, I wouldn't want to choose some other syntax just because of spec complexity reasons [12:37:25.0382] (personally, if we are sticking with `await`, I lean a little more towards `using await`, so it's harder to confuse with a statement-positioned AwaitExpression.) [12:46:26.0237] Thanks all for the feedback on the Async Resource Management proposal. My apologies for the technical issues today, hopefully they won't repeat themselves tomorrow. [13:34:56.0543] erights, et al. Apparently I misspoke regarding `Function.prototype.toString`. The specified semantics include class decorators in a class's `.toString()`, but do not include method decorators in a static method. The conclusion to that issue (https://github.com/tc39/proposal-decorators/issues/109) indicates it should be reopened if there are concerns with the resolution, however. [13:36:50.0329] There was a comment in that issue about how `eval(className.toString())` could produce a copy of that class, but that wouldn't be true in the case of a class decorator capturing the `.toString()` of its target, because its still in the middle of evaluation and the eval result _wouldn't_ be the same as the class that the class decorator sees. [13:37:03.0893] * There was a comment in that issue about how `eval(className.toString())` could produce a copy of that class, but that wouldn't be true in the case of a class decorator capturing the `.toString()` of its target, because its still in the middle of evaluation and the eval result _wouldn't_ be the same as the class that the class decorator sees. [13:41:26.0680] do people in the decorator-before-export camp think that decorators should also come before the `return` when you're returning a class? as in ``` @dec return class {} ``` [13:41:54.0949] I assume not but am not entirely clear on what the relevant distinction between `return` and `export` is here [13:46:31.0884] I guess I don't actually care enough to argue about this, ignore me [13:47:50.0907] the main outcome I would like to see here is typescript accepting only standard syntax (unless a flag is passed), whatever we ultimately settle on [13:55:31.0915] i think we probably should not have allowed this case at all, in either order. declare your thing explicitly and then export/return/etc it [13:59:44.0548] > <@bakkot:matrix.org> do people in the decorator-before-export camp think that decorators should also come before the `return` when you're returning a class? as in > > ``` > @dec > return class {} > ``` Certainly not. There is a clear semantic difference between `export` (which has non-local effects that occur before evaluation) and `return` (which does not). [14:00:38.0778] > <@devsnek:matrix.org> i think we probably should not have allowed this case at all, in either order. declare your thing explicitly and then export/return/etc it lol that is a previously unmentioned fourth option, i guess [14:01:03.0401] IIRC, that was mentioned at one point. [14:01:27.0063] this feels like a garbage in garbage out sort of situation, trying to create meaning from chaos [14:02:01.0469] did typescript actually ship the new decorator impl at this point [14:04:00.0339] We talked about the `return` thing back in 2018 as well: https://github.com/tc39/proposal-decorators/issues/69#issuecomment-429202746 [14:04:30.0119] In our 5.0 beta, yes, but there are a few moving pieces still that we're trying to resolve this meeting. [14:05:04.0492] > <@ljharb:matrix.org> lol that is a previously unmentioned fourth option, i guess Mentioned here: https://github.com/tc39/proposal-decorators/issues/69#issuecomment-429490497 [14:10:06.0172] maybe we can yeet this before anyone starts writing code with it 😄 [14:11:07.0017] i mean that's actually reasonable in that it would leave the question open and remove any time crunch [14:11:45.0151] but it would still cause all the same churn that the TS folks don't want [14:17:19.0748] i will need to read through those threads to understand why we want to allow it in the first place [14:36:21.0611] it doesn't seem like any super strong motivation for this was given lol [14:43:05.0656] if i'm not around tomorrow during the discussion can someone mention just not allowing this at all [14:54:23.0637] > <@devsnek:matrix.org> if i'm not around tomorrow during the discussion can someone mention just not allowing this at all Can you clarify what you mean by "this" in both of the two comments above? Not allowing this change? Not allowing decorators+export in either order? [14:54:41.0100] the latter [14:55:18.0922] I'm sure someone will bring it up, but it certainly doesn't solve our motivation for bringing this back to plenary. [14:55:43.0811] I wasn't able to find motivation for why we want it in the first place, so it seems a lot simpler to cut it out entirely [14:56:06.0864] well I found one comment from Waldemar that seemed against not having it at all [14:56:23.0134] but it didn't include a reason [14:56:26.0646] Not being to decorate an exported class all at once isn't a great developer experience, especially if you compare this to similar capabilities in other languages. [14:57:13.0403] you can export it, you just have to use the separate export declaration [15:02:33.0629] While it isn't an outcome I'd prefer, that was an outcome I suggested since it would allow us to break out this concern from the main proposal and pursue it separately. It would still require a code mod, unfortunately, but that impact might be somewhat lessened by the fact there are many TS projects that can't switch to native decorators due to the lack of parameter decorators (which I plan to propose as a follow up this year), the inability to decorate an entangled pair of `get`/`set` methods (which would be solved by the Grouped and Auto-Accessors proposal), or the inability to register a static extra initializer from a non-static member. Its possible we could resolve this separately by the time those proposals reach Stage 3 and potentially avoid a code mod as well if the ordering is consistent. [15:03:43.0650] personally I don't think it should even be pursued as a followon but at the very least it seems like giving more time is reasonable [15:03:56.0934] 🤷‍♂️ smth for committee to discuss I guess [15:22:55.0885] I think it is important to allow decorated classes to be exported… our language features should generally compose 2023-02-02 [17:25:42.0237] erights: During plenary you asked if there was anything outside of `export`/`export default` that would make the `Function.prototype.toString` of a class non-`eval`-able given sufficient context for identifiers. I said no, but there is, to a degree. Any computed property name can contain `await` or `yield`, making it non-`eval`-able by default without having to wrap the string in something like an `"async function * () { ... }"` first. The context _outside_ of the `eval` itself is not sufficient to support `await` and `yield` on their own. While this is unlikely to occur regularly, it is perfectly legal JS. [20:53:55.0346] > <@ljharb:matrix.org> lol that is a previously unmentioned fourth option, i guess This option was discussed in 2018, and I think it's not a good option because it just make the situation worse. [21:01:15.0331] > <@bakkot:matrix.org> do people in the decorator-before-export camp think that decorators should also come before the `return` when you're returning a class? as in > > ``` > @dec > return class {} > ``` see https://github.com/tc39/proposal-decorators/issues/69#issuecomment-409474841 [06:34:50.0990] Good morning, all. Plenary begins in 26 minutes time. [06:35:31.0403] Please be aware that Import Assertions continuation is scheduled in the first (AM) slot (the final 60min) [07:06:25.0946] Have we started? [07:07:02.0255] HE Shi-Jun: yes [07:07:17.0563] I hear nothing... weird [07:07:32.0534] jitsi has some bugs... [07:08:02.0416] oh, so what can i do ? reconnect? [07:09:26.0791] yes, please refresh if you don't hear anything [07:09:29.0857] reconnect and now I see the screen. [07:09:32.0113] please wipe your browser site cache and restart the browser [07:13:27.0294] Note, we can reuse the WHATWG infra spec (or copy it) for this editorial issue [07:13:45.0011] I agree with avoiding actual Maps (since it is annoying to check whether this leaks) [07:14:57.0141] infra spec is a little bit up in the air on this particular thing at the moment https://github.com/whatwg/infra/pull/451 [07:15:02.0561] might be fixed by the time it's relevant [07:17:08.0364] 1. the `n`th run script should be able to virtualise the `n+1`th script (and all later scripts) 2. the `n`th run script should be able to make itself safe from modifications made by the `n+1`th script (and all later scripts) [07:17:27.0069] this design is consistent with those goals [07:20:49.0423] love how the notetakers have so little to correct that we're just falling over each other to put the names in [07:23:31.0895] Justin Ridgewell: we don't want to add the hidden intrinsics to the global because almost nobody cares about them and they just add clutter [07:23:51.0295] But they can be lazy loaded [07:24:08.0707] bakkot: WDYT my concrete alternative if you also do something similar? [07:24:12.0356] This trades lazy loading for eager, seems like he'll shoot himself in the foot to get this? [07:24:12.0920] we talked about that with some of the new hidden intrinsics in iterator-helpers and the whole committee wanted to not add them [07:24:22.0350] Michael Ficarra: i like justin's suggestion actually [07:24:32.0276] that means the only thing we need to add here is just the string iterator for all intrinsics [07:24:47.0610] like we gotta put them _somewhere_ if we agree to this use case [07:25:24.0918] shu: you pull them out of the `getIntrinsic` function [07:25:26.0567] my use case needs a direct way to access one, not an iterator for all of them - the retrieval use case [07:25:40.0699] * my use case needs a direct way to access one, not an iterator for all of them - the retrieval use case [07:26:12.0559] Please add your name, abbreviation and member organization to today's minutes. [07:26:20.0699] Michael Ficarra: i'm saying i do not want the getIntrinsic function [07:26:25.0181] only a getHiddenIntrinsic function [07:26:43.0817] memory overhead of implementing `getIntrinsic` remains something v8 does not want [07:29:31.0981] it makes it easier for us because, instead of grabbing a few dozen references up front (and having to know which refs to grab), we just grab the one [07:30:11.0103] i don't think that clears the bar for adding to the language given other constraints [07:30:23.0372] that is, the niche use case thing [07:30:42.0388] but the hidden intrinsic use case thing sounds like an missing capability for the robustness people want [07:30:49.0074] * but the hidden intrinsic use case thing sounds like an missing capability for the robustness people want [07:31:28.0162] Sorry, what is the difference between `getIntrinsic` and just doing `globalThis.previouslyHiddenIntrinsic.prototype.foo`? [07:31:51.0214] You would have to grab 0 references if we add to the global, right? [07:31:56.0472] Just get it when you need it [07:32:12.0469] Justin Ridgewell: no, because someone who has run after us may have replaced those [07:32:14.0785] And the behavior would be the same as accessing via `getInrinsic('class.prototype.foo')`? [07:32:29.0705] But `getIntrinsic` can't return the original [07:32:56.0358] `getIntrinsic` would return the original unless it itself had been patched, that's the point of it [07:33:05.0365] * `getIntrinsic` would return the original unless it itself had been patched, that's the point of it [07:33:07.0175] Yes, which was my point [07:33:19.0941] what was your point then? [07:33:34.0817] Either the property has been modified and both `getInrinsic` and `foo.bar.baz` wouldn't get the original, or it's not modified and both would get the original [07:33:50.0116] What's the point of `getInrinsic` if we add hidden intrinsics to the global? [07:33:56.0542] I don't understand what's added [07:33:59.0194] if we have run first, we also have a reference to the "unmodified" `getIntrinsic` [07:34:01.0845] the scenario is: - we run, and cache `getIntrinsic` - some else runs, and messes with the environment - we run again, and need some original thing, which we get from our cached `getIntrinsic` [07:34:09.0586] * the scenario is: - we run, and cache `getIntrinsic` - some else runs, and messes with the environment - we run again, and need some original thing, which we get from our cached `getIntrinsic` [07:34:26.0756] right now, we have to cache everything we'll ever need in the first part [07:34:27.0114] But getIntrinsic can't get a modified value? [07:34:29.0707] which is surprisingly tricky [07:34:41.0171] what does "can't get a modified value" mean? [07:34:43.0290] Justin Ridgewell: I don't know what that means [07:34:44.0818] you don't *want* it to get a modified value [07:34:46.0216] and, just to reiterate -- you would want to be able to patch the cached values? is that right? [07:34:47.0518] question: where is the link of current slide? [07:34:50.0766] or you would be patching the globals [07:35:13.0910] yulia: both patching the globals and patching the `getIntrinsic` function [07:35:28.0214] We do also patch sometimes but that's both trickier and not always necessary [07:35:43.0343] there are a lot fewer things that we need to patch than there are things that we need to _work_ [07:35:53.0327] right so you want to control all access to for example Array.prototype.map [07:35:54.0996] yeah the things we patch is a much smaller set than the things we cache for protection [07:36:01.0965] > <@michaelficarra:matrix.org> Justin Ridgewell: I don't know what that means `Class.prototype.bar = null`, then `getInrinsic('class.prototype.bar')` can't return the original bar value [07:36:04.0892] That's what I mean [07:36:23.0002] Well then what is the difference between just doing `Class.porototype.bar` when you need the value later? [07:36:28.0762] Justin Ridgewell: why? [07:36:39.0900] > <@michaelficarra:matrix.org> yeah the things we patch is a much smaller set than the things we cache for protection would it be useful to have absolute access to a builtin [07:36:40.0298] Justin Ridgewell: it could have been written to by someone else [07:36:45.0093] Because that's the semantics that Jordan outlined today?! [07:36:47.0760] yulia: like, for example, we had an annoying bug recently when some of our late-running code broke in a particular environment because the page had replaced the Response constructor with a version which was not spec-compliant [07:36:57.0211] we don't need to replace it [07:37:03.0379] but we do need to have the original one [07:37:11.0824] right -- thats our use case, we always want the original [07:37:16.0335] never the patched one [07:37:16.0640] > <@yulia:mozilla.org> would it be useful to have absolute access to a builtin if you mean undeniable access, no, in fact that would be very harmful [07:37:28.0329] right, thats what i expected [07:37:30.0810] (because we do patch some things) [07:37:51.0562] so if users start using an undeniable access to array then the things that you do patch would be at risk [07:37:51.0599] > <@yulia:mozilla.org> would it be useful to have absolute access to a builtin "absolute" meaning "undeniable for later code on the page"? no, that needs to be impossible [07:38:11.0727] right, undeniable access for later-running code is a non-starter [07:39:02.0636] > <@jridgewell:matrix.org> Well then what is the difference between just doing `Class.porototype.bar` when you need the value later? in our case, the early-running doesn't always know what values we'll need later [07:39:17.0994] also, the size of the early-running code is more sensitive [07:39:23.0468] (since it needs to be loaded sync, during page load) [07:39:23.0577] I understand that, you call `getInrinsic('foo')` later on [07:39:27.0699] and just thinking out loud: the cached access would be for your code internally, not for the code that is used outside [07:39:46.0204] If the `Reflect` object was _actually_ about reflection, `Reflect.getIntrinsic()` would be a much better place than the global, IMO. I'd also prefer to see a `getIntrinsicNames()` function so as not to overload the return value of `getIntrinsic()`. [07:39:48.0015] so we have two halves here: what you use internally, and what is used by other code externally that you want to patch (to make sure i have it right) [07:40:33.0166] yulia: yes, and sometimes those sets overlap [07:40:53.0440] yulia: right. the patching one isn't solved by this, but is also a much trickier thing to solve, I think [07:41:05.0118] would they have access or knowledge of your cached getIntrinsic? because part of the risk is that getIntrinsic itself can be patched by later code right? [07:41:28.0832] any code which does patching will also need to patch `getIntrinsic` going forward, yes [07:41:43.0451] we have an in-house library for patching which has actually arrived at a pretty decent model; maybe we should propose adding it to the platform some time [07:42:22.0408] i do think that this is a weird area right now, i just don't know exactly how to solve it because there are a few overlapping areas here [07:42:45.0854] i kind of like shu's suggestion, because then you don't have two but it opens hidden intrinsics [07:42:55.0756] I think they're probably separable problems yulia [07:43:28.0258] i'm not contesting that [07:43:59.0993] shu's solution does very little for us in particular because we're not currently doing the "traverse the whole global" thing for performance reasons, though it would be good for JHD and SES I guess [07:44:22.0067] bakkot: but you've also contended that your use case is niche enough that it doesn't need to be in the language IIRC? [07:44:34.0109] well, I would not champion this just for me [07:44:40.0069] I'm just saying if we add this I would definitely use it [07:45:02.0174] and it would eliminate... maybe 50% of the bug reports we get [07:45:20.0786] Did we reach the end of the slides? [07:45:21.0311] i don't really understand [07:45:31.0004] why don't you traverse the global and get rid of 50% of the bug reports? [07:45:36.0358] like the alternative i suggested is functionally equivalent [07:45:40.0678] because that's too slow to do during page load [07:45:42.0384] shu: I don't think it's really that the use case is niche, just that it's currently very inconvenient today to be safe, so people decide to take the easier development and smaller file size trade-off [07:45:46.0862] except you're caching in user space instead of on every context [07:46:04.0267] so... the hypothesis is if you externalize that cost during snapshot creation for v8 that's okay [07:46:07.0075] * because that's too slow to do during page load [07:46:13.0354] * so... the hypothesis is if you externalize that cost during snapshot creation for v8 that's okay [07:46:18.0263] that's the idea! [07:46:21.0738] okay [07:46:22.0967] nty [07:46:31.0763] what i am getting lost on is what the advantage is here -- now you will patch in two places, and everyone who wants to patch will do so in two places. So you still need to run first, in any case [07:46:59.0707] right, we will always need to run first [07:47:08.0648] i know that this is a different use case but its impacted by this api [07:47:14.0017] yulia: https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$Pcs3JQA_VGGAUGQTC_tbJdbIdfADtHrhsW_y7VjanW0?via=matrix.org&via=igalia.com&via=mozilla.org [07:47:55.0867] right now, our first-run code needs to know up front all of the things we will ever need, and cache them. this is both difficult to do and increases the cost of our first-run code, which is performance sensitive because it's running synchronously during page load. [07:47:55.0900] so now you will cache by running first, but it feels like its almost an issue with layering where you want to be able to cascade definitions. don't know if that makes sense [07:48:29.0240] yulia: I don't understand [07:48:33.0406] > <@michaelficarra:matrix.org> yulia: https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$Pcs3JQA_VGGAUGQTC_tbJdbIdfADtHrhsW_y7VjanW0?via=matrix.org&via=igalia.com&via=mozilla.org sorry the matrix chat isn't clear on what is highlighted here. that adding hidden intrinsics to the global is clutter, is that right? [07:48:49.0451] i wasn't thinking of adding it to the global honestly i was thinking of shu's suggestion of a limited subset of apis [07:48:57.0348] yulia: no, this: [07:49:06.0761] too bad, i can't see the slide (seems network is so bad) [07:49:13.0774] yulia: it's the little green line on the left [07:49:21.0854] I see [07:49:32.0443] this is the caching case [07:49:38.0078] yes i agree there [07:49:41.0466] I'm not seeing the slides, should I restart Jitsi? [07:49:48.0376] I can't see them either now [07:49:52.0954] I just restarted and did not see them [07:49:58.0667] I think the problem is on jordan's end [07:50:01.0809] I restarted but still can't see [07:51:07.0134] I can see the slide now :) [07:51:18.0862] I think it was the "toggle tile view" at the bottom [07:56:26.0931] We need a namespace for reflection api which not relate to Proxy :) [07:56:36.0922] The Reflect/Proxy trap correspondence was always sort of accidental/not the original intention, according to Dave Herman [07:56:52.0053] I also like the idea of using the Reflect namespace [07:57:00.0575] maybe `Introspect` ? [07:57:04.0005] it's a great way to move forward with stratificaiton, as Shu's saying! [07:57:25.0496] > <@littledan:matrix.org> it's a great way to move forward with stratificaiton, as Shu's saying! yeah, that paper is great! [07:58:23.0451] If we do allow more than just proxy traps on `Reflect`, I'm more than happy for us to be very selective about what we add to it. It's just a waste to leave it so limited. [07:58:37.0057] * If we do allow more than just proxy traps on `Reflect`, I'm more than happy for us to be very selective about what we add to it. It's just a waste to leave it so limited. [07:59:24.0101] For Node's memory concerns with eagerly grabbing intrinsics, isn't this just pushing the concern into V8 itself? [08:00:06.0989] If V8 has to maintain the pointers to all of these intrinsic values for later retrieval, all those pointers still have to be maintained, just now by V8 [08:00:20.0438] Justin Ridgewell: that's exactly the tradeoff [08:00:27.0070] and what i said above, and bakkot confirmed [08:00:36.0353] that's not a tradeoff i want to make for _all_ webpages [08:00:41.0538] and thus my alternative of just doing the hidden intrinsics [08:00:52.0129] and continue to leave the burden of caching to userland programs that need the robustness, which is rare [08:01:13.0180] Ahh: https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$sHbpRAAb_qOusauVcfykPlOq9v1AMmPraH4FXwNhico?via=matrix.org&via=igalia.com&via=mozilla.org [08:01:21.0567] man matrix copy/paste sucks [08:01:26.0103] Sorry, still trying to make breakfast so I'm missing a lot of the conversation [08:03:59.0472] the iterator method is only for the cache-the-world use case as far as I'm aware; we would have no use for it [08:05:11.0513] i have to drop for 30 minutes for mtg [08:05:24.0164] sorry, i need to be here for import assertions but i gotta drop [08:05:40.0950] well, that is really too bad.... we could've shifted this around [08:05:45.0409] we still maybe can [08:24:38.0947] > <@jridgewell:matrix.org> Ahh: https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$sHbpRAAb_qOusauVcfykPlOq9v1AMmPraH4FXwNhico?via=matrix.org&via=igalia.com&via=mozilla.org im a little late to this, but this is likely a problem for us because our builtins are lazily constructed [08:28:43.0439] I absolutely do not buy the argument that developers are going to start relying on something because it is stage 3 without trying it out in any browser [08:29:08.0029] chrome is currently shipping [08:29:12.0461] They can try it in Chrome [08:29:15.0475] > <@michaelficarra:matrix.org> I absolutely do not buy the argument that developers are going to start relying on something because it is stage 3 without trying it out in any browser * They can try it in Chrome [08:29:16.0699] so for both firefox and safari this is an issue [08:29:19.0607] Isn't this the "stage 3 shipability" discussion we had? [08:29:29.0561] and puts pressure on us to ship our currently flagged versions [08:29:59.0077] ah I forgot about Chrome shipping [08:32:09.0086] Justin Ridgewell: eslint doesn't support anything til stage 4, do you mean like plugins and parsers? [08:32:16.0414] * Justin Ridgewell: eslint doesn't support anything til stage 4, do you mean like plugins and parsers? [08:32:33.0791] i am back [08:33:26.0400] There are other parsers for eslint [08:33:33.0157] I'm somewhat surprised that the ecosystem has been built around a stage 3 proposal. [08:33:59.0353] that's what stage 3 means to the ecosystem - time to ship it and rely on it [08:34:13.0408] which is a big part of why it's a critical signal to send here by dropping it to stage 2 [08:34:30.0426] i don't think the likelihood of the syntax changing is affected, at all, by which stage the proposal is at. [08:44:24.0269] We definitely have to relax the restriction, so the real questions are whether we should change the syntax to match the new semantics, and whether the need to investigate such a change over a period longer than a single plenary session is an indicator that we should demote the proposal to Stage 2? [09:02:58.0453] is Guy cutting in and out for others? [09:03:08.0032] yes [09:03:10.0036] i can't understand really [09:03:10.0571] Yes [09:03:21.0574] yeah i think ron has a good summary of where we want to go. when i brought up having consensus on the loosening -- it wasn't to scope the discussion at stage 2. it seemed like it was what we were agreeing upon and making it explicit would move us forward [09:06:00.0139] by what i'm hearing now i'm fine with the space we're at now, did i miss anything substantive in the first 30 minutes of this item? [09:07:09.0819] I think most of the first 30 minutes was about contemplating the different routes from a process perspective and defining a scope and timeline for the changes. I don't think you missed much if you're up to speed now. [09:07:38.0776] okay [09:07:49.0473] and it is fully clear to all parties that chrome is not unshipping during stage 2 demotion [09:07:51.0286] ? [09:08:00.0125] yep, that was mentioned a few times, here and in plenary [09:08:04.0263] * yep, that was mentioned a few times, here and in plenary [09:08:13.0994] okay, thanks [09:08:38.0481] Didn't Chrome initially ship when this was stage 2? [09:09:16.0265] most definitely not [09:09:26.0509] we don't ship any JS proposals during stage 2 [09:09:35.0480] When did Chrome ship? [09:09:40.0724] during stage 3, May 2021 [09:10:35.0633] * during stage 3, May 2021, version 91 [09:10:52.0763] Thank you, ljharb and everyone else, for being so constructive in this discussion [09:59:45.0339] We overran earlier so we will be starting at 5 mins past the hour (so 5 minutes time) [10:00:40.0709] I'm done for the day, y'all. good luck with the rest of the agenda [10:00:46.0869] iain is here for your mozilla concerns tho [10:01:03.0733] Thanks for your support Yulia throughout the past days - it is appreciated. [10:25:42.0330] PSA: You can also say "element" to refer to a field or method in a class [10:26:10.0327] is that a well-known term? [10:26:16.0643] yes, it's used in the syntax [10:26:24.0882] i don't think the latter implies the former [10:26:37.0760] i'd guess it's intuitive but not well-known [10:26:47.0336] I've rarely heard that word used that way [10:27:30.0092] I am pretty sure the term was used in my OO classes back in school, but I don't know how common that is [10:27:34.0747] I've just been told it'd be good to avoid the word combination "private member" and "element" is right there in spec jargon [10:28:04.0152] it makes perfect sense to me in this context, to be clear, i just don't think it's caught on much yet [10:28:11.0152] * it makes perfect sense to me in this context, to be clear, i just don't think it's caught on much yet [10:28:17.0809] (I've also switched from saying "hard private" to "strong encapsulation") [10:28:26.0757] yeah, same, but I guess we could all start using it like that and it could catch on [10:28:32.0869] should it go in the how-we-work glossary? [10:34:57.0922] ryzokuken: how are we doing on the timebox? [10:35:11.0749] it runs until 39-40 [10:35:21.0810] so at most five more minutes [10:37:02.0951] who is the Chris that Ron is referring to? [10:37:51.0744] pzuraq [10:38:10.0790] 👋 [10:38:40.0558] I'm in another meeting at the moment, will be hopping back in the plenary in a sec [10:38:47.0446] * I'm in another meeting at the moment, will be hopping back in the plenary in a sec [10:39:06.0813] (Chris Garrett) [10:39:14.0135] thx [10:39:16.0521] (I should fix up the notes from yesterday) [10:51:52.0741] ptomato: please add a conclusion to the last topic in the notes [10:52:46.0391] I totally agree, `.toString()` as a big piece of motivation here is a bit bizarre [10:52:55.0592] littledan: Do you have a writeup of your ideas for improving decorator performance that I can point people at? [10:53:29.0164] iain: Oh should we consider this issue still open? I mean, I really think those sorts of things wouldn't increase performance much in practice. [10:53:40.0298] If we should consider them open, we should discourage TS from shipping [10:53:43.0282] (no, I don't have a writeup) [10:55:01.0849] My personal take is that performance is currently probably fine, but I would like to run your suggestions past the person who's actually doing the implementation [10:55:22.0445] I can point him at the notes if necessary [10:55:24.0402] the two things were, 1) make a token that you have to use at the declaration site to permit addInitializer [this got very strongly negative ergonomic feedback, and V8 at the time told us it wasn't necessary, though they haven't started implementing yet] 2) use a class instance instead of an object with closures for the get/set/has getters [last time we discussed that, there were some complicated requirements that Justin Ridgewell asked for, and I thought it'd be simpler to just use things this way] [10:55:32.0208] is this dminor? [10:55:35.0720] Yeah [10:55:42.0525] dminor: ^ [10:56:19.0843] Yeah, so, dminor if you want either of those changes, please raise an issue in the repo ASAP [10:56:32.0106] Sorry, what did I ask for? [10:56:51.0367] remember in the old stage 2 decorators, when they had a class representing the private name, and you said it had to be a frozen class? [10:57:03.0672] making it a fresh object (as iain noted) was a way through without all that frozen class complexity [10:57:17.0683] Ohh, yah, the reified private instance needed own properties and not prototype methods [10:57:28.0400] Because otherwise you could intercept any reified private field [10:57:32.0631] well, no, they were on the prototype but everything was frozen [10:57:48.0719] anyway this was not for MM-style integrity but for some other practical integrity notion (where SES isn't used) [10:58:01.0293] I think that was Domenic's suggestion, but it solved my concern either way [10:58:18.0337] yeah I also disprefer instance methods [10:58:30.0258] anyway that's why I stepped back and suggested what we have now [10:59:57.0564] so this is that exact thing, where implementers realize, "oh, I see, now I have to do four fresh allocations per decorator invocation" (but I expect that's not going to be a bottleneck since its' not per instance) [11:01:55.0936] since angular won't be migrating, what's the scale of usage of legacy decorators *excluding* angular codebases? [11:02:03.0861] i would assume drastically smaller [11:02:42.0245] https://github.com/nestjs/nest also uses legacy decorators [11:03:34.0101] > <@bakkot:matrix.org> https://github.com/nestjs/nest also uses legacy decorators Yeah, I imagine this sort of use case is why Bun felt like turning on TS legacy decorators by default (!) [11:04:16.0506] > <@ljharb:matrix.org> since angular won't be migrating, what's the scale of usage of legacy decorators *excluding* angular codebases? I think it's premature to say what Angular will do... it's a very actively maintained framework [11:04:48.0010] idk that's just what i heard from angular people [11:04:54.0456] they didn't want to update their videos [11:05:00.0060] sorry, not just heard, that's what they told me [11:06:00.0577] ah OK I misunderstood [11:06:41.0782] I believe they've said they are not going to migrate in the absence of parameter decorators, which... uh, I am not going to say they will never happen, but if we were doing a temperature check on parameter decorators I would feel the need for a button to the right of "unconvinced" [11:06:55.0837] > <@bakkot:matrix.org> I believe they've said they are not going to migrate in the absence of parameter decorators, which... uh, I am not going to say they will never happen, but if we were doing a temperature check on parameter decorators I would feel the need for a button to the right of "unconvinced" Ah this makes more sense! [11:07:23.0682] yes that too, they want that dependency injection [11:07:50.0006] we would expect libraries to ship these hybrid-decorator functions - especially in older versions to help with migrating [11:07:51.0854] does nest rely on parameter decorators? [11:07:57.0811] we always said function and parameter decorators would come in a future phase, we just didn't expect class decorators to take so long [11:08:15.0857] * we always said function and parameter decorators would come in a future phase, we just didn't expect class decorators to take so long [11:08:21.0896] * we would expect libraries to ship these hybrid-decorator functions - especially in older versions to help with migrating [11:08:28.0103] > <@ljharb:matrix.org> does nest rely on parameter decorators? I don't want to speak to "rely on" but they do use them [11:08:42.0294] ok - what's the likelihood they'd migrate before angular then? [11:08:56.0431] nest I think is younger and consequently more willing to make breaking changes [11:08:59.0405] but again, that's a question for them [11:09:04.0178] gotcha [11:09:10.0045] > <@bakkot:matrix.org> I believe they've said they are not going to migrate in the absence of parameter decorators, which... uh, I am not going to say they will never happen, but if we were doing a temperature check on parameter decorators I would feel the need for a button to the right of "unconvinced" i'm, like, super unconvinced of parameter decorators [11:09:53.0742] why? [11:10:24.0365] they are not something i want to attach user-programmed logic to in any programming language [11:10:32.0182] and i think dependency injection is not a compelling use case [11:10:35.0679] perhaps there are other use cases [11:10:59.0732] > <@shuyuguo:matrix.org> perhaps there are other use cases I need to come back to this, but there are, yes. [11:11:38.0893] I wonder if dependency injection in particular could be accomplished by... custom pattern matching handlers [11:11:49.0163] > <@rbuckton:matrix.org> I need to come back to this, but there are, yes. FYI, Angular v1 did parameter injection by using the `Function.prototype.toString` of the constructor, which was terrible. [11:12:37.0908] two reasons for me: 1) the only use case I have heard for them are dependency injection, and I think the style of dependency injection which relies on parameter decorators introduces an entirely new calling convention to languages where the calling convention is driven by user code, which IME makes code much harder to maintain; consequently every time someone says "we should have this for DI" I am more convinced we should _not_ do it, not less 2) unlike "methods" and "classes", parameters are not a _thing_ - the only reason method decorators are necessary is because there's no practical way to run a function while attaching the thing-which-is-a-method to a class, but there _is no_ thing-which-is-a-parameter getting attached to anything [11:12:43.0665] also FWIW Ember does dependency injection with field decorators, fitting into the pattern established here [11:12:58.0129] and the usage of that seems a lot cleaner to me! [11:13:19.0492] very happy to let kevin do the arguing for me! [11:13:38.0371] also I'm going to have to drop off this meeting early, later all. my opinion on the `export @dec` topic is, I like the ES syntax better but am not so set on it that I want to fight about it more; the main outcome I would like to see is TS not shipping unflagged support for non-standard syntax [11:13:49.0133] Parameter decorators are also useful for RRTI (runtime type information) and RTTA (runtime type assertions), as well as defining argument handling for routing (HTTP web apis, page routing in react) [11:14:01.0052] if that's achieved by changing the ES syntax I'm fine with it [11:15:41.0229] Could someone write down the definition of "Option 3" here so we all know what it means. [11:15:55.0014] option 3 is "status quo" - which is, "decorators must come after export" [11:16:05.0334] * option 3 is "status quo" - which is, "decorators must come after export" [11:18:44.0796] > <@rbuckton:matrix.org> Parameter decorators are also useful for RRTI (runtime type information) and RTTA (runtime type assertions), as well as defining argument handling for routing (HTTP web apis, page routing in react) I think pattern matching would be a good fit for runtime type assertions [11:19:24.0919] I agree, but as i said those aren't the only cases. there are more but i'll follow up after plenary [11:21:42.0774] wait i'm confused by what daniel is saying [11:21:53.0887] why would people who like the stage 3 ordering make issues saying they like it? [11:22:34.0777] i think he's saying that even before this decision was made, nobody's been pushing for decorators-after [11:22:39.0710] > <@shuyuguo:matrix.org> why would people who like the stage 3 ordering make issues saying they like it? no he is saying, no one disagrees with TS's syntax [11:22:57.0184] altho that doesn't mean that, absent legacy usage, they'd disagree with the current ES syntax [11:23:02.0217] but that's not the opposite of disagreeing with the stage 3 syntax [11:23:08.0381] maybe people don't care either way? [11:23:40.0469] Nobody has come to TypeScript and said "this is bad, the stage 2/3 proposals are clearly heading in a better direction" with decorator ordering [11:23:46.0563] > <@shuyuguo:matrix.org> why would people who like the stage 3 ordering make issues saying they like it? * Nobody has come to TypeScript and said "this is bad, the stage 2/3 proposals are clearly heading in a better direction" with decorator-before [11:23:51.0554] sure but that's because TS hasn't shipped it yet [11:23:58.0969] We run the risk that we are picking winners and losers. [11:24:02.0035] most people don't even know that "proposals" or "stages" are a thing [11:24:11.0037] * Nobody has come to TypeScript and said "this is bad, the stage 2/3 proposals are clearly heading in a better direction" with decorator ordering [11:24:24.0004] danielrosenwasser: but... why is that evidence for preference for one way or the other? [11:24:26.0778] I think its more to the point that, in the years since "decorators after `export`" was decided, the only feedback we received about changing the ordering prior to 5.0 was due to a Babel misconfiguration. [11:24:29.0738] > <@shuyuguo:matrix.org> maybe people don't care either way? No, they care. check #69 u will see almost all heavy TS/decorator users prefer before. [11:24:30.0432] danielrosenwasser: it's also evidence for lack of preference, no? [11:24:46.0831] #69 on what repo? [11:24:58.0081] https://github.com/tc39/proposal-decorators/issues/69 [11:24:59.0016] on decorator repo [11:24:59.0133] https://github.com/tc39/proposal-decorators/issues/69 [11:25:08.0235] The fact that people want an ordering option for Babel, but not for TypeScript, feels like evidence [11:25:44.0981] > <@danielrosenwasser:matrix.org> The fact that people want an ordering option for Babel, but not for TypeScript, feels like evidence agree, that feels like evidence to me [11:25:54.0775] But if your perspective is that that's "no preference", then it seems like either option I'm presenting here seem like reasonable directions [11:26:14.0970] i was saying the "we got 350k issues but stage 3 ordering ain't but 1" didn't seem like evidence for the opposite direction to me [11:26:34.0072] 35k, thankfully not 350k :D [11:26:50.0010] > <@danielrosenwasser:matrix.org> But if your perspective is that that's "no preference", then it seems like either option I'm presenting here seem like reasonable directions yes, i am fine with either option personally [11:27:04.0984] I find this comment is especially useful to explain why we get stage 3 with the syntax which most decorator users don't like: https://github.com/tc39/proposal-decorators/issues/69#issuecomment-1411460427 [11:27:29.0611] quote: "it seems superficially the people in this thread the most reliant on decorators are mostly in favour of before, but also have the highest stakes in keeping the proposal moving forward, giving 'before' up in the bargain" [11:28:59.0690] > <@danielrosenwasser:matrix.org> The fact that people want an ordering option for Babel, but not for TypeScript, feels like evidence History about that option: when we first implemented "non legacy" decorator, the order was still up in the air. There has been _some_ discussion, but not a huge demand. The reason we have then given a default value to the option is that the proposal settled on decorators after export, but it was more out of inertia because no one wanted to continue that discussion (the decorators proposal has been really good at burning out people, me included) [11:29:15.0849] I don't think this is the kind of situation where we need to position someone as the lone objector to option 1; we've heard from lots of people in committee today that they oppose option 1 [11:29:31.0576] that said, I'd be happy with option 1 [11:29:49.0702] i'm happy with option 1 but let's hear from waldemar and did mark also object? [11:30:01.0399] well, not object, but voice anti-support previously [11:30:08.0632] "syntax must reflect semantics" IIRC [11:30:19.0556] Yeah let's call on Mark and Waldemar [11:30:28.0065] I don't think "people have objected to this in the past" is a valid reason to block [11:31:15.0040] no, but the reasons they (and i) objected in the past remain [11:31:18.0417] * no, but the reasons they (and i) objected in the past remain [11:31:33.0093] what is Option 3 btw? [11:31:39.0201] status quo [11:31:39.0975] > <@ljharb:matrix.org> no, but the reasons they (and i) objected in the past remain OK let's focus on those rather than the meta thing [11:31:59.0672] focusing on those is the "mental model" discussion which is what led to all the debates years ago [11:32:05.0013] and i really don't want to reignite those debates [11:33:04.0977] > <@wmartins:matrix.org> what is Option 3 btw? danielrosenwasser or rbuckton if any of you can edit the slides right now to add "option 3: status quo", since we are asking for consensus now, it would be good. Multiple people are confused by mentions to "option 3", including me earlier 😅 [11:38:03.0936] I'm sympathetic with ljharb's explanation for why option 2 is more "composable" than option 1--that you should be able to plop `export` on the beginning of any declaration [11:38:17.0687] (but that shouldn't force us to option 3) [11:38:49.0567] agreed [11:38:51.0143] so what does `@dec1 export @dec2 class {}` mean? syntax error? [11:39:00.0146] oof, i'd hope so [11:39:01.0505] IMO it's fine, they just apply in order [11:39:07.0478] o ok [11:39:08.0665] lol i guess that's an option too [11:39:08.0763] sick [11:39:20.0340] I know that temperature checks should be planned, but I would really like one now just to decide which option to procede with asking consensus on. I fear that no one would block the first thing we ask consensus on, even if the second one would make more people happy [11:39:22.0551] > <@shuyuguo:matrix.org> so what does `@dec1 export @dec2 class {}` mean? syntax error? What's what we mean by preference for exclusive-or. [11:39:47.0432] * I know that temperature checks should be planned, but I would really like one now just to decide which option to procede with asking consensus on. I fear that no one would block the first thing we ask consensus on, even if the second one would make more people happy [11:39:53.0067] Chris's reference to "the dress" is a picture when human eyes perceive the same image to be blue or gold. And both are correct. [11:40:19.0406] i think this is a case of "both are correct" but i'm not sure the dress is given one can sample pixel color values ;-) [11:40:23.0762] > <@robpalme:matrix.org> Chris's reference to "the dress" is a picture when human eyes perceive the same image to be blue or gold. And both are correct. How I see that picture has changed over time! [11:40:28.0588] > so what does `@dec1 export @dec2 class {}` mean? syntax error? That makes me more sympathetic with option 3 [11:40:55.0697] the fact that it is a syntax error makes you more sympathetic? [11:40:56.0378] > <@wmartins:matrix.org> > so what does `@dec1 export @dec2 class {}` mean? syntax error? > > That makes me more sympathetic with option 3 You don't like neither "allowed" not "syntax error"? [11:41:15.0212] > <@wmartins:matrix.org> > so what does `@dec1 export @dec2 class {}` mean? syntax error? > > That makes me more sympathetic with option 3 If we choose Option 2, I would be strongly in favor of disallowing them in both positions on the same declaration [11:41:26.0894] who is William? they don't have an initialism [11:41:32.0598] Syntax error sound like a good compromising. [11:41:43.0891] Michael Ficarra: it's Willian Martins [11:41:55.0204] oh my bad, I misspelled [11:42:37.0668] oh man i was hoping for the high chaos option for applying in order [11:42:47.0072] i liked dan's answer there [11:43:00.0344] Hi I'm one of Netflix delegates. I'm mostly silent that is why you might not met me before. [11:44:04.0256] Which one? The one I stole from Curb Your Enthusiasm? [11:44:29.0280] IMO it's fine for the `export` keyword to be in the toString [11:44:33.0989] I just don't think this matters very much [11:44:55.0469] > <@danielrosenwasser:matrix.org> Which one? The one I stole from Curb Your Enthusiasm? no, the one from littledan saying if you have a decorator in both positions it just applies them in-order [11:44:56.0598] but also cutting off the decorators that come before the export seems fine [11:44:56.0884] i suppose that's an option too and would also meet my understanding of mark's concern [11:45:11.0039] > <@shuyuguo:matrix.org> no, the one from littledan saying if you have a decorator in both positions it just applies them in-order ah yeah everyone hates that suggestion, I have no problem dropping it :) [11:45:17.0532] Why? It should ping-pong [11:45:27.0789] Sorry, I'll move to TDZ [11:46:03.0490] Overall you very much cannot go and re-eval toString and expect that to work, as rbuckton is saying. [11:46:11.0795] * Overall you very much cannot go and re-eval toString and expect that to work, as rbuckton is saying. [11:48:18.0573] ryzokuken: I can no longer do notes. msaboff should be fine on his own though. [11:48:32.0322] it's almost done [11:48:37.0427] thanks to both of you [11:48:41.0535] the real MVPs today [11:49:14.0497] so toString behave diff in before/after case? weird... [11:49:14.0836] option 2 but with or without the XOR positioning? [11:49:24.0968] with XOR [11:49:44.0145] can we clarify this in the meeting for the minutes? [11:50:48.0635] This is a very satisfying ending to the meeting. Congratulations to the presenters! [11:51:30.0406] the transcription was fantastic, very few errors and very easy to edit [11:52:06.0261] they still have a bit of a hard time with non-native speakers, but then again so do I [11:53:07.0993] I really appreciate the transcription, but I'd love if we can now consider the transcription + another doc for short minutes with key points, even if they just capture resolution/conclusions [11:53:36.0936] with high quality transcription, AI summarization might actually be pretty good [11:53:41.0161] worth a try [11:54:04.0693] maybe wait til after manual editing [11:54:16.0609] yeah [11:54:22.0852] AI or human summaries work for me, as long as they capture key points such as resolutions for each topic. [11:54:50.0082] Put this on TCQ as well, but also getting transcription for hybrid meetings would be great. [11:55:32.0619] i would expect it to apply to every meeting [11:56:05.0185] I'll have family visiting, so won't be able to join the plenary in person so soon. I miss going in person! [11:56:06.0158] yeah, the transcriptionist will be at every plenary meeting from here on out [11:56:33.0293] will they be remote at hybrid meetings? [11:56:38.0243] yeah [11:56:45.0760] atleast that is my understanding [11:57:18.0685] that said, I hope over time we can expand to the TG meetings as well (like the regularly scheduled TG2 and TG3 meetings) [11:57:59.0823] TG3 😢 [11:59:22.0676] > <@usharma:igalia.com> yeah, the transcriptionist will be at every plenary meeting from here on out The transcriptionist is approved for 2023, and we'll revisit for 2024 based on your feedback. This is why it's so important and why I'm asking you for it! [12:00:06.0047] > <@usharma:igalia.com> that said, I hope over time we can expand to the TG meetings as well (like the regularly scheduled TG2 and TG3 meetings) This would need to be a separate request, but I don't see anything blocking it in principle [12:10:17.0889] For summaries: you don't have to be the proposal champion to write the summary; anyone can do it [12:10:32.0342] I will write summaries for a couple more topics; it'd be great to split up the work among everyone who has the bandwidth for it [12:13:37.0385] shu: regarding parameter decorators. There is a fairly robust ecosystem of TypeScript projects using legacy/experimental decorators that show that it is an extremely valuable feature, and not just with dependency injection. There are a number of capabilities it could enable: - Constructor Injection for DI - Parameter value marshalling hints for server-side HTTP routers for web apis, client side view routing, and possibly even as a mechanism give WASM type hints for JS functions passed to WASM as WASM/JS integration continues to grow and evolve. - Runtime Type Information or other related metadata. - argument/initializer observers (much like the initializer callbacks in field decorators) Both Parameter Decorators and Metadata are critical to moving the rest of the TS community off of legacy decorators. I'm also hoping that Grouped Accessors will solve the last migration hurdle for entangling `get`/`set` pairs. [12:15:07.0333] IIRC, parameter decorators are also used in some ORM tools to indicate how an entity should be constructed when re-hydrating from a database. [12:15:57.0750] I have a rough outline of what I'm think for parameter decorators here: https://github.com/tc39/proposal-decorators/issues/47#issuecomment-1397714899 I hope to have a proposal ready within the next two plenary sessions depending on my schedule. [12:22:29.0191] Rob Palmer danielrosenwasser rbuckton https://twitter.com/leobalter/status/1621242353494425602 [12:25:21.0512] > <@leobalter:matrix.org> Rob Palmer danielrosenwasser rbuckton https://twitter.com/leobalter/status/1621242353494425602 Great explanation! Raced you but yours explanation is better. [12:26:15.0154] I first posted a summary to my internal team, so posting on twitter had a delay :) [13:34:23.0122] rbuckton: thanks for the details 2023-02-03 [16:29:29.0254] QQ on the decoration discussion, If I have something like ````@dec exports default Foo; ``` [16:29:37.0597] * QQ on the decoration discussion, If I have something like ````@dec exports default Foo; ``` Will that be a valid syntax and will be include on `Function.prototype.toString()`? ```` [16:29:57.0824] * QQ on the decoration discussion, If I have something like ````@dec exports default Foo; ``` [16:29:59.0320] Will that be a valid syntax and will be include on `Function.prototype.toString()`? [16:30:18.0748] * QQ on the decoration discussion, If I have something like ```` @dec class Foo exports default Foo; ``` ```` [16:30:34.0797] * QQ on the decoration discussion, If I have something like ```` @dec class Foo exports default Foo; ```` [16:32:33.0441] * QQ on the decoration discussion, If I have something like ``` @dec class Foo export default Foo; ``` [16:32:57.0475] * QQ on the decoration discussion, If I have something like ``` @dec class Foo {} export default Foo; ``` [16:42:45.0223] Yes, the decorators would be included in this case because they are part of the ClassDefinition production. [16:43:16.0726] thanks! [18:57:06.0614] ljharb: Can you post the links to your slides? [18:57:27.0233] Get Intrinsics in particular [18:58:48.0851] I don't think you presented slides for Symbol Predicates [19:48:12.0535] yes, I will do so later tonight, and you’re right, i didn’t [09:27:10.0027] Ron requested I setup a poll on the syntax for Async Explicit Resource Management. So here goes. - [Twitter Poll](https://twitter.com/robpalmer2/status/1621559341055623173) - [Mastodon Faux Poll](https://elk.zone/mastodon.social/@robpalmer/109801968571918162) [09:44:39.0064] Mastodon has polls, you could prob edit it in [09:45:09.0430] Maybe depends on client I guess [09:49:55.0330] > <@robpalme:matrix.org> Ron requested I setup a poll on the syntax for Async Explicit Resource Management. So here goes. > > - [Twitter Poll](https://twitter.com/robpalmer2/status/1621559341055623173) > - [Mastodon Faux Poll](https://elk.zone/mastodon.social/@robpalmer/109801968571918162) is `using async` not included because no one liked that option, or is there some more serious problem with it I'm forgetting? [11:30:30.0888] * yes, I will do so ~later tonight~ tomorrow, and you’re right, i didn’t [11:31:06.0172] ranked choice voting when :-( [12:08:18.0527] `async` isn't a reserved word [12:08:43.0665] While `await` is, even though it is allowed in non-strict mode for historical reasons. [12:10:20.0467] We possibly could have included it, but that would mean a much broader restriction in the sync proposal than the `using await` restriction we discussed in plenary. [12:10:34.0344] Since `await` is already an illegal identifier in modules, but `async` is not. [12:15:35.0903] we could've made `async` blocked as an identifier everywhere that `await` is, but I guess we didn't. So `await` is easier to parse. 2023-02-04 [05:53:28.0528] Is it essential that the user of the disposable resource gets to decide whether or not the dispose should be asyncly waited on? As opposed to the resource itself deciding that, via the way it sets us the disposable symbol/prototocol. [06:05:24.0426] * Is it essential that the user of the disposable resource gets to decide whether or not the dispose should be asyncly waited on? As opposed to the resource itself deciding that, via the way it sets up the disposable symbol/prototocol. [07:07:04.0043] Well, I think this is just like async/await in general: if you want to defensively allow waiting for the thing, but you don’t know whether it is really needed, use the await form. This is why using await falls back to the sync dispose method. [07:09:08.0184] Remember, sync dispose can already fire off some kind of async cleanup action if it wants, it just cannot force the caller to block for its completion. Using await is for exactly this purpose of when you want blocking on dispose. [08:29:53.0937] > <@robpalme:matrix.org> Is it essential that the user of the disposable resource gets to decide whether or not the dispose should be asyncly waited on? > > As opposed to the resource itself deciding that, via the way it sets up the disposable symbol/prototocol. We made the decision early on to ensure the object matches the user's intent, not the other way around, not unlike `for` vs `for await`. [12:02:11.0745] ljharb (or another admin): could you move https://github.com/tc39-transfer/proposal-async-iterator-helpers over to the tc39 org? 2023-02-07 [16:06:23.0913] Was the conclusion for SuppressedError cause to simply ignore the options bag, not eagerly check it and, like, throw a worse error if the cause is given? [16:17:03.0292] What do people think about putting in a slightly more complete summary in the conclusion for topics in the notes? The idea would be to include a summary of the discussion, not just the points where we reached consensus. I don't see many of these summaries, though. This was a suggestion from several parties, to ensure that our conversations are more accessible. [16:19:29.0431] I don't think we should summarise the notes within the notes [16:19:39.0044] if you want to make a summary, keep it separate from the notes [16:20:33.0498] when I look at the conclusion, I am looking for a clearly spelled out, short description of actions or opinions that we have agreed upon [16:34:23.0821] > <@littledan:matrix.org> Was the conclusion for SuppressedError cause to simply ignore the options bag, not eagerly check it and, like, throw a worse error if the cause is given? The conclusion was to ignore it. [18:17:53.0405] OK I have tried to describe this in the conclusion; reviews/edits welcome [18:19:26.0235] > <@michaelficarra:matrix.org> if you want to make a summary, keep it separate from the notes Well, I was proposing this for convenience/increased engagement, but it clearly didn’t work. Does anyone want to propose another way that we could share the work to write summaries? The old way (leobalter does it all) was unsustainable. [18:20:54.0166] I was thinking that some kind of Google doc is a better way to do this than, say, some facilitator badgers each champion to write a summary and then concatenates them, because this allows us all to edit the summaries for accuracy [18:33:55.0753] littledan: someone from the community can do it? [18:34:00.0116] the raw info is all there in the notes [19:03:22.0149] > <@michaelficarra:matrix.org> I don't think we should summarise the notes within the notes we have precedent for a separate summary.md in the notes folder for the meeting [19:55:40.0749] > <@michaelficarra:matrix.org> littledan: someone from the community can do it? OK, so, given that someone from the community could have been doing this for the past two years, what should we do differently to encourage this? [23:39:07.0121] I would suggest we task the presenter with populating the summary inside the notes doc, next to the conclusion. Google Docs already supports assigning inline issues. On publishing, these can be extracted to a separate file called summary.md [23:40:25.0683] This spreads the workload and provides Champion-assured quality. [00:25:14.0730] Reminder: Nominations for TC39 Chair Group are due by 13 February. The two position available are Chair and Facilitator as described here. https://github.com/tc39/Reflector/issues/456 [08:34:15.0984] wait [08:34:19.0596] you know what we didn't do last plenary [08:34:23.0726] figure out new name for `group` [10:16:52.0233] oof, that's right. Justin Ridgewell can we make sure that's on the march agenda? [10:16:53.0636] * oof, that's right. Justin Ridgewell can we make sure that's on the march agenda? [11:13:44.0193] Yah, ran out of time before this meeting to work on it [13:59:18.0389] can we make `Array.prototype[Symbol.iterator]` non-writable, do you think [13:59:27.0010] in an exotic way so as to not trigger the override mistake [14:00:06.0245] and also the methods on ArrayIteratorPrototype [14:01:09.0209] this would be a commitment to never changing its behavior because such a change could never be polyfilled if it were non-writable, but that commitment seems worth making anyway [14:01:25.0000] * this would be a commitment to never changing its behavior because such a change could never be polyfilled if it were non-writable, but that commitment seems worth making anyway [14:02:47.0998] nonwritable is fine if it's configurable [14:03:06.0702] or you want it to be exotically nonconfigurable also [14:52:25.0788] nonconfigurable also [14:52:34.0434] specifically I want people not to be able to mess with it [14:52:53.0980] so `for (let item of [0, 1, 2])` becomes reliable 2023-02-08 [16:45:16.0712] right [16:59:12.0608] Can we just fix the override mistake? If we introduce a "freeze mode" that doesn't trigger the override mistake for some intrinsics, I'd like this behavior to not be exotic, and be applicable to non intrinsics. One avenue I've been toying with is an options bag to `Object.freeze` that would allow setting such mode on the object and have the `OrdinarySetWithOwnDescriptor` check for that mode. I think changing 2.1 to something like this would be enough: `If ownDesc.[[Writable]] is false and O.[[FrozenWithoutOverrideMistake]] is true, return false.` [17:02:38.0243] Then instead of ad-hoc patching some intrinsics so that they'd be exotic non-configurable, just ask that code opt-in to freezing all the intrinsics through the new "secure mode" [17:03:10.0808] Mm, I'm not sure how much appetite there would be for a new attribute on every object. That's a lot to ask of engines. [17:03:18.0600] maybe? [17:03:36.0013] Doesn't have to be on every object, just the special frozen ones ;) [17:05:27.0494] Implement it as another integrity level if you want, super-frozen. I actually would like if that same super-frozen mode didn't re-execute all the checks in `isFrozen`, and simply returned true if in that mode. It'd behave like a "cached-frozen" mode. [17:05:31.0836] though if you really want this patch to be non-exotic, you can do that without a new attribute by, instead of having a nonwritable field, instead having a frozen getter/setter pair where the setter silently does nothing [17:05:37.0211] * Implement it as another integrity level if you want, super-frozen. I actually would like if that same super-frozen mode didn't re-execute all the checks in `isFrozen`, and simply returned true if in that mode. It'd behave like a "cached-frozen" mode. [17:06:24.0210] I too like things being more frozen, but asking engines to mess about with the internal representations of things is, generally, going to need to clear a pretty high bar [17:06:27.0744] I would expect, anyway [17:06:28.0227] Correct, and that's what the Hardened JS / SES repairs do to tame the override mistake (referring to installing a no-op setter) [17:07:07.0400] * Correct, and that's what the Hardened JS / SES repairs do to tame the override mistake (referring to installing a no-op setter) [17:10:24.0271] However the experience in debuggers and other code that inspect objects is really sub-par with that kind of repair into accessors. [17:13:33.0157] Well, right, seems like it would be easier just to make it exotic [17:14:48.0959] I'm not opposed to having a new integrity mode if you can convince engines it's worth it, I just think that's a lot less likely to happen than making Array.prototype special [17:15:00.0703] easier maybe, but given there were multiple agenda items that broached on the override mistake and in general allowing developers to opt-into a more secure environment, I would really prefer a holistic solution [17:17:54.0969] if you think you can convince engines it's worth it, go for it [17:18:08.0818] I'm not going to spend much effort on that myself [17:18:53.0995] I might at some point spend effort specifically on the Array.prototype case though, since it's particularly acute [17:59:06.0722] It's still possible that we can do the obvious fix for the override mistake. [17:59:28.0472] The attempt we made before was just a counter that an override took place, but not whether it caused any breakage. [18:00:09.0701] Lodash triggered the counter, but the function continued to work correctly because of a fallback path. 2023-02-09 [03:23:08.0140] The invite post for the March 2023 plenary is posted: https://github.com/tc39/Reflector/issues/461 Please remember to use the In-Person Registration form if you are planning to come to the F5 Tower in Seattle. 2023-02-10 [15:50:50.0214] lol JSON.parse reviver semantics [15:50:51.0477] who designed this 2023-02-11 [16:04:54.0249] https://www.ecma-international.org/wp-content/uploads/ECMA-262_5th_edition_december_2009.pdf is uncredited, but I think the information is still available elsewhere 😈 [16:22:21.0800] Wasn't reviver part of Douglas Crockford's json2 library? IIRC, that was the basis for JSON.parse and stringify. 2023-02-12 [10:24:08.0269] A reminder the sign up list is posted for Seattle in March. So far we have 10 people registered. https://github.com/tc39/Reflector/issues/461 2023-02-13 [03:49:40.0506] > <@shuyuguo:matrix.org> lol JSON.parse reviver semantics Extending that to work with YAML was fun. [12:59:02.0966] * A reminder the sign up list is posted for Seattle in March. So far we have 13 people registered. https://github.com/tc39/Reflector/issues/461 2023-02-14 [18:54:48.0703] https://github.com/zloirock/core-js/blob/master/docs/2023-02-14-so-whats-next.md [18:56:37.0279] Did Google even have considered to donate? Maybe Google delegates can bring up this topic to their company though I don't expect it will have any result [19:15:42.0709] i'd love to see every big company donate to all the things it uses; tidelift is great for that. [19:18:02.0485] then you're live in a utopia, that's impossible [19:56:45.0348] Programmers living in western countries should be more wealth to donate. Please do that. I'll donate $50 monthly. [22:47:52.0723] kinda unfortunate to have shu called out like that :-/ [22:48:09.0231] though I don't remember what the context of that conversation would've been [22:48:29.0637] actually I had forgotten that his real name and username were the same person [22:48:30.0134] me as well. [22:48:36.0730] right [22:49:12.0038] i don't think it's any more impossible than expecting any big company to donate [22:49:36.0497] I guess I'm just more used to people calling you out 😅 which is certainly not to say that it's okay [22:49:42.0836] rofl fair enough [22:49:54.0103] (actually in this context I don't understand how your comment there relates to his point) [22:49:59.0687] it doesn't. [22:51:49.0243] he seems to have interpreted "polyfillability isn't a consideration for proposals" as "TC39 doesn't care about polyfills", which if you consider TC39 caring as "anyone cares" then it's objectively false even solely because i'm in the room (and if you consider it as "everyone cares", virtually nothing qualifies) [22:52:21.0683] but i'm pretty used to him misinterpreting my statements 😅 [22:54:05.0211] ugh [07:46:32.0976] > <@rkirsling:matrix.org> though I don't remember what the context of that conversation would've been i don't remember anymore, but i'm pretty sure it came after https://github.com/tc39/proposal-rm-builtin-subclassing/issues/23 [07:46:55.0177] iirc after that thread i decided i'd rather disengage [07:48:10.0514] ahh right [07:48:24.0454] amazing how one forgets about these things [07:50:45.0859] lovely of him to paint you two as unhelpful in a conversation where he so professionally said "I'm fucking tired to explain obvious things to you" 2023-02-15 [03:56:12.0079] Another gentle reminder: please sign up for Seattle plenary in March. So far we have 15 people registered to attend in-person. https://github.com/tc39/Reflector/issues/461 2023-02-16 [14:42:41.0053] I forgot to ask for stage 2 reviewers for Symbol Predicates ( https://github.com/tc39/proposal-symbol-predicates ) at the recent plenary; I'd love to get some folks to volunteer now, to be confirmed in the next plenary, and hopefully already have approved it :-) if anyone's interested, please comment in the thread! 2023-02-17 [17:33:25.0978] bakkot: what is "1. If NewTarget is undefined or the active function object, throw a TypeError exception." intended to do in the Iterator constructor? throw on creating empty iterators? [17:35:25.0791] uhh that spec text predates my involvement. I guess it is intended to make `Iterator` essentially an abstract class? [17:35:33.0233] i.e. you can't instantiate it directly, only inherit from it [17:35:56.0928] okay [17:35:59.0556] (that's the "active function object" bit; the "undefined" is what makes it not invokable without `new`) [17:36:00.0300] that's... fine i guess? [17:36:06.0578] yes, i meant the active function object bit [17:36:06.0881] tbh I didn't notice that was there [17:36:16.0825] that's a behavior i've never implemented before [17:36:19.0111] so wanted to double check [17:36:33.0152] cc snek [17:36:50.0759] like i guess it'd be pretty useless to call new Iterator(), so it's fine to error [17:37:26.0631] I could imagine doing something like `let x = new Iterator(); x.next = () => ({ done: false, value: 0 })`, I guess [17:37:55.0130] but `let x = { __proto__: Iterator.prototype, next: () => ({ done: false, value: 0 }) }` works just as well if you want that [17:38:16.0275] some people are averse to the `__proto__` syntax but like whatever [17:38:56.0464] it does seem like a kind of unnecessary restriction [17:39:30.0009] otoh it genuinely is abstract in that you need to provide your own `next` [18:27:04.0993] > <@bakkot:matrix.org> uhh that spec text predates my involvement. I guess it is intended to make `Iterator` essentially an abstract class? This is something for which I've wanted to add formal syntax for awhile (i.e., `abstract class`). Hopefully having the concept of an abstract class as built in might make it easier to get a proposal adopted [18:27:31.0333] * This is something for which I've wanted to add formal syntax for awhile (i.e., `abstract class`). Hopefully having the concept of an abstract class as built in might make it easier to get a proposal adopted [19:01:20.0707] > <@shuyuguo:matrix.org> like i guess it'd be pretty useless to call new Iterator(), so it's fine to error that is the reason [19:01:31.0591] it is definitely not the norm [00:59:06.0816] The new Safari 16.4 Beta looks excellent. The release notes says that it contains Array grouping. I guess general availability of that will be gated on resolving the API naming to ensure it is web compatible. https://developer.apple.com/documentation/safari-release-notes/safari-16_4-release-notes [10:05:47.0228] > <@bakkot:matrix.org> it does seem like a kind of unnecessary restriction this is my feeling but i don't care that much [10:57:53.0556] wait why is Iterator.prototype non-configurable? [10:58:00.0868] we don't do that for other prototypes do we [11:06:34.0142] My phone says we do? [11:07:26.0968] yeah `.prototype`s are non-configurable by default [11:09:07.0493] but writable on function declarations and maybe some other functions? [11:09:42.0224] wait [11:09:46.0078] hol up [11:10:30.0975] you are correct [11:11:12.0085] i was confused by the iterator-adjacent prototypes, like https://tc39.es/ecma262/#sec-generatorfunction.prototype.prototype [11:11:13.0899] which are configurable [11:11:23.0607] i guess the question is then why are those configurable 2023-02-18 [10:44:00.0708] a new-to-me way to have a web compat issue: https://twitter.com/RickByers/status/1625256623655596037 this one doesn't even require code to be conditionally adding a property based on whether it exists, because it turns out the web platform will do the conditionally adding for you! [10:44:51.0842] I had not realized that some of the magic names on `window`, like named frames, are explicitly only added if there is not already a platform thing of the same name there [11:44:25.0007] ljharb: I made https://github.com/tc39-transfer/proposal-float16array so we have a place to track it; would you (or another admin) bounce it to the main org? 2023-02-19 [09:15:55.0597] > <@shuyuguo:matrix.org> i guess the question is then why are those configurable javascript must never reach consistency on any feature or pattern. reality would collapse.