2021-10-01 2021-10-02 [16:44:57.0483] Aki: as long as you are doing matrix-y things, can I petition you to change the logs links to https://matrixlogs.bakkot.com/ ? the current logs are kinda garbage 2021-10-04 [15:29:35.0346] bakkot: can we host that somewhere that's controlled by the committee instead? [15:39:34.0902] Michael Ficarra: It's on github pages [15:39:53.0522] do you want push access to the repo, or? [15:40:24.0486] but also we relied on a logbot hosted by a non-committee member for the last several years, which was fine [15:40:38.0602] so it does not seem particularly pressing to me [15:41:06.0221] I meant the domain, shouldn't it be easy to be something like `tc39.es/matrixlogs` by transferring to the tc39 org? [15:44:53.0165] I don't intend it to be just for tc39; it also hosts logs for whatwg, and I will probably add more if people ask for them. and I don't really want to run multiple instances of it [15:45:13.0687] so if you want to do the work of setting up and running a separate instance and hosting it there, go for it [15:45:18.0650] otherwise I would prefer not to change mine 2021-10-05 [18:58:41.0939] it'd probably be good to have tc39's be on their own instance under tc39.es 2021-10-06 [07:32:03.0017] Several Stage 0 proposals have been transferred to the tc39 GitHub organization. Is there a particular policy about this? https://github.com/tc39/proposals#onboarding-existing-proposals doesn’t talk about Stage 0. [07:41:46.0463] are internal slots case sensitive? [07:46:06.0926] https://tc39.es/ecma262/#sec-object-internal-methods-and-internal-slots doesn't specify that [07:57:51.0448] yeah, treat them as case sensitive [07:58:01.0159] i'd be against every introducing slot names that differ only in casing [07:58:08.0196] but even so just treat them as case sensitive [08:00:30.0551] I mean more about access. Can I access `[[Foo]]` using `[[foo]]`? [08:11:24.0610] semi-related. is the `[[Description]]` that a Symbol "holds" also an 'internal slot'? The spec seems to say that slots are only on objects, so would it be technically incorrect to say that symbols have an internal slot? [09:02:16.0519] ryzokuken: no, use [[Foo]] [09:42:19.0358] Ashley Claymore: not technically, but conceptually yes [10:01:31.0475] thanks shu 🙂 [10:58:30.0344] PSA: nobody has signed up for the next incubator call yet. the topic is Proxy performance https://github.com/tc39/Reflector/issues/399 [14:15:52.0018] > <@jschoi:matrix.org> Several Stage 0 proposals have been transferred to the tc39 GitHub organization. Is there a particular policy about this? https://github.com/tc39/proposals#onboarding-existing-proposals doesn’t talk about Stage 0. the policy is that stage 1+ proposals *must* be transferred; stage 0 proposals can be, but for scalability, we should probably only transfer the ones that have been discussed in a plenary [15:24:30.0814] Can the `Contains` spec op be used with a sequence of terminals, or would I need to contain the terminals in a nonterminal to use Contains? For example, would the following be valid spec text?: ``` If _node_ Contains `using const`, ... ``` [15:24:51.0754] * Can the `Contains` spec op be used with a sequence of terminals, or would I need to contain the terminals in a nonterminal to use Contains? For example, would the following be valid spec text?: ``` If _node_ Contains `using const`, ... ``` [15:31:53.0239] rbuckton: as it is currently written, it cannot. it walks over the children of a parse node one at a time checking if each is an instance of the argument to Contains, which would not work when the thing you are looking for is spread out across multiple children. [15:32:09.0096] * rbuckton: as it is currently written, it cannot. it walks over the children of a parse node one at a time checking if each is an instance of the argument to Contains, which would not work when the thing you are looking for is spread out across multiple children. 2021-10-10 [09:03:57.0802] FYI to CoC people: just sent in a CoC request (in case it gets caught by spam filters like last time) [10:06:05.0129] Same: I sent two emails CoC yesterday, in case they’re caught as spam. 2021-10-11 [08:40:48.0367] fwiw i got them all. [09:51:40.0420] Delegates, FYI we have implemented an indefinite block on a "sock-puppet" account. Sock puppet accounts are alternate accounts created by users, typically to get around a block or to create the appearance of more support for a poster's ideas. Creating sock puppet accounts is an example of a negative conflict behaviour that will result in an immediate block. cc TabAtkins ljharb jschoi [09:52:40.0323] Thanks for your continued use of the CoC process! Please let me know directly if you have any questions or concerns. 2021-10-13 [10:22:40.0192] devsnek: for your slides for extending `null`, it would be good to have some some slides with the various edge cases (especially "class which extends a literal `null` and has not had its prototype changed", "class which initially extended some other value but has had its prototype changed to `null`", and "class which initially extended `null` but has had its prototype changed to a non-`null` value") everyone agrees `extends null` should work, so much of the meat of the discussion is around these edge cases [10:22:52.0207] I can write something up if you'd find it helpful [10:23:40.0460] also, reminder to the channel that the deadline for advancement eligibility is in two days, and the agenda is currently pretty light [10:31:27.0966] If not much else gets added to the agenda, then I will expand my two proposal updates’ timeboxes from ten minutes to thirty minutes each. [10:31:49.0409] * If not much else gets added to the agenda, then I will expand my two proposal updates’ timeboxes from ten minutes to thirty minutes each. [11:01:49.0766] shu: given that the agenda is kind of light, Michael Ficarra and I were thinking it might be a good time for the subclassing discussion [11:16:40.0444] jschoi: the spec at https://jschoi.org/21/es-array-async-from/ appears to be ahead of the spec in the proposal [11:16:46.0921] I was gonna submit a PR but it's tricky when they're out of sync [11:36:26.0563] bakkot: what's the scope you had in mind? [11:48:41.0192] > <@jschoi:matrix.org> If not much else gets added to the agenda, then I will expand my two proposal updates’ timeboxes from ten minutes to thirty minutes each. any time box less than 30 minutes is pretty ambitious [11:50:57.0313] > <@shuyuguo:matrix.org> bakkot: what's the scope you had in mind? tradeoffs of the "minimal core" philosophy where supplementary methods delegate to core methods so that subclasses only need to override the core [11:51:55.0582] recall the question from the Set methods proposal: do helpers like union/intersection/difference touch the set contents themselves or delegate to the add/remove methods [12:16:12.0156] > <@bakkot:matrix.org> I was gonna submit a PR but it's tricky when they're out of sync They should be in sync; I’m surprised that they were not. I just updated the spec page to match the repository’s build. I’ll set up an automatic build on tc39.es sometime. [12:17:06.0776] > <@michaelficarra:matrix.org> any time box less than 30 minutes is pretty ambitious Haha, yeah—I was just going to speed through a few update slides then say, “Please file any questions in a new GitHub issue; thank you!” [12:53:28.0965] > <@jschoi:matrix.org> They should be in sync; I’m surprised that they were not. > I just updated the spec page to match the repository’s build. I’ll set up an automatic build on tc39.es sometime. unless there's a caching issue or something they appear to still not be in sync - the rendered spec has the TA method, the source in the spec.html file in the repo (which has not been updated in 13 days) does not [12:55:25.0765] I’ll look into it, but either way I haven’t gotten to updating the TypedArray version yet to fulfill #9. I’ll work on deploying to GitHub Pages tonight so we can definitely have an up-to-date spec page. [12:55:46.0625] * I’ll look into it, but either way I haven’t gotten to updating the TypedArray version yet to fulfill #9. I’ll work on deploying to GitHub Pages tonight so we can definitely have an up-to-date spec page. [13:10:01.0087] bakkot: updated slides and also rebased the spec text [13:13:36.0268] also added a note about how class fields don't currently work [13:15:01.0268] * also added a note about how class fields don't currently work [16:30:01.0538] reminder that nobody has signed up for the next incubator call: https://github.com/tc39/Reflector/issues/399 [16:30:17.0184] i will cancel it if nobody else signs up by this friday, Oct 15 2021-10-14 [17:39:46.0654] > <@jschoi:matrix.org> I’ll look into it, but either way I haven’t gotten to updating the TypedArray version yet to fulfill #9. > > I’ll work on deploying to GitHub Pages tonight so we can definitely have an up-to-date spec page. I added an action to proposal-array-from-async that automatically publishes to its gh-pages branch, but it doesn’t look like the gh-pages files are showing up at https://tc39.es/proposal-array-from-async/. Is there anything else I need to do? [17:40:21.0510] Also, I need access to proposal-bigint-math’s repository to enable GitHub Actions so that it can also publish to its gh-pages branch. [23:19:11.0074] > <@jschoi:matrix.org> I added an action to proposal-array-from-async that automatically publishes to its gh-pages branch, but it doesn’t look like the gh-pages files are showing up at https://tc39.es/proposal-array-from-async/. Is there anything else I need to do? you need to make sure github pages is enabled in the repo settings [06:49:00.0104] Oh yeah, right. Could I get settings access to proposal-array-from-async and to proposal-bigint-math? [09:47:39.0319] the chairs would have to do that [11:06:50.0538] > <@jschoi:matrix.org> I added an action to proposal-array-from-async that automatically publishes to its gh-pages branch, but it doesn’t look like the gh-pages files are showing up at https://tc39.es/proposal-array-from-async/. Is there anything else I need to do? I have a similar action set up in a few of my proposal repos. [12:26:59.0027] (note that the template repo does it by auto-building the spec and storing it in the default branch, no gh-pages branch at all - there's a bunch of ways to do it) [15:21:35.0212] I do need settings access to those two repositories anyway, to change these repos’ homepage metadata from spec pages on my personal websites to tc39.es pages. [15:22:17.0359] Aki, bterlson, yulia: Could any chair give me GitHub admin access to proposal-array-from-async and to proposal-bigint-math? [15:22:31.0077] * Aki, bterlson, yulia: Could any chair give me GitHub admin access to proposal-array-from-async and to proposal-bigint-math? 2021-10-15 [01:57:14.0284] Anyone around to merge #1058, #1059, #1060, #1061 in https://github.com/tc39/agendas/pulls? [01:59:02.0035] If not, I think I can merge myself [02:21:51.0402] If we are still light on the agenda, there are a few more proposals I intend to split off from https://github.com/rbuckton/proposal-regexp-features into individual proposals that I can add as well. I intended to propose them for Stage 1, but did not have the time to make individual repos/slide decks for each feature prior to the agenda deadline. I am aware they could be rejected purely on this basis, but if we have the time to spare I can finishing breaking them down tomorrow and add them to the agenda. [08:43:55.0534] They don’t need to be merged before the deadline, for future reference; merely opening the PR is sufficient. [12:52:47.0437] I pointed this out on GH as well, but the Agenda topic rules are actually unclear on that subject: [12:54:17.0455] The term "pull request" is only used in reference to (1). All other points use the term "added" which, given the distinction for PRs in (1), seems to indicate they must be part of the actual agenda by the deadline. If merely having the PR by the deadline is acceptable, I suggest we change the wording in the agenda topic rules. [12:55:49.0666] I'd be happy to clarify the rules to say that raising a PR (that includes the links to the materials) is sufficient. Review/merge time should not count against the submitter given that in all normal circumstances it will get merged within a day. [12:56:13.0919] I was leaning towards the "added" meaning "merged" interpretation because there's no guarantee that a TC39 member looking at the agenda would be expected to also check the open PRs for other not-yet-merged topics and might miss a topic and be unwilling to advance as a result. [13:00:54.0376] As someone who had a proposal blocked because I'd neglected to hit submit on the PR after publishing the branch for the PR (damn two-step process for proposing a change to a MD file on GitHub), I admit to being a bit more cautious in my interpretation. Yes, its not quite the same thing since branches are significantly less visible than PRs, but still its not something I'd like to repeat. [13:10:08.0218] since we've considered a PR sufficient in the past, i pushed up a commit clarifying it [13:10:31.0077] if anyone objects we can discuss it during plenary [13:11:16.0185] Let's remember to explicitly highlight this in the next plenary. [13:14:47.0725] sounds great! i'll be asleep the first half of each day or i'd be happy to volunteer; please do explicitly mention that i've documented past precedent :-) 2021-10-16 [17:23:24.0788] I've added a few late additions (#1065 [merged], #1066 [pending], and #1067 [pending]) to the agenda as I've continued to whittle away at the proposal-regexp-features proposal from last meeting. I'm aware they may be blocked due to the agenda topic rules, but from my calculations it looked like we were light on agenda topics for a 4-day plenary. Even if they don't achieve Stage 1 it is at least worth discussing them individually, though I'm *hoping* that the late addition status won't be a primary blocking concern since I discussed all of these in the last meeting. 2021-10-19 [20:14:50.0937] TC39 Calendar event reminder: Record&Tuple Monthly call tomorrow (19th). 6pm utc [20:16:36.0855] * TC39 Calendar event reminder: Record&Tuple Monthly call tomorrow (19th). 6pm UTC [20:31:54.0927] * TC39 Calendar event reminder: Record&Tuple Monthly call today/tomorrow (19th). 6pm UTC 2021-10-24 [09:14:03.0588] justingrant and I have a heads up for delegates about two changes to the Temporal item in the upcoming plenary: [09:14:53.0345] Wanted to give a heads-up about two changes we just pushed for Temporal's slides for next week's plenary: - Added a [new slide](https://ptomato.name/talks/tc39-2021-10/#23) for a fix for a spec bug discovered after the deadline. It will be hard to wait to fix this bug until Dec, so we added it with a "⌛️" mark. if you feel you need more time to review this, don't hesitate to ask for it. [09:15:21.0716] - A PR that we thought had everyone's 👍️ actually needs more feedback. So we moved it from the main slides into a new ["Discussion" section](https://ptomato.name/talks/tc39-2021-10/#25) at the end. We added additional context to frame the discussion, and time permitting we'd appreciate committee input. [09:15:33.0886] * - Added a [new slide](https://ptomato.name/talks/tc39-2021-10/#23) for a fix for a spec bug discovered after the deadline. It will be hard to wait to fix this bug until Dec, so we added it with a "⌛️" mark. if you feel you need more time to review this, don't hesitate to ask for it. [11:39:08.0830] where is the sign-in form? i don't see it in the reflector thread [11:39:33.0971] Rob Palmer: Aki bterlson ^ [12:48:04.0074] I'll put it up tomorrow two hours before the meeting. Unless you really need it now? [14:44:03.0081] I noticed that I’m not on the TCQ for tomorrow, but I have a constraint that I can really only attend tomorrow although if push comes to shove, I’m sure I can move some stuff around. Is that an oversight or should I try and dig up a free spot on some other day? [14:44:36.0758] nvm me [14:44:45.0262] * I noticed that I’m not on the TCQ for tomorrow, but I have a constraint that I can really only attend tomorrow although if push comes to shove, I’m sure I can move some stuff around. Is that an oversight or should I try and dig up a free spot on some other day? ~x~ [14:44:50.0820] * I noticed that I’m not on the TCQ for tomorrow, but I have a constraint that I can really only attend tomorrow although if push comes to shove, I’m sure I can move some stuff around. Is that an oversight or should I try and dig up a free spot on some other day? [14:44:58.0362] Didn’t see the draft schedule 🤦 [15:57:09.0091] Rob Palmer: i'd prefer the link and password now so i can wake up at like, 1:45am instead of 1:30am 2021-10-25 [23:46:49.0052] The sign-in form is now on the Reflector issue. Please do not post the link here because this is a public channel. [23:51:36.0157] Please could someone try the form to check it's working. [23:55:06.0263] Rob Palmer: just did [23:55:29.0590] I filled out the form and it works [23:55:40.0172] thanks legendecas! [01:52:23.0044] There are 5 of us in the Jitsi call. We'll kick off in 8 mins! [01:58:20.0922] 13 people are here - two mins to go! [02:03:46.0088] 26 people now - and we are go [02:05:27.0224] what is the password of the meeting? [02:05:38.0374] use the form on the reflector [02:05:41.0927] do not post the password here [02:05:48.0204] oh ok thanks [02:30:25.0443] 40 people are here now - good turnout for 2am Pacific Time [02:31:31.0909] many folks missing affiliations in the names [02:33:11.0685] anyone who just shows up as an email address probably has an 8x8 meet account [02:33:19.0078] which doesn't support display names???? [02:33:39.0053] Several of the people in the 8x8 don't have full names even [02:34:07.0076] yeah i see that [02:35:29.0630] there's literally someone with `test123` on here 😅 [02:39:02.0826] Aki: should we give an announcement about that? possible tighten the form so that if the name is not on the form they get booted? [02:39:20.0610] Yup. that's my plan [02:40:44.0106] did we have local-only meetings in 2019? [02:44:34.0142] we haven't had a local-only meeting in… idek 6 years? [02:45:28.0693] sounds good, I was just confused because they were mentioned in Istvan's report as "no longer on the table" but I thought they had been so for a while [02:51:20.0893] SDO = Standards Development Organization ☺ [02:52:31.0949] who wants to add SDO (syntax directed operation) to terminology? https://github.com/tc39/how-we-work/blob/master/terminology.md [02:52:47.0031] we can add both definitions, i thought "standards development org" at first [02:54:06.0336] Ashley Claymore volunteered [03:01:31.0796] https://github.com/tc39/how-we-work/pull/102/files [03:01:53.0881] Should I add 'standards development org' too? [03:01:56.0700] To avoid confusion [03:10:02.0126] yeah, i think we use both in the tc39 context [03:10:19.0795] for example "ecma is an SDO" for that context [03:13:47.0273] added both :) [03:14:49.0940] We have 5 people with non-compliant Jitsi display names. Please can these people rename to use their full name and (affiliation/company) Waldemar, 393939, feng, Hongjian Yang, ZY [03:19:18.0090] waldemar: psst (you're still missing the (Google) part [03:25:25.0542] I just catching up (was out of electricity here) but I'm happy to see the nominations for the Ecma award. Thanks yulia for coordinating this! [03:30:33.0331] Aki: speaking of scheduling stuff, Michael and I would like to defer the subclassing discussion to a later meeting [03:30:56.0634] we've already removed it from the agenda [03:31:03.0065] no shit! WELL. that changes things. [03:31:13.0060] sorry, we should've given you a heads up [03:31:25.0844] all good. i'm sure Ron Buckton will appreciate [03:31:50.0495] turns out subclassing builtins is a very complicated topic [03:32:04.0634] imagine that [03:32:06.0684] * imagine that [03:37:33.0941] can we advance the queue so I can add a reply? [03:38:10.0896] done [03:49:51.0102] Jack Works: you're only looking to expose the composition of serialise/deserialise, not either individually, right? [03:53:12.0774] > <@michaelficarra:matrix.org> Jack Works: you're only looking to expose the composition of serialise/deserialise, not either individually, right? I'm looking for a much more powerful serialize/deserialize API in the language that can be integrated with structured clone [03:53:54.0125] but I never presented it to the committe because I didn't make clear about how I should design those APIs [03:57:14.0530] Design goals: - Format independent (I'm not going to specify a new format to store the serialize result) - Configurable (e.g.: Devs can define their own structures that can be stored into indexedDB via structured clone algr) - Async (Some data structures requires async access, including CryptoKey) - Exportable (a interesting property on CryptoKey) - Sendable (is it ok to transfer/clone to another Realm) - Transfer (as structured clone, transfered data cannot be accessed later) [03:58:31.0764] so it's going to be an opaque blob? [03:58:44.0484] we are breaking for 62 mins. returning at 13:00 UK time [03:58:56.0236] > <@michaelficarra:matrix.org> so it's going to be an opaque blob? Yes, maybe. Host decides how to store them. [04:00:52.0045] My current idea is - defining a new kind of intermediate data structure (let's call it `InterMap`) which works like a Map - design a set of API to ser/deser from/to `InterMap` - let `InterMap` can be structure cloned [04:02:37.0598] k, as long as you can't inspect it and rely on it [04:03:20.0958] though if you plan to have it able to be stored in IndexedDB, I don't see how you're going to do that [04:03:32.0973] will it still be opaque in IndexedDB? [04:07:23.0435] > <@michaelficarra:matrix.org> will it still be opaque in IndexedDB? yes, if you take it out from the indexedDB, you need to use the deserialize API (with the correct options) to extract data from it. [04:10:05.0457] if `A` and `B` encode and decode the `InterMap` in different way, program will fail e.g. - `app that 1 month ago` vs `app today` (via `indexedDB` or other persistent storage) - `website a` and `website b` (via `postMessage` or other communicating API)) [04:58:13.0651] We will be starting the meeting in 2 mins [05:09:49.0276] date.parse is never going to have agreement among engines I think [05:09:57.0044] exactly yes [05:13:54.0765] there was that one person (from Mozilla maybe?) a few years ago who was trying to come up with an intersection semantics but then they left and never came back [05:14:18.0932] yeah [05:14:31.0301] that convinced me it was a lost cause [05:14:38.0158] also a spectacular waste of engineer time [05:14:44.0081] * also a spectacular waste of engineer time [05:19:12.0056] why is this not an arrow? [05:20:51.0483] just so we can do cool point-free stuff? [05:21:17.0559] I don't think this counts as point-free, strictly speaking [05:21:21.0020] the `?` is a point [05:21:26.0499] The one thing I'd like to say on waste of time is that the number of engineers downstream from the specification is vastly larger and to some extent they also have to deal with engines disagreeing here. (I'm glad HTML parsing got solved eventually as that had similar sentiments attached to it.) [05:22:11.0492] is `f~()` (without any `?` or `...`) valid syntax? [05:23:44.0098] Surma: Count me in for Stage 3 review of Module Blocks. I have direct interest for this feature and I need to get on the specs to make sure it connects well with ShadowRealms. [05:25:22.0499] I just can't guarantee I'm gonna be awake for the time you present it :) [05:26:11.0299] That’s okay! I also have Guy Bedford volunteering to be a reviewer, and I don’t think they’re awake ;) [05:26:11.0888] annevk: fair, but in this case we have good agreement on the superior solution, Temporal [05:26:36.0303] two placeholder .... oh [05:26:39.0404] such that there's no point in salvaging the old thing. i thought people are already shipping usertime libraries today instead of relying on the brokenness of Date.parse [05:28:16.0918] shu: I'm not sure it needs salvaging; picking an implementation as winner seems preferable to implementation-defined behavior [05:28:59.0686] annevk: people switch on which engine they are running on before calling Date.parse sometimes, so I don't think we can even get away with that [05:29:13.0333] * annevk: people switch on which engine they are running on before calling Date.parse sometimes, so I don't think we can even get away with that [05:31:17.0372] Sorry, where’s the queue link posted again? [05:31:38.0345] reflector [05:33:21.0072] I’m checking there, but I don’t see a queue link, sorry. What section is it under? [05:33:38.0552] https://github.com/tc39/Reflector/issues/396 under "TCQ" [05:33:44.0503] (that link will only work for delegates) [05:34:00.0995] Ah, sorry! I had not realized that was the acronym. [05:38:14.0557] legendecas: the downside of `a.b~()` being the only way to bind is that it only allows binding to an object the function is already installed on, not an arbitrary object [05:40:38.0304] I'm glad the to see the TCQ reflecting a lot of my thoughts already. For a big majority, the arrow function seems much easier to read. For constructors it feels lacking motivation and perhaps some weird way to sugar class inheritance. [05:41:00.0865] Michael Ficarra: compose it with comma expressions to first assign `b` to `a`, then delete it [05:44:22.0947] shu: to your question on benefit over arrow functions: Benedict optimized bind to an inch of its life and ultimately made them faster than arrow functions (I believe). I wonder if this extra ability to bind arbitrary positions could eliminate the need for arrow functions so much, and therefore lead to possible performance wins. [05:45:30.0973] MM is making the exact point I wanted to make: readers are going to have a harder time with this, for basically no benefit [05:46:35.0600] Rob Palmer: i can see it being more optimizable, yes [05:46:35.0863] I think arrow functions haven't been fully optimized yet if they are still slow. It isn't the syntax that causes this impact here. I wouldn't go with a performance argument for this [05:46:52.0348] but that is far, far below other considerations here [05:47:05.0367] > <@shuyuguo:matrix.org> Rob Palmer: i can see it being more optimizable, yes huh interesting [05:47:14.0554] it's easier to analyze, right? [05:47:31.0386] right, i was thinking about a simpler case [05:47:34.0262] whereas for arrows that do simple forwarding + argument reordering/shuffling, you'd have to pattern match [05:47:46.0943] yep yep, i didn't read fully -- sorry [05:47:48.0024] creating an arrow function captures more scope (the execution context) [05:48:00.0405] it doesn't _have_ to [05:48:13.0288] you could analyze more in the frontend if you really cared, i suppose, to pattern match on forwarding patterns [05:49:05.0563] but speculative optimizability is not compelling enough for this [05:49:41.0396] what are you doing such that you're creating so many forwarding functions? [05:50:02.0853] glue. lots of glue. [05:51:42.0066] if the cost of glue is too high [05:51:58.0546] there might be avenues of exploration on a better `bind` here, than syntax [05:52:17.0614] +1 to a better bind (but "better" would require syntax imo) [05:52:54.0329] better would probably require syntax, yes [05:53:15.0268] i meant better only in terms of optimizability, i guess [05:53:50.0883] unless glue code writers also really care about how their glue code looks [05:53:56.0215] but i'm less sympathetic to that though [05:54:02.0742] * but i'm less sympathetic to that though [05:54:52.0229] i would be pretty surprised to see a JS codebase in which the difference in optimizability between arrows and `.bind` had a user-visible effect on performance [05:58:26.0107] To add onto Ron mentioning bind-this, PFA syntax and bind-this are orthogonal, would synergize, and have very small overlap. Examples in a moment. [05:59:18.0900] `obj.method~()` would handle method extraction with implicit binding, which bind-this does not address. I’m talking about when the receiver of the bound function already contains the function that is being bound. Bind-this would require you to repeat the receiver in this case; it does not address method extraction at all. ```js n.on("click", v.reset.bind(v)) n.on("click", v::v.reset) n.on("click", v.reset~()) ``` [05:59:24.0657] * `obj.method~()` would handle method extraction with implicit binding, which bind-this does not address. I’m talking about when the receiver of the bound function already contains the function that is being bound. Bind-this would require you to repeat the receiver in this case; it does not address method extraction at all. ```js n.on("click", v.reset.bind(v)) n.on("click", v::v.reset) n.on("click", v.reset~()) ``` [06:00:01.0320] Of course, PFA syntax does not address changing the receiver of a function call. ```js isPending.call(this._target()) this._target()::isPending() ``` [06:00:11.0930] PFA syntax and bind-this can also work together, when creating bound functions with multiple partially applied arguments, which people sometimes do use `bind` for. From svgo@1.2.2: ```js smartRound.bind(this, params.floatPrecision) x => this::smartRound(params.floatPrecision, x) this::smartRound~(params.floatPrecision) ``` [06:00:35.0215] * PFA syntax and bind-this can also work together, when creating bound functions with multiple partially applied arguments, which people sometimes do use `bind` for. From svgo@1.2.2: ```js smartRound.bind(this, params.floatPrecision) this::smartRound~(params.floatPrecision) ``` [06:01:35.0531] * PFA syntax and bind-this can also work together, when creating bound functions with multiple partially applied arguments, which people sometimes do use `bind` for. From svgo@1.2.2: ```js smartRound.bind(this, params.floatPrecision) x => this::smartRound(params.floatPrecision, x) this::smartRound~(params.floatPrecision) ``` [06:10:09.0147] gathering my thoughts some more: i can live with pipeline because, while i disagree with its motivations there as well (e.g. naming intermediates is too onerous), i have a sense that there is in fact a large number of folks clamoring for it and really want to type it. syntax catering to popularism is fine by me, active harm excepted. but here, i haven't gotten the sense there is a large number of folks clamoring for it [06:11:58.0123] ```js class C {} function g() { return new C(); } const o2 = g(); // C {} const o3 = new g(); // C {} ``` [06:12:55.0209] > <@shuyuguo:matrix.org> gathering my thoughts some more: i can live with pipeline because, while i disagree with its motivations there as well (e.g. naming intermediates is too onerous), i have a sense that there is in fact a large number of folks clamoring for it and really want to type it. syntax catering to popularism is fine by me, active harm excepted. but here, i haven't gotten the sense there is a large number of folks clamoring for it I feel like popular syntax has a life span, and pipeline creates a new way to write pretty much anything. So, i feel like it is much more risky than it appears. I really think we should be careful with pipeline. But there is clearly a broader issue here, which multiple proposals touch on, and it doesn't feel like it has been fully expressed yet. [06:15:27.0528] bakkot: that's fair, but that's always a problem; I've seen it happen more than once that such cases end up getting overturned due to newer code (perhaps on other websites) relying on the behavior of a single browser. You cannot win with implementation-defined. [06:17:44.0553] > <@yulia:mozilla.org> I feel like popular syntax has a life span, and pipeline creates a new way to write pretty much anything. So, i feel like it is much more risky than it appears. I really think we should be careful with pipeline. But there is clearly a broader issue here, which multiple proposals touch on, and it doesn't feel like it has been fully expressed yet. The kind of code to which pipeline applies (temp variables to make a transformation tube) is very common. I don't think I've ever come across cases where partial application of a middle argument is necessary. [06:17:56.0369] rbuckton: g is an example of a function on which you get the same thing whether or not you invoke it with new. But most functions aren't like that: function F() {}; const o2 = F(); // undefined const o3 = new F(); // object [06:18:06.0093] > <@rbuckton:matrix.org> ```js > class C {} > function g() { return new C(); } > const o2 = g(); // C {} > const o3 = new g(); // C {} > ``` This is not the same as `new new Function()` [06:18:41.0933] sarahghp: always good to hear a practitioner's take, thanks [06:18:46.0088] I know. [06:18:46.0709] * PFA syntax and bind-this can also work together, when creating bound functions with multiple partially applied arguments, which people sometimes do use `bind` for. From svgo@1.2.2: ```js smartRound.bind(this, params.floatPrecision) x => this::smartRound(params.floatPrecision, x) this::smartRound~(params.floatPrecision, ?) ``` [06:19:32.0303] That was the point I was addressing though. [06:19:53.0697] We're still talking past each other,. [06:20:27.0558] If you wrap new so that it's invoked with a call, it makes no sense to new it again. [06:20:56.0028] We have no concept of a double-new. [06:22:08.0855] const g from the presentation should be only callable, not constructible. [06:22:09.0397] My point was that the behavior is analogous to the `function g() { return new C(); }` example, above. Banning `new g()` seems strange to me, but I'm not opposed to that. [06:23:03.0936] waldemar: I believe ljharb preferred the opposite, that a `new C~()` would *require* `new` at each call site. [06:23:14.0651] No because that function g does the same thing whether you new it or not. Use a function that does something different on new in the example. [06:23:39.0451] bound constructors require `new` at the callsite [06:23:44.0788] so that's the same thing i'd expect here [06:23:47.0464] The approach I went with was to just do what `function g() { return new C(); }` does, in that calling `new g()` isn't valuable but doesn't break anything. [06:24:44.0183] example code: [06:25:02.0653] ```ts const x = module function f(a = expr()) { } ``` [06:25:28.0495] although we know `expr()` must be evaluated in the new module, it's not clear on the syntax [06:26:01.0509] because it didn't have a good visual separator `{ }` [06:26:32.0847] A partial application of `new C~()` would make the `new` part of the result, regardless as to whether `C` is a class or function: ```js function C() { } function g() { return new C(); } const o1 = g(); // C {} const o2 = new g(); // C {} ``` [06:27:16.0051] > <@waldemarh:matrix.org> No because that function g does the same thing whether you new it or not. Use a function that does something different on new in the example. * A partial application of `new C~()` would make the `new` part of the result, regardless as to whether `C` is a class or function: ```js function C() { } function g() { return new C(); } const o1 = g(); // C {} const o2 = new g(); // C {} ``` [06:27:29.0104] The difference is between `C~()` and `new C~()`. [06:30:08.0370] if we don't have `new` in partial application, the behavior is the same as `.bind`: ```js function C() {} const g = C~(); const o1 = g(); // undefined const o2 = new g(); // C {} ``` However, not having `new` feels strange in this example: ```js class C {} const g = C~(); // doesn't throw const o1 = C(); // does throw, must use `new C()` ``` [06:30:16.0095] Process question: What do I do with reviewers? Do I have to collect/write them down somewhere? [06:30:25.0257] * if we don't have `new` in partial application, the behavior is the same as `.bind`: ```js function C() {} const g = C~(); const o1 = g(); // undefined const o2 = new g(); // C {} ``` However, not having `new` feels strange in this example: ```js class C {} const g = C~(); // doesn't throw const o1 = C(); // does throw, must use `new C()` ``` [06:30:53.0872] They're usually added to the notes. [06:31:49.0473] Surma: you may include a list of reviewers to the explainer/README, that's something folks do [06:31:52.0946] > <@rbuckton:matrix.org> if we don't have `new` in partial application, the behavior is the same as `.bind`: > ```js > function C() {} > const g = C~(); > const o1 = g(); // undefined > const o2 = new g(); // C {} > ``` > > However, not having `new` feels strange in this example: > ```js > class C {} > const g = C~(); // doesn't throw > const o1 = C(); // does throw, must use `new C()` > ``` i don't find that example strange because you're not actually invoking `C` in line 2 (unless you're saying people will be confused by PFA syntax and think it's invoking a function). i think `C()` and `g()` should throw the same, though. [06:34:55.0027] https://github.com/tc39/proposal-js-module-blocks/issues/45 [06:36:33.0709] I'm fine with have partial application without `new` (in the partial call), if necessary. I still feel that its unfortunate we don't have a built-in way to allocate a class instance via callback w/o having to defer to arrow functions. If we had `Function.prototype.construct` (to mirror `Function.prototype.call`/`Reflect.construct`) I might be less concerned with supporting `new C~()`. Something like: ```js Function.prototype.construct = function (...args) { return new this(...args); }; class C {} const o1 = C.construct(); // C {} const g = C.construct~(); const o2 = g(); // C {} ``` [06:37:14.0300] But that suffers from the same problem as `Function.prototype.bind`: needing to rely on a method that could be patched at runtime. [06:37:23.0741] Can someone tell me Guy Bedfords association? Or where I can look it up? [06:38:43.0008] I think Guy is an Invited Expert [06:41:06.0188] Stage 3 reviewers PR here! If I missed anyone, please leave a comment :) Thanks to everyone who volunteered! https://github.com/tc39/proposal-js-module-blocks/pull/56 [06:41:09.0283] Guy is a delegate of OpenJS Foundation [06:45:41.0305] I have no normative comments for DurationFormat, but it does still need a bit of editorial work, which we can address during stage 3 [06:48:28.0842] erights: welcome to the matrix [06:48:29.0075] (test please ignore) [06:48:31.0403] > <@surma:matrix.org> Stage 3 reviewers PR here! If I missed anyone, please leave a comment :) Thanks to everyone who volunteered! > > https://github.com/tc39/proposal-js-module-blocks/pull/56 Hi, can you add me too? And I think the sugar and issue 45 are two serious problem, we should not hurry to stage 3 [06:50:58.0404] THanks Jack Works. I’ll add you to the PR [06:52:16.0171] Jack Works: Sorry, what’s your affiliation? [06:55:18.0182] > <@surma:matrix.org> Jack Works: Sorry, what’s your affiliation? Jack-Works on github [06:55:33.0972] > <@michaelficarra:matrix.org> MM is making the exact point I wanted to make: readers are going to have a harder time with this, for basically no benefit I'm not disagree MM, but IMO, hack style pipe have very similar problems. So... [06:55:39.0125] I'm from Sujitech [06:57:37.0274] > <@haxjs:matrix.org> I'm not disagree MM, but IMO, hack style pipe have very similar problems. So... Yeah I agree, but the pipe had so much community demand, we had to do *something* [07:03:07.0293] > <@shuyuguo:matrix.org> gathering my thoughts some more: i can live with pipeline because, while i disagree with its motivations there as well (e.g. naming intermediates is too onerous), i have a sense that there is in fact a large number of folks clamoring for it and really want to type it. syntax catering to popularism is fine by me, active harm excepted. but here, i haven't gotten the sense there is a large number of folks clamoring for it A very controversial questions: how "large number", and what's they really want? I have said many times, as my personal experience, most people who really like pipeline are come from fp community, and pipeline op in their mind === F# style pipeline, but we now go forward hack style... [07:05:29.0951] I just updated the conclusions for the various topics in the notes; presenters, please make sure I captured it accurately [07:08:07.0459] > <@sarahghp:matrix.org> The kind of code to which pipeline applies (temp variables to make a transformation tube) is very common. I don't think I've ever come across cases where partial application of a middle argument is necessary. I'd like to say, if u don't need papp, you will very likely also not need hack style pipeline but only f# style pipeline :-) [07:08:54.0895] i don't need partial application, but i desperately need hack style pipeline, more than i need F# style [07:09:18.0001] (i could use all three for things, but "need" is different than "could use") [07:12:25.0471] Yes, I think I am more in ljharb 's boat there as well. [07:12:38.0966] It's rare I do PFA that bind would not suffice for. [07:13:35.0812] > <@michaelficarra:matrix.org> Yeah I agree, but the pipe had so much community demand, we had to do *something* Well I hope that would be "we had to do something which really match people real requirements" [07:17:00.0765] > <@ljharb:matrix.org> i don't need partial application, but i desperately need hack style pipeline, more than i need F# style This is quite strange, in 80% cases, hack style pipeline can be replaced by f# style + partial application. [07:17:08.0228] can't speak for everyone, but my real requirements are "be able to make nested function calls, some of whose arguments are non-simple expressions, left to right" [07:17:29.0147] what i mean is, i don't need what F# or PFA offers, but of course they can be *used* for what i need [07:17:48.0631] the smallest thing that does what i need tho is hack, and i don't have a need for PFA outside of that. [07:17:52.0554] JavaScript straddles the fence between an OOP-style language and an FP-style language, without really being stellar at either. The partial application and pipeline proposals (in their various forms) have been trying to chip away at the FP-style side since 2018 to improve the language for those folks, similar to the decorators and public/private field proposals trying to chip away at the OOP-style side. [07:18:59.0856] HE Shi-Jun: polling is a hard problem. we'll never really have the resources to do scientific polling. if your question leads to "we should ignore developer signals because we don't have a good enough polling mechanism", that's not a position that reckons with reality [07:19:26.0637] so we do with the best we have, direct constituents we can poll (e.g. internal partners at our workplaces), anecdotes, compelling arguments from delegates, etc [07:19:58.0290] and the sense from those various sources is that there is enough demand for pipelines for us to do something, despite my personal reservations [07:20:23.0753] > <@ljharb:matrix.org> the smallest thing that does what i need tho is hack, and i don't have a need for PFA outside of that. so that's the point, u only want the part which just match your cases, but I don't think it's a good design choice, because separate f# + papp could have better orthogonality and composablity. [07:20:43.0877] I guess — and I am being genuine here — I don't really see how PFA helps with the FP-"flavored" JS with which I am most familiar. The hard-core FP heads already are living their unary lives if the F# threads are to be believed and otherwise idiomatic JS is written so that arguments apply in order or are argument bags. [07:20:49.0307] > <@rbuckton:matrix.org> JavaScript straddles the fence between an OOP-style language and an FP-style language, without really being stellar at either. The partial application and pipeline proposals (in their various forms) have been trying to chip away at the FP-style side since 2018 to improve the language for those folks, similar to the decorators and public/private field proposals trying to chip away at the OOP-style side. * I guess ... and I am being genuine here, I don't really see how PFA helps with the FP-"flavored" JS with which I am most familiar. The hard-core FP heads already are living their unary lives if the F# threads are to be believed and otherwise idiomatic JS is written so that arguments apply in order or are argument bags. [07:21:05.0094] * I guess — and I am being genuine here — I don't really see how PFA helps with the FP-"flavored" JS with which I am most familiar. The hard-core FP heads already are living their unary lives if the F# threads are to be believed and otherwise idiomatic JS is written so that arguments apply in order or are argument bags. [07:21:11.0598] HE Shi-Jun: to be clear, i'm not opposed to F# or PFA, in general or on the basis of "it's more than i need". i'm just pointing out that your assertion that someone who needs hack will also need PFA or F# is incorrect. [07:21:41.0947] * HE Shi-Jun: to be clear, i'm not opposed to F# or PFA, in general or on the basis of "it's more than i need". i'm just pointing out that your assertion that someone who needs hack will also need PFA is incorrect. [07:23:38.0388] * HE Shi-Jun: to be clear, i'm not opposed to F# or PFA, in general or on the basis of "it's more than i need". i'm just pointing out that your assertion that someone who needs hack will also need PFA or F# is incorrect. [07:24:35.0867] zzz time [07:27:03.0931] > <@shuyuguo:matrix.org> HE Shi-Jun: polling is a hard problem. we'll never really have the resources to do scientific polling. if your question leads to "we should ignore developer signals because we don't have a good enough polling mechanism", that's not a position that reckons with reality Obviously I don't say ignore signals. I think everyone who attend the previous meetings should remember I explained many times I think pipeline requirements is very valid. My point is we should also not ignore the other part, especially pipeline op proposal, there are many conflicts in the repos and some are even locked by the champions. And I'm very worry about that what we as committee do on pipeline op, doesn't really solve the requirements of the developers. [07:28:35.0563] But just "give people something". [09:30:00.0278] > <@michaelficarra:matrix.org> legendecas: the downside of `a.b~()` being the only way to bind is that it only allows binding to an object the function is already installed on, not an arbitrary object thanks for the clarification! but doesn't that also indicate that we may have two ways to bind a method to object when bind operators also lands? that can be confusing for developers to choose in between. [09:33:07.0266] And they are both sugars for `Function.prototype.bind` with feature augmentations. [09:41:11.0115] > <@legendecas:matrix.org> And they are both sugars for `Function.prototype.bind` with feature augmentations. I wouldn’t say that bind-this and PFA syntax overlap that much. I wrote about this in https://github.com/js-choi/proposal-bind-this/blob/main/README.md#pfa-syntax. I also have a slide devoted to this in my upcoming presentation about bind-this. [09:42:04.0801] PFA syntax does not address the clunkiness of this: ```js // bluebird@3.5.5/js/release/synchronous_inspection.js isPending.call(this._target()) this._target()::isPending() ``` …or this: ```js // ajv@6.10.0/lib/ajv.js validate = macro.call(self, schema, parentSchema, it); validate = self::macro(schema, parentSchema, it); ``` [09:42:25.0197] Bind-this does not address `fn.bind(null, ...args)`. [09:43:06.0057] At most they overlap somewhat when the receiver object itself contains the function to which we wish to bind. In that case, PFA syntax would be terser than bind-this, because bind-this would require repeating the receiver. ```js n.on("click", v.reset.bind(v)) // Note how v both contains v.reset and is the receiver of the function. n.on("click", v::v.reset) // bind-this n.on("click", v.reset~()) // PFA syntax ``` [09:43:30.0802] * At most they overlap somewhat when the receiver object itself contains the function to which we wish to bind. In that case, PFA syntax would be terser than bind-this, because bind-this would require repeating the receiver. ```js n.on("click", v.reset.bind(v)) // Note how v both contains v.reset and is the receiver of the function. n.on("click", v::v.reset) // bind-this n.on("click", v.reset~()) // PFA syntax ``` [09:44:20.0881] But there are many cases in which it is not the case that you want to bind/call a function on an object that does not already contain that function. In fact, that may be the majority of uses of `.call`. And there are a *lot* of uses of `.call`: it’s one of the most frequently used JavaScript methods. [09:50:12.0040] This is a very detailed explanation, thanks! I'm very eager to see the progress of bind operator. However, I'm a bit concerned that several proposals are trying to do it in different directions and they all overlaps in one use case or another. [09:53:09.0824] That is understandable. Do note that bind-this and PFA syntax could also work synergistically. ```js // svgo@1.2.2/plugins/convertTransform.js smartRound.bind(this, params.floatPrecision) // Original x => this::smartRound(params.floatPrecision, x) // bind-this this::smartRound~(this, params.floatPrecision) // bind-this + PFA syntax ``` [10:00:11.0373] * That is understandable. Do note that bind-this and PFA syntax could also work synergistically. ```js // svgo@1.2.2/plugins/convertTransform.js smartRound.bind(this, params.floatPrecision) // Original x => this::smartRound(params.floatPrecision, x) // bind-this only this::smartRound~(this, params.floatPrecision, ?) // bind-this + PFA syntax ``` Anyways, I view them as pretty orthogonal. I understand Yulia’s desire to see if there’s a grand unifying syntax that could address all of the use cases, but I think the old bind operator kind of tried to do that and got stuck in the muck. bind-this, at least, tries to solve only one problem: .call/.bind are very common but are very clunky. Because of that, it can combine with PFA syntax or the pipe operator or whatever well. [10:00:27.0951] * That is understandable. Do note that bind-this and PFA syntax could also work synergistically. ```js // svgo@1.2.2/plugins/convertTransform.js smartRound.bind(this, params.floatPrecision) // Original x => this::smartRound(params.floatPrecision, x) // bind-this only this::smartRound~(this, params.floatPrecision, ?) // bind-this + PFA syntax ``` Anyways, I view PFA syntax and bind-this (and pipe operator) as pretty orthogonal. I understand Yulia’s desire to see if there’s a grand unifying syntax that could address all of the use cases, but I think the old bind operator kind of tried to do that and got stuck in the muck. bind-this, at least, tries to solve only one problem: .call/.bind are very common but are very clunky. Because of that, it can combine with PFA syntax or the pipe operator or whatever well. [10:05:23.0541] `this::smartRound~(this, params.floatPrecision, ?)` Sorry but I'm confused by this example. Why the first argument of `~()` is been treated as this binding? [10:51:11.0673] HE Shi-Jun: i hear you, but we've been debating "which pipeline" on more principled grounds for _years_ with no real progress [11:14:10.0094] IMO one nice little detail of hack pipes is that they can be slotted into the middle of a method call chain without changing any of the surrounding code ``` arr .map(f) .filter(g) |> customMethod(%) // added in later .reduce(j, unit) ``` [11:17:02.0358] * IMO one nice little detail of hack pipes is that they can be slotted into the middle of a method call chain without changing any of the surrounding code ``` arr .map(f) .filter(g) |> customMethod(%) // added later .reduce(j, unit) ``` [11:17:21.0965] * IMO one nice little detail of hack pipes is that they can be slotted into the middle of a method call chain without changing any of the surrounding code ``` arr .map(f) .filter(g) |> customMethod(%) // added later .reduce(h, unit) ``` [11:25:14.0566] Apologies; I made an error. It should indeed be `this::smartRound~(params.floatPrecision, ?)` to be equivalent to `x => this::smartRound(params.floatPrecision, x)`. I have corrected my previous message. [11:25:20.0507] * That is understandable. Do note that bind-this and PFA syntax could also work synergistically. ```js // svgo@1.2.2/plugins/convertTransform.js smartRound.bind(this, params.floatPrecision) // Original x => this::smartRound(params.floatPrecision, x) // bind-this only this::smartRound~(params.floatPrecision, ?) // bind-this + PFA syntax ``` Anyways, I view PFA syntax and bind-this (and pipe operator) as pretty orthogonal. I understand Yulia’s desire to see if there’s a grand unifying syntax that could address all of the use cases, but I think the old bind operator kind of tried to do that and got stuck in the muck. bind-this, at least, tries to solve only one problem: .call/.bind are very common but are very clunky. Because of that, it can combine with PFA syntax or the pipe operator or whatever well. [11:25:28.0049] > <@legendecas:matrix.org> `this::smartRound~(this, params.floatPrecision, ?)` Sorry but I'm confused by this example. Why the first argument of `~()` is been treated as this binding? * Apologies; I made an error. It should indeed be `this::smartRound~(params.floatPrecision, ?)` to be equivalent to `x => this::smartRound(params.floatPrecision, x)`. I edited my message. [11:26:27.0965] * Apologies; I made an error. It should indeed be `this::smartRound~(params.floatPrecision, ?)` to be equivalent to `x => this::smartRound(params.floatPrecision, x)`. I have corrected my previous message. [12:42:32.0488] > <@aclaymore:matrix.org> IMO one nice little detail of hack pipes is that they can be slotted into the middle of a method call chain without changing any of the surrounding code > > ``` > arr > .map(f) > .filter(g) > |> customMethod(%) // added later > .reduce(h, unit) > ``` the ambiguity on that method access is very scary [12:53:47.0921] how is it ambiguous? 2021-10-26 [18:01:45.0760] another heads up for delegates, about Temporal. we got another spec bug report from two implementors today, and while investigating that one, Justin found another spec bug. I've added the fixes to the slides that I will present on Wednesday, but again since they are late additions, we understand if delegates will need more time to consider them. [20:05:46.0358] Was there no CoC Committee update in the first session? It was on the agenda, but I didn’t hear any update and it’s not in the notes. [01:43:49.0592] No, I think the plan was to have it later. [01:57:38.0797] The Halloween edition of TC39 plenary will begin in 3 mins. [01:59:38.0301] 👻 [02:03:29.0357] I forget it every time: I don't have to fill the form every day, right? [02:03:35.0229] * I forget it every time: I don't have to fill the form every day, right? [02:04:46.0934] correct, nicolo - we keep the same password [02:04:57.0777] we just need each attendee to fill it in once [02:05:04.0355] Ok thanks! [02:10:19.0199] (I had to do it twice because if you don't open matrix in a new window or save the info, you can't get back to it 🙈) [02:16:31.0928] oh hi Surma [02:16:56.0696] 👋 Tierney Cyren [02:17:11.0246] glad to see you here :) [02:18:57.0194] 👋hello [02:20:28.0557] for the notes: frank said 3 PRs, but I can't figure out what the third one was [02:20:30.0481] anyone know? [02:20:32.0697] That looked like it worked. [02:20:41.0480] there was the non-continuous weekend one and the annex A one and then a third one [02:21:19.0898] "canonical"? [02:21:26.0687] ah yes thanks [02:23:22.0818] queue may be confused https://gc.gy/285b32a5-6cd1-4c10-9e9a-8a300f754897.png [02:26:57.0041] an engine could probably do nice stack traces like that itself, no need to include pos in the error [02:30:32.0232] shu: raw returns some magic object that tells json.stringify to use the string as source instead of a string [02:30:59.0641] In the cases where I have needed position information in JSON, I've generally had to rely on something like the TypeScript parser and AST, even in a purely JS project. My use cases so far have been fairly niche, such as doing minor updates to an existing JSON file while preserving the source formatting (usually for JSON files intended to be both human and machine readable such as package.json). [02:39:42.0422] syg: right now, JSON.stringify of an object without a `toString` is guaranteed to do the thing you expect absent a reviver, but if the symbol is shared that's no longer true [02:46:15.0404] Michael Ficarra: I am strongly opposed to having the marker be an object with a symbol here because it implies that the engine will need to do a lookup on every object [02:46:23.0948] which is observable [02:46:53.0114] it's simpler in the sense of "fewer kinds of object in the language", true, but not in terms of "how much observable behavior there is", and the second thing seems like the thing we should be minimizing most of the time [02:48:17.0197] bakkot: fair point [02:49:04.0438] that's a good point [02:49:16.0282] though i don't think a particular problem for performance in the common case [02:49:18.0605] bakkot: how do we ensure these exotic marked objects don't usefully escape the callback? [02:49:31.0682] you don't [02:49:39.0045] is the value of the slot fresh? [02:50:08.0564] oh you mean per-invocation [02:50:28.0599] in terms of spec language you could say its `{[[Index]]: n, [[String]]: s}` [02:50:48.0056] and expect that index back [02:50:55.0002] or you could expect the whole object i guess [02:50:57.0873] cuz it has identity [02:52:14.0216] Michael Ficarra: you can't ensure they don't escape, but like devsnek says you have a field which indicates which invocation it is [02:52:25.0301] s/field/internal slot/ [02:52:28.0336] > <@bakkot:matrix.org> syg: right now, JSON.stringify of an object without a `toString` is guaranteed to do the thing you expect absent a reviver, but if the symbol is shared that's no longer true is that something that's generally depended upon? [02:52:41.0243] ```js let thing; let raw = (v) => { thing = { v }; return thing; }; const result = callback(key, value, { raw }); if (thing && result === thing) { ``` [02:52:48.0816] okay I mean a counter is just a fresh value, so I'm fine with that [02:52:55.0095] like, wouldn't the new guidance be "here's another hook we need, if you hook into it, well, you get hook behavior" [02:52:55.0098] and stringify encounters an object with this slot holding a different value than for the current invocation it can throw [02:53:03.0030] what happens if you call raw multiple times in one callback [02:53:05.0811] * and stringify encounters an object with this slot holding a different value than for the current invocation it can throw [02:53:14.0277] devsnek: same index [02:53:15.0893] i feel like that should work, you could compose a sub-object [02:53:45.0596] Tbh I would expect the argument to `raw` to always be a string [02:53:48.0879] Otherwise it's not raw [02:53:54.0446] no i mean like [02:54:16.0910] `(key, value, { raw }) => ({ a: raw(foo), b: raw(bar) })` [02:54:32.0225] uh ok, that makes sense [02:55:10.0571] For example to represent a `class Fraction { #numerator: bigint; #denominator: bigint }` [02:55:29.0742] * For example to represent a `class Fraction { #numerator: bigint; #denominator: bigint }` [02:55:30.0803] ye you could put a tojson on that [02:55:36.0078] which uses raw [02:56:24.0632] toJson wouldn't get passed `raw` [02:56:25.0492] I think [02:56:41.0445] unless we do the global well-known symbol approach [02:56:55.0938] why does it matter which approach [02:57:00.0399] Can't toJSON receive a parameter even if it's not global? [02:57:04.0150] i think tojson should get to participate [02:57:23.0202] > <@nicolo-ribaudo:matrix.org> Can't toJSON receive a parameter even if it's not global? (it _could_ break something?) [02:57:30.0158] I mean it could but it doesn't in the current proposal [02:57:37.0694] > <@nicolo-ribaudo:matrix.org> Can't toJSON receive a parameter even if it's not global? * I mean it could but it doesn't in the current proposal [02:57:59.0430] also if we're going to let toJson participate I think a well-known symbol would make more sense anyway [02:58:22.0581] since the point of having the per-invocation value is to ensure the stringifier callback has control [02:58:37.0829] and toJson is for giving the objects being serialized control [02:59:24.0444] though, I guess a global well-known symbol means we'd be imposing a cost on all _existing_ serialization calls, which seems bad [03:01:38.0248] extra get per object in the graph to be stringified does seem bad [03:01:47.0170] though isn't that an issue even with a per-stringify symbol [03:02:46.0597] yeah [03:02:54.0437] not with an opaque object though! [03:03:29.0873] well, not an extra get but an extra slot check, which ought to be much cheaper, yes [03:03:37.0761] so, ok, here is an alternate possible design which I don't hate: add a new `JSON.rawString` which returns an opaque, frozen, null-prototype object with a new internal slot holding a string (which has been checked to be valid JSON - maybe even a valid JSON primitive?). this can be called by any code. if JSON.stringify encounters such an object, it serializes it to its internal slot [03:03:59.0955] then toJson can use this function, and revivers can as well [03:04:41.0174] basically just the "allow it to be not per-invocation" approach, but with internal slots instead of symbols [03:04:58.0652] +1 from me. if the opaque object has gensym behavior it also complicates the performance of the slot check [03:05:13.0984] "has gensym behavior"? [03:05:38.0860] https://gc.gy/d9ff7617-8eb7-4039-81bf-ac0201805137.png [03:05:42.0647] the fresh minting behavior where each invocation of stringify has a new kind of opaque object only valid for that invocation [03:06:03.0056] gensym = generate symbol? [03:06:12.0792] yeah [03:06:31.0032] it's the scheme thing that returns fresh symbols [03:09:52.0872] I know what gensym is but am confused about how it affects GC here [03:10:24.0663] oh, unless you're thinking about the GC of the underlying string? [03:10:45.0637] I would just not worry about the fact that holding the opaque object holds the string, I guess [03:10:55.0827] no not gc [03:11:25.0989] i meant the "is this one of them opaque objects" checks [03:11:32.0837] oh [03:11:58.0170] I mean, you check if it has the slot, and then if it does you check if the value for the slot matches the value for the current invocation [03:12:01.0337] seems not so bad [03:12:13.0277] and it's just the presence-of-slot check which gets paid by code not using this capability [03:14:35.0097] agree, seems not so bad [03:15:45.0763] yeah I favour this raw function that returns an object with an internal slot with index (or two such slots) option now [03:15:53.0600] github issue: https://github.com/tc39/proposal-json-parse-with-source/issues/19 [03:16:33.0094] Michael Ficarra: https://github.com/tc39/proposal-json-parse-with-source/issues/18#issuecomment-951789801 [03:16:36.0117] Michael Ficarra: what index? the per-invocation counter? [03:16:50.0725] ehh, i'd still rather we just have global [03:17:20.0845] The only issue I see with an exotic object is if you write any custom JSON serialization logic today in a replacer/reviver, you would need to be able to test whether the object is one of these exotic objects so you can pass it through rather than trying to convert it yourself. [03:17:35.0260] yes, per-Json-stringify counter and possibly a per-callback counter [03:17:45.0458] i am against a per-callback counter [03:17:58.0783] that's probably fine shu [03:18:15.0671] i am also against a per-invocation counter and favor bakkot's concrete alternative, to be clear [03:18:21.0848] but i am more against per-callback counter [03:18:29.0263] So you need both a `JSON.rawSting` and a `JSON.isRawString`, otherwise it comes *harder* to write serializers/deserializers. [03:18:53.0953] what do you do with isRawString [03:19:58.0906] If you do custom serialization of any kind you need to know if the object you get in your custom serializer/replacer is this special exotic object or some other object. [03:20:35.0846] fwiw, in the R&T repository there has been a bunch of discussion about tagged strings (https://github.com/tc39/proposal-record-tuple/issues/258#issuecomment-947115796). This feels similar, since it's a string tagged with `JSON.rawString`. (we are not looking to include tagged strings in the R&T proposal) [03:20:49.0528] why do you need to know [03:20:53.0010] * fwiw, in the R&T repository there has been a bunch of discussion about tagged strings (https://github.com/tc39/proposal-record-tuple/issues/258#issuecomment-947115796). This feels similar, since it's a string tagged with `JSON.rawString`. (we are not looking to include tagged strings in the R&T proposal) [03:21:55.0777] > <@nicolo-ribaudo:matrix.org> fwiw, in the R&T repository there has been a bunch of discussion about tagged strings (https://github.com/tc39/proposal-record-tuple/issues/258#issuecomment-947115796). This feels similar, since it's a string tagged with `JSON.rawString`. > > (we are not looking to include tagged strings in the R&T proposal) this issue makes me very sad, previously we said that Box(v) should always work without you having to care what v is [03:22:25.0904] A naive replacer might do: ```js function serializer(value) { if (typeof value === "object") { if (Array.isArray) { ... } const result = {}; for (const key in value) { ... } return result; // uh oh, we've replaced the exotic object with an empty normal object. } ... } ``` [03:22:51.0618] If there's no way to test, you have to expect to pass through objects with no keys, which adds complexity. [03:23:08.0765] rbuckton: `JSON.isRawString = o => o && typeof o === 'object' && !(toJSON in o) && !['{', '['].includes(JSON.stringify(o))` [03:23:13.0692] > <@nicolo-ribaudo:matrix.org> fwiw, in the R&T repository there has been a bunch of discussion about tagged strings (https://github.com/tc39/proposal-record-tuple/issues/258#issuecomment-947115796). This feels similar, since it's a string tagged with `JSON.rawString`. > > (we are not looking to include tagged strings in the R&T proposal) I really don't like attaching state to strings or any object in a way that is not only immediately consumed [03:23:36.0064] if we do that, we'd have to at least have a testing function like what Ron's talking about [03:23:57.0006] but then you force anyone using this feature to test anything that goes into their returned object [03:23:59.0872] > <@bakkot:matrix.org> rbuckton: `JSON.isRawString = o => o && typeof o === 'object' && !(toJSON in o) && !['{', '['].includes(JSON.stringify(o))` (assuming that `isRawString` enforces that its argument is a primitive JSON string or digit sequence) [03:24:05.0902] The upside of a symbol is its something you can check for. [03:24:09.0259] (to be clear, not saying this is great, just saying that it's possible-ish without a new function) [03:24:25.0076] > <@bakkot:matrix.org> rbuckton: `JSON.isRawString = o => o && typeof o === 'object' && !(toJSON in o) && !['{', '['].includes(JSON.stringify(o))` A `JSON.rawString("{}")` would be observabily the same as `Object.freeze({ __proto__: null })` [03:24:47.0271] bakkot: So, your suggestion is to JSON.stringify an arbitrarily complex/large object that may have its own nested toJSON just to check for an exotic raw string object? [03:24:56.0523] nicolo-ribaudo: "assuming that isRawString enforces that its argument is a primitive JSON string or digit sequence" [03:25:19.0393] > <@bakkot:matrix.org> nicolo-ribaudo: "assuming that isRawString enforces that its argument is a primitive JSON string or digit sequence" Whops, I didn't read it [03:25:26.0049] rbuckton: you can add `Object.keys(o).length === 0` if you're worried about that [03:25:27.0524] It would have to be much more robust, checking for null prototype, no properties, etc. [03:26:57.0391] bakkot: More like `Object.getPrototypeOf(o) === null && Object.getOwnPropertyNames(o).length === 0 && Object.getOwnPropertySymbols(o).length === 0` etc. [03:27:13.0332] unless you're concerned about proxies, I don't think you need those additional checks [03:27:58.0078] no non-exotic object can have the behavior that `toJSON` is absent and also `!['{', '['].includes(JSON.stringify(o)[0])` [03:27:59.0560] In which case I point you at `Array.isArray`, which is better (and more reliable) than `o => typeof o === "object" && o !== null && Object.prototype.toString.call(o) === "[object Array]"` [03:28:19.0009] * no non-exotic object can have the behavior that `toJSON` is absent and also `!['{', '['].includes(JSON.stringify(o)[0])` [03:28:49.0505] I thought rawString could return a string that contains any valid JSON. Couldn't you do `JSON.rawString("{}")`, and wouldn't that fail the check? [03:29:01.0104] rbuckton: "assuming that isRawString enforces that its argument is a primitive JSON string or digit sequence" [03:29:19.0915] which I think it should, separately from this concern [03:29:32.0823] (otherwise you can abuse it to add whitespace, which seems bad) [03:29:34.0876] That's fair, but you're still requiring a fairly complex check that could be more easily exposed by the language. [03:29:45.0512] yeah [03:30:02.0503] like I said, not saying my proposal is great, just that it's possible-ish [03:30:12.0142] though I guess you _do_ also need to check for boxed numbers / strings, which is also annoying [03:30:30.0178] so yeah it seems reasonable to add `isRawString` [03:31:08.0249] An `isRawString` shim is much more complex than an `isArray` shim, which means its much easier to get wrong if you're rolling your own serializer (which, I would argue, is the exact situation you're in if you're using this functionality). [03:32:11.0985] is there a good way for me to get involved in the LF discussion meetings? [03:32:32.0203] Tierney Cyren: you may join this ad-hoc group [03:32:40.0784] I've wanted to participate but how is unclear and I've not gotten around to asking [03:32:50.0087] write an email to Patrick and he'll add you to the mailing list/event [03:32:53.0565] * write an email to Patrick and he'll add you to the mailing list/event [03:33:29.0870] talk to Isabelle, I think she's responsible for getting everyone interested from MS involved [03:46:23.0686] $4m seems like a lot but what's the actual runway that provides? [03:46:57.0054] that number does not feel helpful in a vacuum [04:59:38.0630] we are starting up plenary in 1 minute! [05:06:00.0779] it also happened with NativeError.prototype.toString lol [05:06:53.0237] chrome had that from 2016 to 2019 until i removed it [05:09:53.0861] instead of tightening host restrictions, can't we just make a section of test262 which is like "okay to fail, but should probably be looked at because it's more likely a bug"? [05:10:13.0843] i was just thinking that [05:10:19.0127] like a common-sense directory lol [05:10:27.0077] Michael Ficarra: yes, i plan to bring that up [05:10:37.0479] i object to this proposal [05:10:38.0155] thanks shu [05:10:43.0678] what is this proposal [05:10:48.0243] but i'll wait for jordan to actually say the proposal first [05:10:48.0516] i haven't made it yet. [05:10:51.0026] before i add myself to the queue [05:11:00.0642] i assume its restricting names on prototypes or smth [05:11:59.0335] test262-parser-tests has a "fail" directory which is spiritually the same: https://github.com/tc39/test262-parser-tests/tree/master/fail [05:12:29.0059] "Any property on a given object mentioned in the specification, must ONLY appear in the locations specified on that object or its prototype chain" [05:12:37.0684] > <@michaelficarra:matrix.org> test262-parser-tests has a "fail" directory which is spiritually the same: https://github.com/tc39/test262-parser-tests/tree/master/fail good filenames [05:13:17.0122] hey you try naming files with random non-programs [05:13:29.0615] pull requests welcome [05:14:17.0867] are the names just a hash of the source code or sth? [05:14:22.0438] * are the names just a hash of the source code or sth? [05:14:24.0800] yep ryzokuken [05:14:43.0750] i like test262 names [05:17:07.0705] man I gotta update that project [05:17:10.0984] `test-assignment-really-terribly-bad.js` [05:19:26.0096] would we need work in e.g. test262.report if we add a new test category? [05:21:04.0517] test262.report is bocoup right [05:21:38.0729] Yeah [05:23:17.0920] I wonder if there are test cases we would like to add to 262 aside from things we feel bold enough to tighten that would nonetheless be useful for impls? I seem to recall tests in this category back in the day but have forgotten [05:23:48.0223] gc tests :P [05:26:36.0265] devsnek: you ready to present extending null next? [05:26:42.0857] yep [05:26:54.0805] assuming i haven't fallen asleep by then [05:27:03.0867] do not fall asleep 😁 [05:27:43.0043] > <@devsnek:matrix.org> gc tests :P Well for what it's worth, all those are busted right now (relies on removed `cleanupSome`). I have on my todo list of fixing all these [05:28:04.0356] i'm still sad about cleanupsome being separated [05:28:24.0140] Justin Ridgewell: if we need to pull in items today, are you available to present destructure private fields? [05:38:33.0059] NativeError.prototype.toString on v8 only shadows Error.prototype.toString uselessly [05:51:29.0767] hm i didn't really have a position [06:02:12.0569] lol ok i am going to be the only one maybe [06:05:18.0276] Could `super()` just be a no-op in `class extends null`? [06:05:51.0421] yulia: someone brought up the possibility of `class extends void {}` for a statically-analyzable version of `null` [06:06:02.0219] she brought that up, yeah [06:06:08.0462] oh yeah [06:06:09.0129] i guess some SM engineers thought it odd because (void 0) is undefined? [06:06:12.0381] sorry I'm tired [06:06:14.0960] yeah [06:06:17.0908] that doesn't seem like a very big objection, though [06:06:22.0449] the void 0 thing [06:06:35.0608] yeah i think it works kind off well personally [06:06:46.0338] it's super weird to not allow `extends X` for any valid X, and to force `null` to have a special syntactic form [06:06:51.0743] * it's super weird to not allow `extends X` for any valid X, and to force `null` to have a special syntactic form [06:07:12.0302] null objects aren't supposed to be special, from a conceptual standpoint [06:07:16.0424] * null objects aren't supposed to be special, from a conceptual standpoint [06:07:21.0759] `null` was already special [06:07:27.0342] you have to extend a _constructor_ [06:07:31.0571] there is nothing weird about `null` not working [06:07:34.0732] i would consider null special [06:07:40.0595] it was always going to be special-cased [06:07:47.0892] Besides, you can't write `class extends void 0` since a `void` expression isn't a LHS expression [06:07:54.0373] the weird thing is that we special cased it to not throw on definition [06:08:21.0550] if we can do this from a syntax perspective, i don't mind if super == this [06:08:23.0106] thats fine [06:08:56.0812] We could always have a shared %NullConstructor% that you assign as the base for `class extends null` so that `super()` could work. [06:11:45.0179] i.e., change 8.f.ii. of ClassDefinitionEvaluation to be `Let constructorParent be %NullConstructor%.`, where %NullConstructor% is a built-in function purely for the purpose of supporting `super()`. [06:11:57.0013] * i.e., change 8.f.ii. of ClassDefinitionEvaluation to be `Let constructorParent be %NullConstructor%.`, where %NullConstructor% is a built-in function purely for the purpose of supporting `super()`. [06:11:57.0940] yulia: could you expand a bit on the runtime problem in SM? [06:12:20.0568] basically, we won't be able to determine which bytecode we need to use until we execute it [06:12:33.0454] bytecode for what operation? [06:12:56.0362] for the look up of the prototype iirc [06:13:08.0887] im trying to find the notes just a sec [06:13:14.0532] thank you [06:13:38.0932] "In this proposal if the base is null, the spec is asking for the constructor to still extend Function.prototype (which is reasonable enough). Normally we pull the super target function off the constructors own prototype while running, but in this case we also need to check elsewhere to find the original heritage to know if it was null vs explicitly Function.prototype. This can be fixed for us by adding the original heritage (or at least a flag) to the JSFunction of the constructor. Problem is we don't really have a lot of spare slots or flags on functions themselves" [06:14:08.0469] Mathieu Hofman: it's not a base class _unless_ it inherits from Object. [06:14:33.0585] perhaps base classes should all have extended null, and `extends Object` should have been required to make something inherit from Object.prototype, but that ship's long gone [06:14:42.0458] ooh, i see [06:14:58.0650] that makes sense, yes, that's a bigger problem, in its requiring two bits of info [06:17:10.0037] (totally fine with me if the constructor itself also inherits from null) [06:17:13.0060] * (totally fine with me if the constructor itself also inherits from null) [06:17:30.0666] the custructor should not inherit from null [06:17:37.0807] > <@ljharb:matrix.org> (totally fine with me if the constructor itself also inherits from null) This is problematic if you want to use `.bind` [06:17:38.0370] that makes the function prototype methods not available [06:18:01.0909] yes gut reaction for not having F.p methods on the constructor is "oof" from me [06:18:25.0227] Function.prototype.bind.call etc, which is already what robust code does [06:18:32.0122] do people use function prototype methods on constructors? [06:18:34.0024] ljharb: no code does that [06:18:39.0324] lol most doesn't, sure [06:18:45.0731] your code, my code, a couple of polyfills, and no one else in the entire world [06:18:48.0016] but how often are you binding constructors either [06:18:52.0731] not never! [06:19:18.0070] `⊤ class` [06:19:39.0622] that's `Object` [06:19:51.0783] or, well [06:19:54.0837] a _second_ top class [06:19:56.0206] i guess we don't really have a lattice [06:20:03.0242] TIL bound functions proxy [[Construct]] [06:20:04.0898] create your own! [06:21:47.0743] yulia: if the word `extends` appears then it's not a base class [06:22:14.0520] haha shu i was just thinking about structs [06:22:16.0721] a base class is `class {}` which includes inheriting from Object [06:22:34.0158] that is not the usual OO understanding of "base class" [06:22:35.0156] > <@ljharb:matrix.org> yulia: if the word `extends` appears then it's not a base class with this pr that's not true [06:22:56.0750] i don't care what the spec says about what's base/derived, i'm concerned with what users think [06:23:03.0126] i feel like this isn't a useful direction for the discussion? there are many ways to read it and virtual classes are really useful [06:23:09.0624] and the syntax determines that imo, not theoretical inheritance models [06:23:21.0660] so, i am happy to consider other syntax [06:23:32.0942] like, very much -- we don't have to have extends at all [06:23:40.0335] > <@ljharb:matrix.org> and the syntax determines that imo, not theoretical inheritance models fairly strong disagree, actually, class hiearchies are very conceptual [06:24:31.0407] if that were broadly true then there would have been outcry that default class inheritance wasn't null [06:24:48.0776] Object.prototype isn't a "top class" because you can have things that don't inherit from it [06:24:55.0424] a base class is defined in relation to a class definition. In `class B extends A {}`, `A` is a base class in that `B` derives from `A`. `B` could always be the base class for another definition (i.e., `class C extends B {}`). [06:25:19.0226] i meant more like "top of a lattice" [06:25:33.0691] You can say that `B` is a subclass, and that `class A {}` is not a subclass [06:25:34.0043] ron's right on general use of "base class", ime [06:25:40.0505] i suspect i'm not familiar with that term in the way you're using it (lattice) [06:25:57.0285] strong agree with shu here [06:26:00.0718] > <@rbuckton:matrix.org> a base class is defined in relation to a class definition. In `class B extends A {}`, `A` is a base class in that `B` derives from `A`. `B` could always be the base class for another definition (i.e., `class C extends B {}`). I probably should have said "root class" [06:26:42.0253] `🌱 class {}` [06:26:59.0201] [joke] [06:27:32.0401] I am going to drop in 3 min, and caroline will take over for mozilla [06:27:51.0111] so, any further questions on the null stuff, just dm me and ill get to it when im back [06:30:53.0343] ljharb: "root class" is just as cromulent for what i mean, the thing hierarchies top out at [06:31:11.0923] like, surely it's not just syntax, because we set up class hierarchies before `class` syntax was added [06:31:16.0703] and people understood them just fine [06:33:06.0342] sure but in those cases null and a constructor were 100% interchangeable [06:33:33.0178] you did have to either omit or conditionally call a superclass constructor, to be fair, but there wasn't a syntactic requirement around `super` there [06:38:55.0393] rbuckton: if we need will you be able to bring forward a regexp item to today? [06:39:35.0833] `Uint8Array.fromAsync(reader)` 👀 [06:39:53.0068] I personally do not think it's weird to have 2 ways to express syntactically a root class: `class {}` or `class extends void {}`. In both cases no `super()` would be allowed [06:40:13.0299] a root class doesn't extend anything. [06:40:25.0633] `root class {}` or something would at least not have that confusion [06:40:31.0898] bterlson: That would be fine [06:40:47.0377] My understanding is that in english `void` is nothing ;) [06:41:02.0678] `void` produces `undefined` which is a reified thing, not the absence of a thing [06:41:12.0038] * `void` produces `undefined` which is a reified thing, not the absence of a thing [06:41:13.0253] technically in english void and null are synonyms [06:41:27.0031] no, `void expr` produces `undefined` [06:41:37.0650] `class {}` does not literally "not extend anything" either - it extends `Object.prototype` [06:41:41.0180] right, currently that's the only way JS supports using `void` [06:41:52.0191] but, the way you think about it is that it does not extend anything [06:41:57.0101] bakkot: yes, that's true as well. but it's not explicitly claiming to not extend [06:44:07.0850] my point is that "`void` produces `undefined` which is a reified thing, not the absence of a thing" is true in a technical sense but it is also true in a technical sense that `class {}` is a base class but also extends `Object.prototype`, if you are being that kind of precise. on the other hand, _colloquially_ it is understood that `class {}` is a base class, and I argue that _colloquially_ it would be easily understood that `extends void` means "does not extend anything" [06:44:48.0340] i would do `null class Foo {}` [06:45:37.0917] `const o = null { a: b }` when [06:45:49.0978] there's already __proto__ syntax tho [06:45:56.0206] wait hold on [06:46:02.0339] `class Foo { __proto__: null }` [06:46:11.0155] what does that do [06:46:29.0963] with the colon, it's a syntax error, in TS i'm not sure [06:46:32.0171] oh wait it uses DefineOwnProperty [06:46:34.0853] Its a SyntaxError :) [06:46:48.0654] `__proto__ = null` would probably create a public class field, or throw, not sure [06:46:50.0895] can someone put in a conclusion for the previous agenda item in the notes [06:46:51.0749] man i really wish class fields used Set [06:46:54.0757] In TS its says you have a field named `__proto__` whose type is `null`. [06:47:03.0073] I am so glad class fields do not use Set [06:47:11.0311] (re conclusion) there really isn't one i think, it's an update [06:47:16.0219] * (re conclusion) there really isn't one i think, it's an update [06:47:21.0307] galaxy brain is: what if object literals used set [06:47:25.0667] they used to [06:47:30.0514] lol [06:47:45.0038] ok so we just need to special case [06:47:49.0233] `__proto__ = null` in classes [06:48:11.0416] ``` The production PropertyNameAndValueList : PropertyName : AssignmentExpression is evaluated as follows: 1. Create a new object as if by the expression new Object(). 2. Evaluate PropertyName. 3. Evaluate AssignmentExpression. 4. Call GetValue(Result(3)). 5. Call the [[Put]] method of Result(1) with arguments Result(2) and Result(4). 6. Return Result(1). ``` ~ ES3 [06:48:21.0994] * ``` The production PropertyNameAndValueList : PropertyName : AssignmentExpression is evaluated as follows: 1. Create a new object as if by the expression new Object(). 2. Evaluate PropertyName. 3. Evaluate AssignmentExpression. 4. Call GetValue(Result(3)). 5. Call the [[Put]] method of Result(1) with arguments Result(2) and Result(4). 6. Return Result(1). ``` ~ ES3 [06:48:32.0071] is that SSA [06:49:31.0362] > <@devsnek:matrix.org> `__proto__ = null` in classes Except that already has a well-defined behavior: ``` > class C { __proto__ = null; } undefined > var o = new C(); undefined > o C { ['__proto__']: null } ``` [06:49:42.0800] bakkot: wtf [06:49:43.0167] ya ik :( [06:50:03.0520] Just need decorators: ```js @extendsNull class C {} ``` [06:50:28.0467] shu: yeah it was a wild time [06:50:30.0046] rbuckton: doesn't matter if nobody relies on it [06:50:33.0887] i need to convert more people to my function decorator cult [06:50:50.0865] devsnek: I'm always willing to try a new cult [06:51:19.0046] > <@devsnek:matrix.org> i need to convert more people to my function decorator cult But the hoisting problem though [06:51:43.0155] that kind of hoisting is almost never used in practice [06:51:53.0542] i don't know a case where its *needed* [06:52:03.0123] Function expression decorators: ✔️ Function declaration decorators: ☠️ [06:52:32.0194] i seriously believe we can do decorators on function declarations by just not hoisting the function value [06:52:35.0393] > <@devsnek:matrix.org> that kind of hoisting is almost never used in practice That kind of hoisting is about 80% of the TypeScript compiler [06:52:38.0027] no one will notice [06:52:41.0101] i definitely hoist a lot of functions [06:52:52.0267] on the other hand, decorators are bad, so I'm ok with them being harder to use :P [06:52:52.0383] but do you call them before their declaration [06:52:54.0432] or just refer to them [06:52:57.0299] devsnek: yes [06:53:00.0976] call them [06:53:06.0164] ok but [06:53:07.0652] you can just [06:53:10.0739] not put decorators on that code [06:53:11.0385] functions go at the bottom, logic goes at the top [06:53:15.0922] (for scripts) [06:53:29.0103] its a simple choice [06:53:49.0992] At one point I was thinking about this: ```js // not hoisted // not reassignable const function f() {} // ok @dec const function f() {} // syntax error @dec function f() {} ``` [06:54:10.0778] as a shorthand for `const f = function () {}` [06:54:14.0622] ron i won't accept stylistic practice from the typescript compiler source [06:54:18.0586] `const function` means a different thing [06:54:19.0331] until you get rid of the 40k line file [06:54:45.0814] > <@bakkot:matrix.org> `const function` means a different thing in some languages, yes. [06:55:06.0543] Either way, I'm all for function expression decorators. [06:55:20.0020] anyway i think this would work in practice and i encourage some company that has resources to do research to research it [06:55:25.0621] Just not a fan of adding a decorator breaking hoisting on a function declaration. [06:56:20.0864] i don't think it counts as "breaking" as much as a tradeoff, it certainly doesn't have any impact on existing code [06:56:22.0803] since it also can break circular imports [06:56:25.0685] * i don't think it counts as "breaking" as much as a tradeoff, it certainly doesn't have any impact on existing code [06:56:31.0782] it can't break circular imports [06:56:42.0301] re: the actual presentation, I strongly agree with WH [06:56:50.0500] sqrt is good, we should have it [06:56:54.0464] i mean it can break stuff but that's unrelated to the circular importing [06:57:05.0628] Its the same hoisting problem. Hoisted functions are reachable in a circular import. [06:58:19.0238] right i'm just saying the base case is unchanged and the worst case is the same case as an undecorated class or a variable decoaration [06:58:25.0129] > <@devsnek:matrix.org> i don't think it counts as "breaking" as much as a tradeoff, it certainly doesn't have any impact on existing code The problem with existing code is that existing code is some the code I want to decorate, and adding a decorator would change the semantics in a non-obvious way. [06:58:57.0675] its the same hazard as migrating function to class [06:59:56.0584] There's a hidden hazard with decorators that doesn't exist when you're changing `function` -> `class`, in that its still `function`. [07:00:11.0122] adding a decorator to something definitely risks all sorts of breakage; it's not something you can expect to do transparently [07:00:41.0841] If someone is using TypeScript (or JS with the TS language service), we could give you errors on decorated function decls. [07:00:53.0798] you could do that when it breaks hoisting too [07:01:12.0420] (not arguing for breaking hoisting, necessarily, but none of those are compelling arguments against doing so to me) [07:01:19.0146] p sure the two most popular eslint configs yell at you about hoisting and circulars, separately [07:01:27.0805] * p sure the two most popular eslint configs yell at you about hoisting and circulars, separately [07:02:35.0068] anyway that's my hill [07:03:05.0385] honestly i don't even know what i would use decorators on classes for lol [07:03:35.0133] and yes i know there are use cases, that's just where i'm at personally [07:03:52.0407] i very much want ``` @bound method () {} ``` to be a thing [07:03:55.0511] > <@devsnek:matrix.org> honestly i don't even know what i would use decorators on classes for lol I use them in TS for so many things. [07:04:12.0063] I want function decorators, but I also want parameter decorators. [07:04:17.0423] i just want `@router.get('/foo') function getFoo() {}` [07:04:54.0491] why that over `router.get('/foo')(function getFoo() {})`? [07:05:09.0969] because that's ugly and weird [07:05:33.0521] and it doesn't compose well [07:06:03.0223] `@get('/foo') @loginRequired({ admin: true }) @ratelimit(4, 1) function getFoo() {}` [07:06:25.0007] `|>`? [07:06:26.0299] One reason: ```js const getFoo = router.get('/foo')(() => {}); getFoo.name; // "" // vs const getFoo = @router.get('/foo') () => {} getFoo.name; // "getFoo" ``` [07:06:35.0219] lol [07:06:47.0583] lol fair, but that's not compelling to me; if you want a name don't use arrows [07:06:55.0959] i do not like expression position decorators lol [07:06:56.0082] i will always believe FNI was a mistake [07:07:36.0203] ljharb: You want `@bound`, let the snek have `@dec function f() {}`. [07:07:41.0941] FNI was a mistake only if you think name is anything other than a debugging facility [07:07:45.0279] lol [07:08:05.0244] > <@michaelficarra:matrix.org> FNI was a mistake only if you think name is anything other than a debugging facility i think it's a mistake BECAUSE it's a debugging facility. inferred names are harder to grep for. [07:08:23.0580] > i just want `@router.get('/foo') function getFoo() {}` oh god, this is the strongest argument against function decorators I've yet seen [07:08:29.0928] just have a code server that supports fni [07:08:39.0390] if people are going to write code like that we should not have function decorators [07:09:21.0767] like what [07:09:23.0106] The VS Code codebase uses so many parameter decorators for DI, we really need parameter decorators shortly after class/member decorators. [07:09:25.0647] oh [07:09:35.0044] bakkot: have you never used flask in python [07:09:43.0452] devsnek: yeah, it's _awful_ [07:09:43.0847] its incredible [07:09:48.0036] lol [07:09:50.0095] Parameter decorators are so much higher on my list of priorities than function decorators, tbh. [07:09:52.0032] especially debugging other people's flask apps [07:09:58.0096] just instantly unmaintaintable nightmares [07:10:11.0771] idk i love it [07:10:20.0312] aside from the globals [07:10:21.0770] Worst case, you can do: ```js const { getFoo, ... } = class { @router.get("/foo") static getFoo() {} }; ``` [07:10:22.0704] should've been function parameters [07:15:30.0244] at a deep level i really do not get dependency injection [07:17:19.0635] i do not like DI [07:29:39.0906] but what is it? [07:29:54.0987] is it just passing parameters or is there some gestalten design thing i'm not getting [07:30:35.0208] Yeah. It’s just passing parameters. [07:32:53.0552] but then you need parameter decorators for some reason [07:34:35.0287] It’s kind of like the opposite of `import` in that…if A needs B and B needs C—instead of B pulling in specifically C for itself—B defines a parameter, A pulls in B and C, and A plugs C into B’s parameter. [07:35:14.0141] So A can switch C with something else compatible with B’s parameter before plugging it into it. [07:35:42.0463] * So A can switch C with something else compatible with B’s parameter before plugging it into it. [07:35:58.0668] most DI is something like taking parameters for your dependencies, but the actual construction of your object graph is handled by a composer. [07:36:17.0072] It allows you to substitute dependencies for testing or even at runtime based on circumstance. [07:38:38.0172] Whenever we need to refer to another variable elsewhere, we always face the choice of (1) defining it as a function parameter to be plugged in later or (2) importing it and hardcoding the dependency. There’s nothing special about that choice; it’s just an everyday thing. [07:40:08.0940] Although like Ron said, some people use elaborate composer systems that try to abstract away this plugging in for you. [07:40:33.0061] DI using parameter decorators is something like: ```js // service-c.js class ServiceC { constructor( @inject("service-a") serviceA, @inject("service-b") serviceB ) { ... } } // main.js import { ServiceA } from "./service-a.js"; import { ServiceB } from "./service-b.js"; import { ServiceC } from "./service-c.js"; const container = new ServiceContainer(); container.addClass("service-a", ServiceA); container.addClass("service-b", ServiceB); container.addClass("service-c", ServiceC); const instance = container.getService("service-c"); // gets or creates a ServiceC from the container ``` [07:41:48.0181] And in test code, you can do: ```js import { ServiceC } from "./service-c.js"; it("test the service", () => { const mockServiceA = { ... }; const mockServiceB = { ... }; const serviceC = new ServiceC(mockServiceA, mockServiceB); // test serviceC using mock behavior from dependencies }); ``` [07:43:27.0872] Of course, `main.js` is a contrived example. Many DI containers are fairly flexible, allowing you to specify optional dependencies, aggregate dependencies, nested containers, disposable containers (to manage component lifetime), etc. [07:43:56.0046] As well as lazily-injected circular dependencies using field decorators. [07:54:27.0926] and why would i want to do this? [07:56:59.0879] You would want to do this if you're a very large application that wants to break itself into smaller components for ease of maintenance, or support pluggability/extensions. [07:58:04.0993] Its a fairly common idiom across any number of programming languages. Its primarily used server-side or in desktop applications, though not so much in the browser. [07:58:29.0964] the easiest to maintain thing is the thing i can read [08:00:47.0248] Like anything, once you understand the system its fairly easy to read. [08:08:05.0784] The VS Code system has a decorator factory that is used to create the actual decorators used for injection, and names the decorators to coincide with the interface name of the expected input. As a result, your code looks something like (in TS): ```ts // themeService.ts // describe the service interface export interface IThemeService { getColorTheme(): IColorTheme; readonly onDidColorThemeChange: Event; getFileIconTheme(): IFileIconTheme; readonly onDidFileIconThemeChange: Event; } // create a decorator for the service export const IThemeService = createDecorator(); // editor.ts import { IThemeService } from "./themeService"; export class EditorService { themeService: IThemeService; constructor( @IThemeService themeService: IThemeService ) { this.themeService = themeService; } // code that uses themService } ``` [08:10:50.0567] All the decorator does is provide the glue that the composition plumbing uses. The idea is fairly similar to context providers in React. I don't have to dig around in the plumbing of my application to find and use a dependency, I merely need to declare that I require the dependency and the composition runtime will either provide it, or fail to compose early because of an unsatisfied dependency. [08:11:23.0471] Its also much like a module import graph, except that you have more control over lifetime of the entire dependency graph. [08:12:58.0855] The Managed Extensibility Framework (MEF) API in .NET is another example of a DI system, and it actually uses `Import` and `Export` attributes to define dependency relationships within a DI container. [08:17:37.0072] this seems like an invitation to write unnecessarily complex code ... the virtue of low-magic is links are really clear (I also don't really like `context` in React tho) [08:18:01.0982] to be verbosely clever instead of code-golf-style tersely clever [09:01:50.0635] does anyone have a good resource for descriptions of non-standard JS extensions over the years? as-in, pre-harmony stuff that got removed like conditional catch / let blocks / etc [09:03:41.0244] rubber duck method, i guess this is a good resource: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features [09:07:09.0149] Doesn't list E4X! [09:07:40.0370] Microsoft JScript had a special `::` syntax for events, I believe. (CC: rbuckton) [09:07:43.0593] * Microsoft JScript had a special `::` syntax for events, I believe. (CC: rbuckton) [09:08:56.0369] And JScript supports `expr() = expr2`? [09:10:44.0679] what does that do? [09:11:11.0372] Golly, I do not remember. I wish there were still resources about this. 😔 [09:12:45.0156] > <@rick.button:matrix.org> what does that do? IDK, just heard of that [09:13:52.0212] > <@rick.button:matrix.org> what does that do? I think it was to allow things like `eval("x") = 2`, but I might be wrong [09:15:36.0008] wild [09:16:20.0368] `eval("x") = 2` is what engine developers fear [09:16:30.0209] * `eval("x") = 2` is what engine developers fear [09:23:47.0870] Ok, maybe it wasn't for eval: the ES 1 specification, at paragraph 11.2.3, says that any host function can return a reference, but `eval` doesn't [09:24:41.0484] * Ok, maybe it wasn't for eval: the ES 1 specification, at paragraph 11.2.3, says that any host function can return a reference, but `eval` doesn't [09:26:41.0523] You can do `(x) = 2` today, but you can't do `({ x }) = { x: 2 }`. [09:28:33.0359] not a non-standard extension, just an idiosyncrasy of the language [09:29:07.0098] We are taking about `fn(x)=2`, not `(x)=2`! [09:48:06.0586] can anyone read through https://tc39.es/ecma262/#sec-number.prototype.toexponential and confirm whether `0.0.toExponential(2)` should be `'0.00e+0'` vs `'0e+0'`? [10:05:47.0965] uh, looks like 0.00e+0 [10:06:16.0464] `f` is 2, so step 9.a says `m` is `"000"` [10:06:27.0487] then step 11 puts a `.` after the first digit [10:14:34.0842] ok cool, thanks - that seemed right to me but i wanted another check [10:51:06.0855] re: `f() = x`, see discussion in https://github.com/tc39/ecma262/issues/257 [11:01:46.0233] on some previous occasion this came up, bterlson said it was vbarrays specifically that used this [11:02:04.0182] yessir, vbarrays [11:02:05.0840] and someone in the meeting chat said: ``` [2:21 PM] Paul Leathers Yes, VB arrays are the case I remember. [2:23 PM] Paul Leathers The call didn’t really return an lvalue. If the engine saw a(i) = x, it would perform a call to IDispatch::Invoke with the PROPERTY_PUT attribute set and the value to write as an extra argument. ``` [11:02:34.0647] though I never did manage to find an example of this I could actually get to work in IE6 [11:02:37.0619] maybe that was too new though [11:03:12.0998] I think because of the COM magic, it's possible vbs wouldn't work right on newer systems even if IE6 and JScript+JS did [11:03:33.0760] oh, fun [11:03:53.0783] I recall there being some particular system setup when I was testing VB/JS interop [16:57:07.0266] hi chairs, re. https://github.com/tc39/Reflector/issues/396#issuecomment-952406138, chipmorningstar needs a power-up 😄 2021-10-27 [22:45:49.0504] https://hackmd.io/PjvSgvS-Tj-nv3lJl5Dglg?view#1300-15002 15m | 🕐 `String.cooked` for Stage 1 will be at 13:00hrs or earlier? As we already covered Error Cause on Day-2 [22:46:06.0864] * https://hackmd.io/PjvSgvS-Tj-nv3lJl5Dglg?view#1300-15002 15m | 🕐 `String.cooked` for Stage 1 will be at 13:00hrs or earlier? As we already covered Error Cause on Day-2 [02:00:26.0066] we are starting plenary now! [02:03:34.0302] Good morning everyone i'm already one scotch in [02:07:59.0084] seems like we should use stages but go straight to stage 2 [02:09:46.0162] I'm happy to be a reviewer for 2->3 [02:09:49.0624] also support stage 2 [02:10:05.0732] wait, ask for reviewers! [02:12:47.0212] my b thanks bakkot & yulia [02:13:59.0526] does anyone else see aki in the middle of the stream? [02:14:00.0326] oh yeah was just about to ask [02:14:18.0733] lol Jitsi just wants to make sure i'm on everyone's mind [02:22:06.0920] why not just "using" and then the expression? why is "using const void" better? [02:34:16.0256] waldemar: i'm going to delete your topic, if you re-add it to the queue i can move it back to the top. [02:35:54.0380] the `await` in a `for await` happens on the line with the `await` [02:35:57.0869] it does not seem analalgous [02:36:40.0536] agree, mathieu's point was that it was in the middle [02:36:48.0258] well it does affect control flow, it can throw [02:40:48.0070] correct me if i am wrong, but isn't this implicit resource management rather than explicit resource management? [02:41:04.0145] the finally block is implicitly called [02:41:09.0851] > <@michaelficarra:matrix.org> why not just "using" and then the expression? why is "using const void" better? `using (expr)` would be a problem, since that's a valid function call [02:41:46.0322] > <@yulia:mozilla.org> correct me if i am wrong, but isn't this implicit resource management rather than explicit resource management? exactly! By reading the title, I'd expect a `free` function or something like that 😅 [02:41:55.0479] aki i added my topic back so you can clear me [02:42:20.0270] yulia: well i guess it's explicitly queuing the disposal method up to be called at a different place [02:42:23.0926] implicit would be a destructor, imo [02:43:12.0485] erights makes some good points [02:43:24.0117] in both cases the disposal method is not explicitly stated by the programmer, but this is a nit [02:43:30.0451] its not a substantial criticism [02:44:14.0421] what we have now is explicit, but that comes with the possibility that steps are missed especially during control flow, so i understand the goal here [02:44:59.0394] is it possible to limit `using await` to - top of an async function - top of an async do expression to resolve the implicit interleaving point problem? [02:45:30.0784] Jack Works: not really, you need to do it in a loop body or lots of other places [02:45:44.0921] what are some example of async disposal methods? [02:46:02.0204] > <@bakkot:matrix.org> Jack Works: not really, you need to do it in a loop body or lots of other places make sense [02:46:12.0221] > <@shuyuguo:matrix.org> what are some example of async disposal methods? closing a network resource, for example [02:46:21.0865] that's async? [02:46:51.0300] > <@bakkot:matrix.org> Jack Works: not really, you need to do it in a loop body or lots of other places top of a block? [02:47:06.0267] I think of it as the `defer myVar.close()` in Golang [02:47:56.0646] so you'd close the file/socket async to avoid blocking [02:48:09.0110] but you'd want to definitely do it once the block ends [02:48:13.0515] Michael Ficarra: top of a block works, but that's pretty much just `try using` again, right? [02:48:14.0202] > <@shuyuguo:matrix.org> that's async? in node most of them are async [02:48:23.0481] actually why did we go away from `try using`? [02:48:24.0426] i see, thanks [02:48:39.0284] bakkot I want to present this issue https://github.com/tc39/proposal-do-expressions/issues/75 to the committee to get a consensus of adding the restriction I proposed. How do you think? [02:48:39.0753] > <@bakkot:matrix.org> Michael Ficarra: top of a block works, but that's pretty much just `try using` again, right? SGTM [02:48:53.0247] > <@bakkot:matrix.org> actually why did we go away from `try using`? apparently feedback from the incubator call [02:49:01.0902] * bakkot I want to present this issue https://github.com/tc39/proposal-do-expressions/issues/75 to the committee to get a consensus of adding the restriction I proposed. How do you think? [02:50:21.0114] Jack Works: I'll bring it up next time I present; I don't think there's much reason to present it before then [02:51:19.0125] > <@bakkot:matrix.org> Jack Works: I'll bring it up next time I present; I don't think there's much reason to present it before then ok I just want to have that restriction so I can continue to work on the typescript implementation [02:53:40.0635] about 20 min remaining [02:54:24.0775] I am confused about the `Disposable` container - how is `new Disposable(() => foo())` different from `({ [Symbol.dispose]() { foo() })` ? [02:55:34.0361] @bakkot it takes iterables [02:55:43.0139] No difference I guess [02:55:46.0236] an iterable of disposables [02:56:00.0727] > <@michaelficarra:matrix.org> @bakkot it takes iterables Isn't `Disposable.from` take iterables instead of the constructor? [02:56:08.0436] * No difference I guess [02:56:22.0844] Jack Works: yes that's right, was there a constructor too? [02:57:35.0959] I guess it's for DX, `new Disposable(f)` is much easier to write than `({ [Symbol.dispose]: f })` [02:58:43.0903] this example doesn't seem particularly problematic to me [03:00:41.0136] oh oops i advanced the queue, misinterpreted what Waldemar meant by "let's move on to the next one" [03:01:29.0035] it's okay, I don't think anyone would begin talking before Waldemar is finished 😇 [03:02:25.0737] wouldn't any implicit disposal solution make figuring out tail calls more difficult (for humans)? [03:03:07.0211] maybe in a world where tail calls matter [03:10:17.0749] Michael Ficarra made this same point the first time this proposal came up, IIRC [03:11:34.0838] i think RAII is so common new syntax is warranted, abusing for-of seems not great [03:11:43.0114] for reading anyway [03:11:54.0191] eh, I don't think it's an abuse of for-of [03:12:14.0845] in the Scala world, they use `for` for everything and it works nicely for them [03:12:29.0284] (`for` in scala is like Haskell `do` notation) [03:12:33.0902] that `for-of` trick is really cleaver [03:12:40.0065] but in the JS world `for` is for iteration? [03:13:01.0839] shu: not for-of, it's syntax for a protocol [03:13:06.0155] we can use it to not wait for this proposal ship that might take years [03:13:08.0499] we disagree [03:13:35.0950] for-of _has_ a protocol, i would contend very few would understand it as syntax for protocols [03:13:43.0906] it's syntax for iteration [03:14:53.0999] yeah, we just disagree [03:15:38.0153] Michael Ficarra: tbf, the protocol literally uses "Symbol.iterator", so I feel like it's fair to say that it is for iteration [03:16:01.0794] that said, I also agree that this is a perfectly fine use of for-of [03:16:07.0361] lots of languages use `for` like this [03:16:08.0056] it's syntax for interacting with the iteration protocol, but "iteration" can mean many things [03:16:13.0017] why async is a fault? is there any articles I can know the reason? cc yulia [03:16:33.0151] yeah i strongly disagree with the opinion that async/await is a mistake [03:16:36.0289] we iterate over Maybe in our code all the time, and people don't typically think of that as "iteration" [03:16:39.0371] the bugs stem from, well, asynchrony, not the syntax [03:17:15.0680] > <@jackworks:matrix.org> why async is a fault? is there any articles I can know the reason? cc yulia it is very tricky to determine a fire and forget bug with async await [03:17:27.0074] it is very difficult to find just from reading or from static analysis [03:17:53.0388] but the comparison is with Promise handlers, right? [03:18:01.0314] which i feel like has to be harder [03:18:06.0475] https://github.com/mhofman/disposator [03:18:18.0678] the other issue with async await is the added viscosity to the language, and the reliance on unnecessarily writing code in a step wise fashion [03:18:31.0459] i think the space of async code is unsolved [03:18:42.0906] at least in javascript, this is easier in typed languages [03:18:51.0523] IMO the iterator approach is not particularly hard to read. Sure it takes a minute to understand why it actually works, but it's not obscure: ``` for (const {using} of Disposable) { const resource = using(getResource()); } ``` [03:19:53.0099] > <@yulia:mozilla.org> i think the space of async code is unsolved I sometimes think the knowledge that `async`/`await` was coming led to less investment in the spaces of Promises and Generators (in particular) [03:20:06.0695] rbuckton: sorry i cam across strong there [03:20:16.0385] > <@yulia:mozilla.org> it is very difficult to find just from reading or from static analysis hmm Isn't it save us from promise chain/callback hell? I think it actually improved the readability and static analysis [03:20:22.0772] I'm still looking for another reviewer [03:20:23.0408] i don't feel like *strongly* about this [03:20:58.0660] > <@jackworks:matrix.org> hmm Isn't it save us from promise chain/callback hell? I think it actually improved the readability and static analysis how does it improve static analysis? [03:21:18.0750] like, over promises [03:21:30.0189] > <@mhofman:matrix.org> IMO the iterator approach is not particularly hard to read. Sure it takes a minute to understand why it actually works, but it's not obscure: > ``` > for (const {using} of Disposable) { > const resource = using(getResource()); > } > ``` I still think that, while this is usable, it feels very easy to mistake what's going on here with normal iteration. [03:21:30.0290] it's syntax [03:21:39.0102] it's more analyzable than promise handlers, which are just functions flowing places [03:22:05.0502] > <@yulia:mozilla.org> rbuckton: sorry i cam across strong there Not a problem, it wasn't my intent to characterize stage 2 in that way. [03:22:22.0676] right but you can also await non-promises [03:22:34.0163] so you don't necessarily know anything about what you are awaiting [03:22:46.0456] i think we're assuming different goals of the analysis [03:22:59.0262] i was referring to analyzing the conceptual control flow of the code [03:23:38.0556] what would you like this analysis to answer? [03:23:41.0046] alright, i mean -- i use async await, my main point is that its highly bug prone [03:23:54.0626] Aki: We advanced topics without getting another Stage 2 reviewer. Waldemar is still willing to review but I'm still missing a reviewer since it seems Yehuda is unavailable. [03:24:10.0470] shit damn [03:24:12.0233] sorry [03:24:27.0091] yulia: i feel like that's categorically false, it was an improvement over the Promise handlers and callbacks before that [03:24:35.0798] which were much _more_ bug prone [03:24:37.0918] the static analysis came up because this has been solved by typescript -- by introducing a promise type, its much easier to track async bugs [03:24:39.0595] Can we add a topic to the agenda to bring this back up after the break? [03:24:44.0484] yup [03:24:57.0000] if you're making a statement that the absolute bugproneness is still high, then i agree with that [03:25:09.0524] but to characterize it as a "mistake" suggests to me that it was worse than the status quo before it [03:25:45.0840] yulia: If it were just generators/yield, TypeScript doesn't yet have a way to contextually type the result of a `yield` based on its input value. So we can't correctly type an async coroutine built using a generator. [03:26:07.0581] * yulia: If it were just generators/yield, TypeScript doesn't yet have a way to contextually type the result of a `yield` based on its input value. So we can't correctly type an async coroutine built using a generator. [03:26:20.0937] rbuckton: i didn't mean the generators yield pattern [03:26:27.0897] i meant the async await pattern in typescript [03:27:31.0469] the reason i was saying mistake was because i think there was a design space before, that doesn't exist now that we have async await [03:27:43.0277] i don't think we want to add yet another promise handling syntax [03:27:47.0444] that would likely be a waste [03:28:05.0470] i see [03:28:16.0779] and my point around saying it was a mistake was related too "stage 2 is agreed upon" which i brought across too strongly [03:28:30.0813] i can understand being disappointed in not exploring closed avenues [03:28:38.0132] or, rather, not having any reason to anymore [03:28:54.0315] yep, thats what i have regrets about [03:29:00.0608] but we're not a research language, so eh [03:30:12.0092] yeah, what can you do [03:30:52.0619] about mistake, I think the biggest mistake is all `then`ables can be awaited. That really cause bugs in my program while I'm using Proxy [03:31:16.0069] oh yeah thenables are terrible [03:31:22.0643] F# does have a few niceties that avoid some of the gotchas that languages like JS have for async/await, but I think async/await in JS is pretty good and pragmatic given all the constraints. [03:31:42.0898] there is also the kotlin approach but i don't know how much i like it [03:31:49.0300] though it would address some bugs [03:32:10.0808] thenables :( [03:32:49.0197] perhaps you meant thenables 🤡 [03:33:04.0483] At Agoric, we found that a simple lintable syntactic restriction on use of await that avoids a large class of bugs: https://github.com/Agoric/agoric-sdk/wiki/No-Nested-Await [03:34:23.0747] that looks like a very subtle bug [03:34:53.0070] how do you... not use `await` in a loop [03:36:27.0769] A top level `for await of` loop is fine. We do not have `await` inside the loop. Was surprised that all the in-loop awaits we had were easy to rewrite, and made the code better. [03:36:50.0168] the example from this slide of "people storing regexen in a way which doesn't allow them to represent flags" is not compelling [03:37:02.0006] 🤔 [03:37:25.0628] We have more and more powerful & complicated RegExps [03:37:51.0867] but I never used any advanced features of RegExp (I think it's hard to learn and hard to read) [03:38:02.0570] bakkot: 100% agree, and I think that's the only motivation for the feature [03:38:26.0438] * but I never used any advanced features of RegExp (I think it's hard to learn and hard to read) [03:40:38.0315] I think having part of the regex be case sensitive is a reasonable thing to want [03:40:49.0714] I want to see actual motivating regexps [03:41:23.0562] you should say that maybe [03:41:43.0241] bakkot: so we don't need to change arbitrary flags, we need a case-sensitivity modifier? I'd be much more okay with that [03:44:06.0817] at the end of today, i'm going to wish we had that regexp subgroup chip talked about last time (or maybe 2 meetings ago) [03:44:20.0181] i feel like i _should_ care but i don't really [03:45:37.0453] this isn't my area so... i don't have much of an opinion [03:46:11.0032] also we don't have an expert on this rn since we are integrating an external engine. [03:47:46.0860] thanks y'all, btw [03:48:37.0730] > <@shuyuguo:matrix.org> at the end of today, i'm going to wish we had that regexp subgroup chip talked about last time (or maybe 2 meetings ago) Did I say that? [03:48:46.0912] i thought so! but it's 4am [03:48:49.0765] Ah, yes I did. [03:48:56.0424] i feel like [03:49:01.0331] regexs have a lot of stuff in them already [03:49:12.0523] and we are proposing to ~double the number of distinct syntaxes they have [03:49:14.0095] seems like [03:49:14.0809] a lot [03:49:34.0390] yes, i had thought part of the point of splitting it out is so we could reject some piecemeal [03:49:37.0006] When you said "subgroup" I thought you were talking about subgroups inside regexps, instead of regexps inside a subgroup. [03:49:39.0346] i would use all of them probably, but [03:49:41.0604] it's so many [03:49:48.0845] is it true that this feature is equivalent to `/condition/.test(str) ? /yes-pattern/.test(str) : /no-pattern/.test(str)`? [03:50:19.0547] TG4 [03:50:29.0863] i would support tg4 for regex [03:50:40.0052] Only for really trivial regexes [03:50:40.0135] yes please [03:52:54.0957] i'd like to be a reviewer on private field destructuring; i didn't realize stage 2 for it was a possibility. [03:53:08.0746] good morning Jordan! [03:53:37.0275] ljharb: add yourself as reviewer in the notes [03:53:41.0730] k [03:58:30.0790] did someone say "ISO 8601 regex"? https://github.com/tc39/proposal-uniform-interchange-date-parsing#background 🙃 [04:00:15.0546] literally just yesterday I took an extremely long regex and broke it into a sequence of ifs and the code is now much more readable, even though it is also longer [04:01:15.0083] i agree with the abstract notion of meeting users where they are [04:01:30.0710] but, it seems like if the ultimate goal is something like, better TextMate grammar support in VSCode or something [04:02:04.0893] doesn't VSCode have enough adoption to pressure TextMate grammars to express what they need to express without using regexps as a full blown PL? [04:04:45.0560] SURELY there exists some code today that you would want to rewrite using this feature (if it's well motivated) [04:05:12.0652] that can be the example [04:07:24.0034] A procedural question: Stage-0 proposals that get presented to plenary should get transferred to the TC39 GitHub organization, right? Like this proposal, if it doesn’t make Stage 1? [04:07:27.0402] it does seem to help cases where parts of a pattern must currently be duplicated, but it may not be the best way to do so [04:07:55.0030] * A procedural question: Stage-0 proposals that get presented to plenary should get transferred to the TC39 GitHub organization, right? Like this proposal, if it doesn’t make Stage 1? [04:08:16.0515] Richard Gibson: I want to solve that with a better regex builder in the language [04:08:28.0250] same [04:08:47.0153] every time I build a regex by naive string mashing and `new RegExp` I feel slightly gross [04:08:59.0652] most of those times this proposal wouldn't help [04:12:38.0548] Incidentally, is a CoC Committee update still going to occur sometime this plenary? I wanted to make sure I didn’t miss that. [04:12:56.0433] Lookbehinds can be variable length in ES: /(? Agenda says it happened but notes say it didn’t. [04:13:06.0323] I have asked Jory to present a CoC update [04:13:18.0525] if we're process lawyers today, stage 1 entrance criteria includes 'Illustrative examples of usage" which I don't think was satisfied [04:13:39.0473] > <@waldemarh:matrix.org> Lookbehinds can be variable length in ES: /(? > <@michaelficarra:matrix.org> if we're process lawyers today, stage 1 entrance criteria includes 'Illustrative examples of usage" which I don't think was satisfied I did provide examples of usage though. [04:18:02.0198] I strongly feel that conditionals improve readability in complex patterns, and can improve readability when you have to context switch between RegExp syntax and JS syntax. I'm also not forging net new syntax here, but asking the committee to consider adopting existing syntax that is a well trodden path across multiple heavily used implementations. [04:18:44.0684] rbuckton: I just want to see some examples where you compare to how you write it today, because I am having a hard time making that comparison myself, so I can't convince myself the feature is needed [04:19:53.0667] rbuckton: I don't think anyone is complaining about the syntax chosen. Being in another regexp implementation isn't motivation, it's guidance on syntax/semantics choices. [04:22:04.0821] if a feature like this is well-motivated, it should be easy for you to find code that was written using facilities that are available today that would've been written using your feature and turned out "better", using whatever definition of "better" you want [04:22:48.0726] fwiw I have read a lot of Boost and miscellaneous PCRE regexes and I don't know that I have ever seen a conditional expression; "in a heavily used implementation" isn't really that informative relative to "heavily used in an implementation" [04:25:45.0049] "should be easy" is not so easy when your search criteria is `(?(?=`, but I understand your meaning. [05:00:26.0423] Plenary is starting.... now! [05:01:42.0282] rbuckton: If the TextMate grammar and related cases (all logic *must* be in the regex) did not exist, do you think you'd still be motivated to champion the RegExp conditionals proposal? [05:04:22.0196] Yes, I've used it often enough in .NET. I'll admit, it is a niche feature compared to what we already support, but many of the cases where its used its either: - The only way to achieve what you want _in the regex_, vs having to completely break down the regexp. - Much easier to read than alternatives. [05:05:15.0406] maybe you still have access to the .NET examples where you've used it then? [05:06:58.0707] this doesn't seem like a pun to me? [05:07:05.0276] nor to me [05:07:06.0357] a pun is when you are using a word in a non-obvious way [05:07:16.0236] Nothing I could locate quickly, I've spent most of my time in JS/TS for the last 6 years. [05:07:17.0719] but "raw" and "cooked" are antonyms [05:07:23.0473] raw/cooked may be duals in the food preparation space, but I'm not sure String.raw is in any way a "dual" of String.cooked [05:07:46.0759] Raw isn’t just a food term. Raw supplies, for example. [05:07:56.0556] Raw material. [05:08:03.0997] yes, words have multiple meanings [05:08:07.0472] yeah i am not sure about "cooked" here [05:08:27.0152] i kinda like it [05:08:31.0673] I prefer something like "processed". I had no idea what "cooked" meant. [05:08:42.0201] I'd prefer a name that is describes better what it does (atleast somewhat). [05:08:48.0937] * I'd prefer a name that is describes better what it does (atleast somewhat). [05:09:04.0086] Cooked isn’t necessarily just a food term either. [05:09:13.0234] Although its association with cooking is stronger than raw’s. [05:09:30.0450] "processed" doesn't mean anything at all to me [05:09:34.0720] every function processes its inputs [05:10:05.0465] i'm fine with `identity` as well [05:10:13.0989] would not prefer "processed" [05:10:36.0566] baked. [05:10:37.0009] to be fair, I initially had to have the relationship between "cooked" and "raw" explained to me [05:10:38.0680] it should be baked [05:10:41.0412] In the issue tracker I proposed `String.interp` or `String.interpolate` for just basic interpolation [05:10:50.0240] * In the issue tracker I proposed `String.interp` or `String.interpolate` for just basic interpolation [05:10:51.0715] Baked also is not necessarily a food term either. [05:10:54.0810] Oops, I’m up. [05:11:12.0273] you're still ingesting something i guess [05:11:13.0230] close enough [05:11:32.0329] String.ingested [05:12:03.0825] digest might actually work [05:12:16.0935] oh no that's too overloaded with hash stuff [05:12:23.0817] digest makes me think about hashing/signing [05:12:27.0326] what shu said [05:12:33.0442] ah, nevermind [05:12:41.0384] * digest makes me think about hashing/signing [05:13:55.0327] > <@rbuckton:matrix.org> In the issue tracker I proposed `String.interp` or `String.interpolate` for just basic interpolation I like `interpolate` [05:14:00.0358] ga-zem-nid? [05:14:03.0180] also `process` [05:14:20.0496] nothing about ingesting! 😱 [05:14:27.0182] "cooked" makes sense in reference to the actual specification text: 13.2.8.3 GetTemplateObject ( templateLiteral ) - Step 5: `Let cookedStrings be TemplateStrings of templateLiteral with argument false.` - Step 11.b: `Let cookedValue be cookedStrings[index].` [05:14:49.0760] If we go with `processed`, we could subtly continue the `raw` metaphor [05:15:14.0421] the spec text can easily change its terminology to better reflect users' mental models [05:15:29.0109] why are people shipping so much `console.log`? [05:15:50.0897] diagnostic logging? [05:15:54.0065] I think I only use call when it's bound, to turn a function of n parameters in to a function of n+1, where the first is the this-value: `const blink = Function.prototype.call.bind(String.prototype.blink); blink('DHTML')` [05:16:15.0009] > <@shuyuguo:matrix.org> why are people shipping so much `console.log`? it's totally fine for anything running in node to use it in production [05:16:45.0506] Michael Ficarra: call-binding is definitely my primary use case - but that's also because it bypasses the need to `.call` later on the call-bound thing [05:16:48.0984] I like the thinking here a lot [05:16:59.0747] * Michael Ficarra: call-binding is definitely my primary use case - but that's also because it bypasses the need to `.call` later on the call-bound thing [05:17:01.0939] i find any natural language - PL connection fairly tenuous [05:21:09.0143] i do like and appreciate the simplicity [05:21:11.0099] how would I define my `blink` function from above using this new feature? [05:21:21.0189] * i do like and appreciate the simplicity [05:22:48.0986] `const { blink } = String.prototype; const callBoundBlink = blink::blink.call;` i think? but you don't need the call-bound one either; you can do `str::blink()` any time [05:23:15.0028] > <@michaelficarra:matrix.org> how would I define my `blink` function from above using this new feature? * `const { blink } = String.prototype; const callBoundBlink = blink::blink.call;` i think? but you don't need the callbound one either; you can do `str::blink()` any time [05:23:20.0741] * `const { blink } = String.prototype; const callBoundBlink = blink::blink.call;` i think? but you don't need the call-bound one either; you can do `str::blink()` any time [05:23:46.0681] You asking for a way to uncurry `this`, which is kind of the opposite of what this does (though you _can_ do it using this syntax and `.call`). [05:24:21.0737] Partial Application would be `String.prototype.blink.call~(?)` (binds Reference to `blink.call`) [05:24:25.0070] `this::smartRound~(params.floatPrecision)` looks bad to me [05:24:32.0074] for all my use cases, the "uncurry this" pattern (which i call "call-binding") is completely unnecessary with the `::` calling syntax, since its sole purpose is to robustly change the receiver later [05:24:40.0655] * You asking for a way to uncurry `this`, which is kind of the opposite of what this does (though you _can_ do it using this syntax and `.call`). [05:24:49.0281] * for all my use cases, the "uncurry this" pattern (which i call "call-binding") is completely unnecessary with the `::` calling syntax, since its sole purpose is to robustly change the receiver later [05:25:14.0491] It seems like a large number of cases of `bind` are for partial application. Were those taken out? [05:25:27.0594] If this doesn't support partial application? [05:25:30.0466] erights: pipe and `.call` wouldn't let me be robust against `delete Function.prototype.call` [05:25:32.0645] we had seen the opposite -- that bind is usually for binding `this` [05:25:48.0059] its a common pattern for example in jsx [05:26:00.0928] binding this or the partial application? [05:26:06.0088] binding this [05:26:14.0579] for JSX, I have partial, but that's functional components ... I guess old react is classes [05:26:15.0207] partial application is much less frequent as a use for `bind` [05:26:21.0959] yulia: JSX isn't shipped to the browser though, right? [05:26:25.0423] * for JSX, I have partial, but that's functional components ... I guess old react is classes [05:26:29.0523] so it can compile to a bind call? [05:26:36.0411] no, but we are sensitive to how people are using the language [05:27:02.0083] and there are other cases of bind outside of react, it was just the immediate example that came to mind [05:27:13.0097] i think js choi did some great corpus analysis for this [05:27:43.0777] can someone advance the queue to indicate mark's topic is up? [05:28:39.0561] > <@rbuckton:matrix.org> You asking for a way to uncurry `this`, which is kind of the opposite of what this does (though you _can_ do it using this syntax and `.call`). I see now, thanks. You're right, it looks to be the opposite. [05:28:46.0077] > <@yulia:mozilla.org> i think js choi did some great corpus analysis for this do you know, is that in the repo? (I'm just a curious student driver lol) [05:29:11.0207] I want to explicitly oppose jhd's motivation here [05:29:22.0715] bakkot: YOU DO THAT TOO! [05:29:31.0762] that is: I think this should be an extremely low-weight factor [05:29:37.0486] Michael Ficarra: yeah, but I know that I'm weird [05:29:39.0438] that's fine [05:29:39.0681] we're super weird [05:29:40.0945] > <@sarahghp:matrix.org> do you know, is that in the repo? (I'm just a curious student driver lol) https://github.com/js-choi/proposal-bind-this#bind-and-call-are-very-common [05:29:56.0540] bakkot: +1 [05:31:12.0099] basically every module I ever write, I protect against later-run code overriding or deleting built-ins, and so should everyone [05:31:52.0222] it's reasonable not to expect people to write unergonomic code to achieve that. but if we can provide a way to make robust code easier, how are we not incentivized to do so? [05:35:06.0370] michael: no you do not [05:35:08.0389] this is false [05:35:15.0078] I have seen you write `.map` many times [05:35:22.0982] > <@michaelficarra:matrix.org> basically every module I ever write, I protect against later-run code overriding or deleting built-ins, and so should everyone Someday I hope we can do better, because that's an unreasonable expectation for the majority of JS devs. [05:35:37.0687] > <@bakkot:matrix.org> I have seen you write `.map` many times blasphemy! [05:36:06.0992] Is old bind operator proposal withdrawn? It's in stage 0 list [05:36:26.0810] no [05:36:37.0681] but it would be if this one made it to stage 2 [05:37:00.0449] > <@rbuckton:matrix.org> Someday I hope we can do better, because that's an unreasonable expectation for the majority of JS devs. it is now. but it shouldn't be. [05:37:20.0037] For all those proposing new syntax especially, please reread https://erights.medium.com/the-tragedy-of-the-common-lisp-why-large-languages-explode-4e83096239b9 [05:38:10.0845] legendecas: regarding your queue item, typically competing proposals in stage 1 is fine, once one advances to stage 2, the alternatives typically are withdrawn [05:38:12.0104] > <@ljharb:matrix.org> it is now. but it shouldn't be. I have thoughts on this related to concurrent JS and shared structs, but nothing formal yet. [05:39:12.0618] Michael Ficarra: https://github.com/michaelficarra/samevalueset/blob/e1a5b6ea5d1336ea42908e7061ba3a03536624bd/src/index.js#L31 [05:39:16.0723] not `.map` but close enough [05:39:36.0506] If we had PFA and bind-this, `o::f` would be synonymous with `o::f~(...)` (though more terse). [05:39:45.0525] grepping actual code on github for counterexamples is a dirty trick :-p nobody compare my style recommendations to a minority of my actual code please [05:39:57.0999] * grepping actual code on github for counterexamples is a dirty trick :-p nobody compare my style recommendations to a minority of my actual code please [05:40:21.0889] Which might reduce the motivation for non-call `o::f`, but only if PFA advances to stage 2+. [05:41:08.0898] > <@bakkot:matrix.org> not `.map` but close enough to be fair, I did go to some effort to make that code robust (using call-bound call to call callbacks), just missed that case [05:41:50.0582] yulia: my understanding of pipeline is about reducing "dimensionality" (i.e. flattening nesting, which is harder to mentally process), not ordering per se [05:42:14.0693] the reason nesting is hard to read is that you have to process it backwards was my understanding [05:42:23.0736] research on how word order matters sounds interesting however, links? [05:42:36.0666] felienne's work on reading code [05:42:41.0559] What are the competing rivals for bind-this? The old bind proposal and extensions? PFA is not a competing rival, though it is cross cutting and shares some functionality. [05:42:44.0565] i'm skeptical of that claim because there are pelnty of non-SVO languages that are just as easy to to comprehend? [05:42:46.0539] i believe she presented it last year, i can find the links [05:42:57.0629] nesting is difficult because you need to track a stack of state [05:43:02.0107] can i get a definition of svo? [05:43:11.0815] rbuckton: yes, those are the two. not PFA. [05:43:12.0637] e.g. center embeddings in english are hard to understand [05:43:15.0415] Michael Ficarra: literally a majority of the method calls in this module are not robust against prototype pollution [05:43:17.0711] subject-verb-object word order [05:43:24.0354] ah yes, thanks [05:43:42.0349] yes, this is true, but we currently don't have true internationalization of programming languages [05:43:43.0033] also if you are trying to be defensive against prototype pollution you can't use `...` with arrays, including in function arguments [05:43:47.0147] it's just not a realistic concern [05:44:02.0267] this is also openly being explored, the defacto grammar and understanding of programming languages is english right now [05:44:10.0293] this is also reflected in how we define grammars and parsing [05:44:57.0006] > <@yulia:mozilla.org> this is also reflected in how we define grammars and parsing oh? [05:45:25.0505] yes, there was an interesting presentation on this in pilates (programming in languages other than english) conference [05:45:41.0291] that is true, and something node core already has to deal with, and that `::` can actually solve by using it with the extracted Symbol.iterator method. [05:45:47.0075] or, i think i got the acronym wrong [05:45:49.0871] > <@bakkot:matrix.org> also if you are trying to be defensive against prototype pollution you can't use `...` with arrays, including in function arguments * that is true, and something node core already has to deal with, and that `::` can actually solve by using it with the extracted Symbol.iterator method. [05:46:25.0025] https://icer2021.acm.org/getImage/orig/Programming+In+Languages+that+Aren%E2%80%99T+English.pdf [05:46:43.0295] ljharb: how does `::` help with making `function f(...args){}` robust against prototype pollution [05:46:57.0790] or even `f(...args);`, for that matter [05:47:03.0896] delete Function.prototype.call [05:47:11.0025] the first one doesn't use the protocol; the second can't be protected, that is true. i was speaking to iteration use cases for mitigation. [05:47:17.0418] * the first one doesn't use the protocol, the second can't be protected, that is true [05:47:36.0437] * the first one doesn't use the protocol; the second can't be protected, that is true. i was speaking to iteration use cases for mitigation. [05:47:38.0842] > <@legendecas:matrix.org> delete Function.prototype.call The problem is you can also `delete Array.prototype[Symbol.iterator]` and break the code. [05:48:27.0678] at least, the `f(...args)` case. [05:48:43.0199] I cannot wait to have `groupBy`! ❤️ [05:49:42.0938] omggggg maybe yes! [05:49:48.0375] My primary motivation for PFA (and bind-this) is convenience, not prototype pollution. Its a nice bonus, but a much smaller concern to me. [05:49:51.0006] I don't even think this one would be the first to ignore species, right? [05:50:05.0446] nope [05:50:09.0062] at least Temporal [05:50:22.0812] the immutable array methods ignore it, I believe [05:50:33.0310] also resizable buffers [05:51:43.0316] This the right time to ask how likely it is that species will be removed? [05:52:03.0792] well [05:52:10.0483] lol you can ask :-p [05:52:12.0000] annevk: removed? removed how? [05:52:13.0533] * lol you can ask :-p [05:52:27.0451] * This the right time to ask how likely it is that species will be removed? [05:52:33.0498] somebody that's not me need to find time in the next 1-2 years to actually build a custom V8 that lets you toggle species-handling, and seeing what breaks [05:52:34.0729] Symbol.species will continue to exist, if that's the question [05:53:37.0765] don't tempt fate justin [05:53:49.0611] we should name this `sort` [05:53:58.0406] because that's what that word actually means [05:54:00.0183] > <@annevk:mozilla.org> This the right time to ask how likely it is that species will be removed? we hit some snags.. [05:54:10.0829] but, hopefully can start looking into it again in the new year [05:54:17.0859] I'm much more interested in `groupByMap` for most places where I'd use this, since I'd like to have non-string/symbol keys, but I'm not against it. [05:54:19.0596] there is a library that is heavily using it [05:54:29.0003] what, core-js? [05:54:32.0344] yeah [05:54:52.0484] im not convinced it is impossible yet [05:55:00.0427] IIRC, all of core-js usage of Symbol.species is purely to emulate spec behavior for shims that use Symbol.species. [05:55:03.0484] yeah i don't feel like those are real uses [05:55:07.0040] exactly, yeah [05:55:28.0224] there is a possibility that other browsers can use the chrome escape hatch that was built in there [05:55:28.0647] the real difficulty there is i now refuse to engage with the author of core-js [05:55:44.0773] i can understand why [05:55:48.0430] And also, `core-js` has a big number of downloads but just because it includes every polyfill, not because of `Symbol.species` [05:56:03.0684] If core-js had a way to conditionally *not* shim/use Symbol.species, I expect it would be less of a problem. [05:56:09.0412] * And also, `core-js` has a big number of downloads but just because it includes every polyfill, not because of `Symbol.species` [05:56:10.0276] yes exactly [05:56:14.0630] 100% agree that core-js's usage of these things shouldn't be weighted highly (also any polyfills/shims, including my own) [05:56:19.0759] i did a test run with core-js and the libraries that were listed [05:56:23.0378] it's not breaking the web to cause unnecessary polyfilling [05:56:38.0021] and there were breakages that i found, but i didn't have enough time to fully clear the issue raised [05:56:43.0422] and i didn't want to engage further [05:56:49.0093] we have an implementation in FF for testing [05:57:11.0561] oh awesome you already did an implementation? [05:57:20.0160] yes, with the different grades [05:58:03.0351] oooo [05:58:10.0491] where's the patchstack? [05:59:45.0994] its from last year, let me ask the author (can't find it rn) [05:59:50.0991] sarahghp: Note that the methodology details are hidden in a `
` disclosure element at the end of the section. There’s also manual-review data in issue #12. [06:00:03.0245] * sarahghp [regarding `.call` corpus analysis]: Note that the methodology details are hidden in a `
` disclosure element at the end of the section. There’s also manual-review data in issue #12. [06:01:27.0112] +1 to throwing for `plain` with strings with `Z` [06:01:29.0794] > <@shuyuguo:matrix.org> where's the patchstack? here it is https://phabricator.services.mozilla.com/D101832 [06:01:36.0585] its without deleting it, its just disabling it [06:01:45.0383] yulia: ty [06:02:31.0511] right, i had similar plans for a V8 flag but can't find the time to actually code it up [06:02:59.0475] yeah, we should do a run of an experiment with it but i keep not finding the time [06:11:34.0306] ptomato: is ftang in the loop for all these normative changes and bug fixes? [06:11:42.0249] because i sure as hell won't remember to check these [06:12:07.0653] iirc ftang discovered many of them [06:12:48.0874] yes, but didn't know if it was all of them [06:13:05.0580] i have a hard enough time reviewing the implementation, just wanted to check i also didn't have to keep up with the normative changes and fixes [06:15:04.0464] I think if there's _someone_ on top of all this, it has to be ftang... [06:19:53.0868] Doh, I forgot to ask for Stage 3 reviewers [06:20:06.0453] oh no [06:20:16.0950] We can make it informal [06:20:19.0737] i'd love to review array grouping [06:20:21.0953] we really need to figure out a strategy for not forgetting that [06:20:23.0811] * i'd love to review grouping [06:20:25.0288] * i'd love to review array grouping [06:20:34.0825] Justin Ridgewell: I will review for you [06:20:43.0374] Whoot [06:20:50.0132] still ask, though [06:20:50.0751] Thanks Jordan/Michael [06:22:08.0891] I'd love to review array grouping too [06:24:01.0604] I feel like "an options bag which must provide one of these two options" is not actually that confusing? [06:25:01.0318] it can be very hard to figure out what one did wrong with APIs like this, at any experience level. [06:25:11.0889] * it can be very hard to figure out what one did wrong with APIs like this, at any experience level. good error messages help but aren't always sufficient. [06:25:54.0185] bakkot: strong +1 [06:28:11.0232] > <@michaelficarra:matrix.org> we really need to figure out a strategy for not forgetting that Add a "Stage 3 Reviewer Sign-up" feature to tcq? [06:30:07.0442] Or even just a general "Stage Advancement" feature that adds something to an agenda topic that can show up in the queue as part of advancing the topic, with an option to allow reviewers to sign up when necessary. [06:32:27.0246] i kinda like WH's solution of just making it optional and then it doesn't round to anything [06:32:48.0993] but I don't share ljharb's intuition that options bags should themselves be optional [06:34:26.0502] I'm not saying that the options bag should be optional. But if you pass an options bag without a smallestUnit, then round should be the identity. [06:36:24.0122] > <@rbuckton:matrix.org> Or even just a general "Stage Advancement" feature that adds something to an agenda topic that can show up in the queue as part of advancing the topic, with an option to allow reviewers to sign up when necessary. feature request: https://github.com/bterlson/tcq/issues/45 /cc bterlson [06:43:47.0102] justingrant: ftr i'm not happy with Duration round's API still, but i agree it's better to have the string shortcut with smallest and the options bag with "smallest or largest" than the status quo, especially considering the other methods would all be using the ergonomic string shortcut pattern [06:43:59.0260] I wouldn't block for overloading of string and options bag, but I'd ask that it only be used when it really improves the ergonomics and that there is no confusion possible as to what default setting is set [06:44:12.0999] * justingrant: ftr i'm not happy with Duration round's API still, but i agree it's better to have the string shortcut with smallest and the options bag with "smallest or largest" than the status quo, especially considering the other methods would all be using the ergonomic string shortcut pattern [06:45:16.0948] IMO requiring that an object is always present is not an issue if some config is always required. If all options are optional, an empty object and no object should be equivalent [06:46:28.0747] super agree that empty and no object should be equivalent, and that the pattern should not be used when there's confusion about what the default should be (and only when the pattern improves ergonomics) [06:46:40.0266] * super agree that empty and no object should be equivalent, and that the pattern should not be used when there's confusion about what the default should be (and only when the pattern improves ergonomics) [06:46:56.0884] i'm confused then [06:47:30.0209] about which part [06:47:44.0068] i'd take Mathieu Hofman's position to also mean that it's not problematic for A() to take an optional options bag and B() to take a required options bag of the same shape (with >1 required properties) [06:47:59.0304] but ljharb you find that problematic? [06:48:12.0891] * i'd take Mathieu Hofman's position to also mean that it's not problematic for A() to take an optional options bag and B() to take a required options bag of the same shape (with >1 required properties) [06:48:32.0008] i find ">1 required properties" or anything more complex than "1 specific required property" problematic [06:48:54.0102] * i find ">1 required properties" or anything more complex than "1 specific required property" problematic [06:49:08.0680] can you say more about where that intuition comes from? [06:49:10.0141] okay, then we still disagree, i find that fine [06:49:22.0905] bterlson: advance queue? [06:49:25.0604] I feel like... it is pretty common to have things like "you must specify either an X or a Y" [06:49:32.0413] right [06:49:57.0359] config objects can have fairly involved, but still intuitive logic to them [06:49:59.0057] Just grep a browser's .webidl files for `required` if you need some prior art [06:49:59.0975] from confusion i've experienced and witnessed many others experience when they misuse such APIs. It is … not uncommon to do that. that's why i don't like it, because i run into it often enough. [06:50:00.0648] like, implications [06:50:20.0939] config objects are a PITA to work with [06:50:25.0310] I agree people get confused about these sometimes but like [06:50:29.0811] people get confused about lots of stuff [06:50:37.0724] I don't think these are inherently confusing [06:50:40.0485] yes, i agree with that too, but the confusion stems from the fundamental complexity of configuration [06:50:43.0992] yes exactly [06:50:45.0434] and when it's unavoidable - like Duration round - maybe that's fine. but when it's avoidable we should avoid it. [06:51:06.0137] i think you're confusing the source of confusion -- you can say, there needs to be fewer options, and Apple would agree [06:51:08.0567] if i had a better idea for Duration round i'd suggest it, but i don't [06:51:11.0930] but sometimes the problem space just sucks [06:51:19.0898] i don't mind lots of optional options :-) [06:51:33.0817] but that's not a complicated case [06:51:35.0824] and nobody disputes that temporal's problem space is a hellish nightmare [06:51:52.0758] i think the disagreement is, i don't think you can wave away inherent logic required in many config objects [06:51:58.0068] including mutual exclusion, implication, etc etc [06:52:13.0596] you can't wave that away by trying to adopt linter-like rules like "options bags must be optional" [06:56:17.0850] bakkot: that error message is gonna get so many complaints [06:56:25.0900] > <@shuyuguo:matrix.org> ptomato: is ftang in the loop for all these normative changes and bug fixes? yes, he found most of them, but I am pretty sure he read the slides as well. I'll double check at the next Temporal meeting [06:56:49.0816] excellent, thank you [06:56:54.0741] ``` let value = /regex#/ a+b/x ``` [06:56:56.0162] is ambiguous [06:58:25.0282] Uh well, if we are going to require balanced brackets in `(#...)` comments we might as well disallow `/` in line comments [06:58:41.0156] * Uh well, if we are going to require balanced brackets in `(#...)` comments we might as well disallow `/` in line comments [06:59:12.0902] Nvm, it would probably make parsing that code a nightmare [06:59:19.0064] * Nvm, it would probably make parsing that code a nightmare [06:59:43.0772] big +1 to not changing permissive grammar here [06:59:54.0247] i will probably refuse to implement that change out of fear [07:00:11.0089] uhh I think we've been without a notes curator for a little bit [07:00:57.0646] anyone who participated in the last discussion, please help edit the recent notes [07:08:29.0433] think we got it mostly cleaned up [07:08:34.0130] the discussion portion at least [07:08:39.0990] talk portion is still a bit mangled, but mostly readable [07:08:41.0384] * talk portion is still a bit mangled, but mostly readable [07:09:47.0605] looks good, thanks everyone [07:35:41.0850] Was it rbuckton who agreed to be a reviewer for `String.cooked`? Trying to recall (yes, will check the notes too) [07:38:38.0166] NVM, it is Richard Gibson thank you! [07:50:17.0411] bterlson: is the remaining point for Temporal already on the list of overflow topics for tomorrow or should I request that somewhere in particular? [13:22:24.0062] shu it sounded like no one wants to touch RegularExpressionLiteral? It seems like it would be feasible to balance `(?#` and `)` so as to allow an unbalanced `[]` inside a comment. I'm not sure I fully understand the reticence to make changes here. [13:30:34.0557] I suspect it is a desire for stability of tokenization to accommodate software already present in the ecosystem, but regardless I agree that it should be explicitly articulated 2021-10-28 [17:02:40.0400] Sorry all for being late to reply to Temporal-related posts above. Was so relieved to be done with my 15 mins of fame this morning that I forgot to check the delegates channel afterwards. 😄 I'll add a few notes and replies now. [17:06:12.0316] > <@pchimento:igalia.com> bterlson: is the remaining point for Temporal already on the list of overflow topics for tomorrow or should I request that somewhere in particular? I didn't see a response to this so I went ahead and added Temporal to the overflow section in the HackMD page. If this was wrong, please feel free to revert and let us know about the correct process. Thanks! [17:11:24.0153] > <@ljharb:matrix.org> and nobody disputes that temporal's problem space is a hellish nightmare Finally, we've found an invariant we can all agree with! 😄 [17:20:14.0162] > <@ljharb:matrix.org> it can be very hard to figure out what one did wrong with APIs like this, at any experience level. good error messages help but aren't always sufficient. Speaking of error messages, one suggestion I'd have for the committee: a standardized way for the spec to provide hints to implementers about error messages, and guidelines for proposal authors for when to provide those hints in the spec. Proposal authors (especially if the proposal's polyfill gets a lot of use) have a lot of tribal knowledge about the requirements for error messages, but AFAIK there's not really an "official" way to convey that knowledge to implementers. Nor is there a requirement that proposal authors think through the "how are users likely to misuse this API and what should the error message say to help them?" problem. I don't think that implementers should be required to use any particular error message, but IMO having more clarity and consistency in error messages across implementations seems like a good idea, both to help users and to avoid inevitable churn from bug reports asking to improve error messages after the implementation ships. Also, implementers may not have insight into the kinds of bugs that users will run into, so they may not be in the best position to write the most helpful error message text without getting those bug reports. I'm not proposing any specific solution, but did want to highlight the problem and see if there was any existing prior art on the committee around this issue. [17:36:10.0484] > <@waldemarh:matrix.org> I'm not saying that the options bag should be optional. But if you pass an options bag without a smallestUnit, then round should be the identity. We'll plan to spend our overflow time tomorrow focusing on this question. Reading the replies above, I believe that there are three possible solutions: 1. `.round({})` is allowed (and does nothing), but `.round()` throws. 2. Both are accepted and do nothing. 3. Both throw. The current Temporal Stage 3 proposal uses (3). There were two reasons the champions selected (3): first, because it's a no-op and likely a programmer bug, and second for defense against typos in the property name like `.round({smalestUnit: 'second'})` which would be treated the same as `.round({})`. (Sadly there's no typo defense for optional property names without breaking extensibility, but our opinion was that preventing at least some bugs was better than preventing no bugs.) One request I'll relay from ptomato: this proposal is already in Stage 3, so we'd ask for there to be a really persuasive case to change the existing plan of record. The default should be that we stick with what's already been approved, because we really want to get this API shipped soon! [17:47:25.0854] > > shu : is ftang in the loop for all these normative changes and bug fixes? > ptomato: yes, he found most of them, but I am pretty sure he read the slides as well. I'll double check at the next Temporal meeting We also implemented the following process: * PRs that affect the spec text are marked with a `spec-text` label in GH https://github.com/tc39/proposal-temporal/pulls?q=is%3Apr+label%3Aspec-text * PRs that don't affect the spec (e.g. changes to docs, polyfill, tests, build tools hell, etc.) are marked `no-spec-text` * PR authors who forget to put the right label on (prime suspect: me, usually!) will be publicly embarrassed and a maintainer will quickly add the right label. I'll leave it to Frank and other implementers to say whether it's actually been helpful in cutting down the noise, but anecdotally I've been hearing fewer complaints since we started doing this so 🤷. [20:32:30.0688] spec 13.5.1.2 RS: delete operation [20:32:42.0885] what does it mean by delete binding? [20:32:55.0387] ```js var a = '1' delete a; function z() { 'use strict'; a } z() ``` [20:33:06.0121] I tried this but `z` didn't throw [21:03:48.0494] IIUC var declaration is not deletable (except in eval mode), so a is actually still reachable in z. [21:05:43.0096] https://tc39.es/ecma262/#sec-globaldeclarationinstantiation 16.1.7 step 17, defined as `Perform ? env.CreateGlobalVarBinding(vn, false).`. the second parameter of `CreateGlobalVarBinding` defines if the binding is deletable. [21:08:22.0059] I got it. ```js a = '1' delete a; function z() { 'use strict'; a } z() ``` [21:08:24.0247] this will throw [01:48:16.0269] plenary will start in... 12 mins [02:08:40.0334] can someone remind me what the motivation for boxes is [02:08:59.0857] allow to keep mutable object in record/tuple [02:09:08.0617] I guess [02:09:16.0967] not just mutable, but also objects like functions [02:10:04.0962] if you can put a box in a record, you have already given up on the "records are deeply immutable" goal, so what benefit does the box have? [02:11:07.0692] Boxes are imutable. They are similar to having a Symbol [02:11:16.0891] and that symbol can be used to look up an object [02:11:28.0484] that seems to be a technical point [02:11:39.0494] conceptually it's to link the immutable to a mutable thing, right? [02:11:49.0437] they can be used to look up an object without any other facilities [02:11:58.0890] that sure does not sound like they are immutable to me [02:12:08.0792] like, they give access to mutability [02:12:48.0852] they're immutable in the sense that `const` is constant [02:14:17.0291] There are a lot of use case that require expressing an immutable structure with mutable exit points [02:14:20.0005] They give an explicit signal when leaving the immutable part of the "graph" [02:14:40.0038] Mathieu Hofman: right, but just putting an object in the record is already an immutable structure with mutable exit points [02:14:55.0063] how is "and then this value is not a primitive" not already an explicit signal? [02:15:20.0712] like, that is currently already how you distinguish between the mutable and the immutable stuff [02:15:29.0601] Is there a reason this can't be solved using `Symbol` and `Map`? [02:15:47.0957] well, weakmaps i guess [02:16:03.0054] but i thought the R&T champions have gone back and forth on Box vs that approach [02:16:04.0167] > <@bakkot:matrix.org> how is "and then this value is not a primitive" not already an explicit signal? because you can't put non primitives inside records and tuples. [02:16:08.0510] i forget the outcome [02:16:30.0457] Mathieu Hofman: yes, but that's a design choice they made, which they now seek to introduce a new exit point for via a new primitive whose sole purpose is to wrap an Object [02:16:38.0678] seems... unnecessary, is how i read bakkot's point [02:17:02.0178] There is a long discussion on why implicitly allowing objects inside records/tuples is not feasible [02:17:20.0488] main one being it's a footgun [02:17:39.0299] why is this less a footgun? [02:18:00.0814] because you need to explicitly wrap the object [02:18:25.0474] you can't mistakenly put something mutable in your immutable structure [02:18:47.0093] but unless you're constructing all values inline, you could get a box already via a variable, no? [02:18:59.0271] `const tuple = #[getFoo()]` [02:19:13.0428] `getFoo()` can return boxes, no? [02:19:32.0383] it can, but you may not always know what it returns [02:19:39.0759] well yes, that's the point [02:19:53.0866] if it returns boxes, then `#[getFoo()]` is conceptually not deeply immutable [02:20:02.0927] but you don't know if `getFoo()` returns boxes or not [02:20:16.0544] so you don't know if `#[getFoo()]` is really deeply immutable without exit points or not [02:20:29.0902] The only way you get immutability is via a function call, like `ObjectPlaceholder.unwrap(myBox)`: it's a function call that returns a mutable thing [02:20:42.0859] Exactly as if you would have a symbol representing an object, white a side symbol->Object map [02:20:52.0896] * Exactly as if you would have a symbol representing an object, white a side symbol->Object map [02:21:17.0925] > <@mhofman:matrix.org> it can, but you may not always know what it returns we cannot always know a function returning any type of thing, in that sense? [02:23:00.0404] boxes do not seem like a good fit for the thing justin is discussing? it seems like you would just want a` #[type: 'user data', data: whatever]` [02:23:32.0139] i missed the use case [02:23:37.0224] is it like taint tracking? [02:24:57.0594] > <@bakkot:matrix.org> boxes do not seem like a good fit for the thing justin is discussing? it seems like you would just want a` #[type: 'user data', data: whatever]` They can be leveraged to build that thing [02:25:12.0304] I outlined it in the primitive issue [02:25:37.0483] > <@shuyuguo:matrix.org> i missed the use case It basically similar use case of marking exit points where value in the exit points can be any value (primitive or object) [02:25:54.0939] ah [02:26:14.0319] and ObjectPlaceholder doesn't work for that only because it can't contain primitives [02:26:20.0983] https://github.com/tc39/proposal-record-tuple/issues/258#issuecomment-940639809 [02:27:01.0877] I'm annoyed that it's `ObjectPlaceholder`, but the reply in TCQ was to address why an explicit exit marking is valuable [02:28:33.0168] The primitive issue could be solved by another layer of object, do I understand that correct? [02:28:41.0045] I am still really confused by what boxes are for [02:28:56.0717] is there an explainer somewhere? [02:29:05.0773] > <@haxjs:matrix.org> The primitive issue could be solved by another layer of object, do I understand that correct? Yes, or `#{ isObject: boolean, value: primitive | placeholder }` [02:29:49.0823] specifically, the advantage of boxes vs just putting objects directly in the graph, and having "it is not a primitive" be the explicit exit point [02:30:41.0059] But there's no need for that? [02:31:00.0046] I havne't seen a justification for why we should prevent primitives directly in Box [02:31:00.0852] > <@bakkot:matrix.org> is there an explainer somewhere? We have a short usage example at https://github.com/tc39/proposal-record-tuple#box (which uses `Box` as the name) [02:31:33.0419] that does not explain the motivation over just putting objects directly in the record [02:32:02.0470] > <@bakkot:matrix.org> specifically, the advantage of boxes vs just putting objects directly in the graph, and having "it is not a primitive" be the explicit exit point I remember the author of scala.js prefer just putting objects :) [02:32:29.0707] > <@jridgewell:matrix.org> I havne't seen a justification for why we should prevent primitives directly in Box maybe it looks more "clear" ? [02:32:45.0504] > <@bakkot:matrix.org> that does not explain the motivation over just putting objects directly in the record Ok, I always interpret "why we need placeholders" as "why just primitives isn't enough" 😅 We have https://github.com/tc39/proposal-record-tuple/issues/206 where we discussed about explicit/implicit boxing [02:33:55.0950] nicolo-ribaudo: again, the question is "why have boxes at all, vs just putting things in the graph directly" [02:34:02.0856] that issue presupposes the existence of boxes [02:34:11.0473] Could we split objectplaceholder/box into further proposal? Consdier it could be implemented by symbol as weakmap keys? [02:35:11.0640] CompositeKeys for Maps is a key use case for Tuples, which i think a lot of people will want [02:35:23.0009] So I don't think this is a niche use-case, to want objects in Tuples [02:35:42.0233] right, but again, my question is "why not just put objects in tuples, instead of having boxes" [02:36:35.0129] > <@bakkot:matrix.org> right, but again, my question is "why not just put objects in tuples, instead of having boxes" good question. actually I also think maybe it's much fit for js? consider other similar languages also choose that way? [02:41:16.0193] > <@aclaymore:matrix.org> So I don't think this is a niche use-case, to want objects in Tuples this is probably the underlying question [02:41:59.0209] do the R&T champions think mutable exit points is common? if so, then why not bakkot's suggestion? if not, then why not symbols (technical problems notwithstanding) [02:42:51.0894] so far i've heard one argument against "why not bakkot's suggestion" is the need for _primitive_ mutable exit points as well [02:43:01.0148] but then again the current solution also doesn't admit that [02:43:45.0069] As I mentioned, there are a lot of issues with direct objects inside primitives. One was it's a footgun, and a user might mistakenly put mutable data where they didn't expect it. The other is the same security concern as how to "dereference" an ObjectPlaceholder. Existing code assumes that if something is a primitive, it doesn't contain object which represent authority. It would break a lot of deployed membranes and SES. [02:43:52.0421] Maybe we need two things: Tuple (which could include object directly) and PrimitiveTuple [02:44:21.0542] Mathieu Hofman: i remain baffled by the footgun argument [02:44:30.0483] if it's common, you're asking people to look up incantations to do what they want [02:45:21.0854] The other programming experience may not support footgun argument. Though JS may be have something special I don't know... [02:45:39.0209] > One was it's a footgun, and a user might mistakenly put mutable data where they didn't expect it Boxes don't really help that, since `#[foo()]` may or may not be a box and so may or may not be mutable. Also boxes are super complicated so it seems like there's at least as much possibility for footguns there > Existing code assumes that if something is a primitive, it doesn't contain object which represent authority. But boxes _are_ primitives which contain objects; this argument confuses me [02:45:57.0502] > <@shuyuguo:matrix.org> if it's common, you're asking people to look up incantations to do what they want I'm not following [02:46:33.0766] Yeah, I remember the author of scala.js also point out some footgun of using Box in the issue. [02:46:52.0216] if wanting objects-as-mutable-exit-points-in-records is a common use case, i assure you people will do what they want to do, and just look up the incantation to do that. in that light, i'm not too convinced that you've avoided any footguns [02:47:19.0029] So I am also not sure whether box could really solve the "footguns" of object in tuples. [02:47:32.0113] + what's already been said about not knowing the return type of `foo()` [02:47:41.0712] > But boxes _are_ primitives which contain objects; this argument confuses me But you need access to the `ObjectPlaceholder` to get to the content, so they are not a risk on their own [02:47:43.0853] lol why does element convert `+` to a single bullet point list [02:48:25.0795] > <@mhofman:matrix.org> > But boxes _are_ primitives which contain objects; this argument confuses me > > But you need access to the `ObjectPlaceholder` to get to the content, so they are not a risk on their own eventually developer would like to write some conditional logic and it could cause footgun in some way... as the author of scal.js shows. [02:48:40.0706] > <@shuyuguo:matrix.org> if wanting objects-as-mutable-exit-points-in-records is a common use case, i assure you people will do what they want to do, and just look up the incantation to do that. in that light, i'm not too convinced that you've avoided any footguns At least they've thought of it and the incantation is an explicit marker in the code [02:49:41.0849] https://github.com/rbuckton/proposal-regexp-features/issues/2 [02:49:45.0861] Basically ObjectPlaceholder is a standardized "Symbol as weakmap key + global weakmap registry" [02:50:59.0063] * Basically ObjectPlaceholder is a standardized "Symbol as weakmap key + global (per realm) weakmap registry" [02:51:19.0219] i would still like to know the "how common a use case do you expect mutable exit points to be" question [02:52:22.0000] > <@haxjs:matrix.org> eventually developer would like to write some conditional logic and it could cause footgun in some way... as the author of scal.js shows. I did not see any footgun in that example [02:53:33.0871] > <@shuyuguo:matrix.org> i would still like to know the "how common a use case do you expect mutable exit points to be" question We initially didn't consider it, but after some users come up with the question "why only primitives?" (https://github.com/tc39/proposal-record-tuple/issues/31) we have started talking about it and found that users would love to be able to store objects because many things are not representable as immutable (for example, everything that comes from the dom) [02:53:55.0663] > <@mhofman:matrix.org> I did not see any footgun in that example Actually in the thread there are some code example to deal with box conditionally and have bugs, which seems a signal of footgun. [02:54:12.0170] Agoric has discovered a strong need for records/tuples in order to make sure a Proxy can't be used to interleave code while traversing an apparently inert (deeply frozen) object. All these records do need to contain exit points (proxies/references to remote objects) [02:54:26.0382] > <@shuyuguo:matrix.org> i would still like to know the "how common a use case do you expect mutable exit points to be" question * Agoric has discovered a strong need for records/tuples in order to make sure a Proxy can't be used to interleave code while traversing an apparently inert (deeply frozen) object. All these records do need to contain exit points (proxies/references to remote objects) [02:54:28.0295] > <@mhofman:matrix.org> Basically ObjectPlaceholder is a standardized "Symbol as weakmap key + global (per realm) weakmap registry" Seeing it explained this way would be illuminating. [02:55:55.0527] okay, thanks for the anecdotes [02:56:58.0885] I have extremely strong reservations about making this be per-realm just for agoric's use case. [02:57:28.0768] > <@bakkot:matrix.org> I have extremely strong reservations about making this be per-realm just for agoric's use case. This is not just for agoric's use case, this is for any cross realm membranes [02:57:43.0721] shu: the original need for boxes came up from framework authors, the ability to reference functions (handlers) in R&T seems essential if they want to be able to use R&T instead of objects [02:57:51.0476] same with dom elements [02:57:53.0048] > <@bakkot:matrix.org> I have extremely strong reservations about making this be per-realm just for agoric's use case. it's ses use cases if i understand correctly... [02:57:53.0579] ok, same comment but with "just for existing cross realm membranes" [02:58:05.0877] actually for agoric, it's not a problem if an ObjectPlaceholder can only be created explicitely [02:58:10.0756] so we will end 35 minutes early in the morning? [02:58:17.0379] +1 to bakkot [02:58:39.0498] and by "framework authors", is it react, or multiple frameworks? [02:59:48.0479] react and many react-like frameworks I guess 😅 [03:00:34.0217] to clarify my +1: i personally would give mid-weight to frameworks' need, especially if it extends beyond just one, and would give no weight to membrane enablement [03:00:39.0568] "we will add it because it exists elsewhere" is such a terrible argument [03:01:07.0291] yeah especially with regexes becauses everyone in the world has just copied Perl, which put everything anyone ever thought of into their regexes [03:01:21.0581] > <@shuyuguo:matrix.org> to clarify my +1: i personally would give mid-weight to frameworks' need, especially if it extends beyond just one, and would give no weight to membrane enablement This is not enablement, this is actually breaking security expectations of exiting deployments [03:02:08.0363] but side tables (again, with the symbol technical issues notwithstanding) also work for agoric, right? [03:02:18.0518] "I'd have to remember this `(?=\R?\z)` pattern" isn't much different than "I'd have to remember the difference between \z and \Z", except the former reads easier [03:02:24.0181] One way to avoid the footgun of storing object in tuples maybe, make it explicitly, not by "box", but by "key"? for example only special key could store object: #{a: 1, &onclick: ()=>{} } [03:03:26.0397] For the JSX use case, my first thought was: so R&T should be compared by value, _but_ treat all box as the same, otherwise it's not likely to speedup vdom based frameworks because most people don't write "useCallback" for their callback then the JSX record will always !==, Then the framework has to do the old classic diff algorithm and gain nothing from adopting record and tuple. [03:03:38.0406] The main issue with symbol and side tables is being able to detect and target where the exit points are. It becomes an ergonomics issue of using them [03:03:50.0721] Jack Works: R&T is not likely to speed up vdom at all in any world [03:04:02.0656] At the end of this session I've scheduled 5mins to discuss this clarification to the agenda deadline rule that Jordan talked about in this channel a week or so ago https://github.com/tc39/agendas/commit/d2ef80976759f763eaf621b851479753e29b081c#diff-0b87e2fc7748588525a23909f36542c8244da7bf86fe1e93ee9715e549f7944b [03:04:32.0109] > <@shuyuguo:matrix.org> Jack Works: R&T is not likely to speed up vdom at all in any world I know. Just my first thought when I see that use case. [03:06:30.0548] that seems like the best possible fix! [03:07:15.0635] And I have another question. Months ago, Record and Tuple decides to use Symbols as WeakMap keys as the solution of storing objects. Why we have Box now? [03:08:07.0924] Because we found opposition against symbols as weakmap keys because of registered symbols (wich could never be collected) [03:08:35.0991] Is that really a problem? [03:08:55.0663] Set object on the global this can get the same result [03:09:08.0261] 2 main reasons: - Leaking issues with well-known and registered symbols - Box is an explicit marker of intent, where symbol can be just other data. You don't need knowledge about the structure to understand what it means [03:09:13.0393] > <@nicolo-ribaudo:matrix.org> Because we found opposition against symbols as weakmap keys because of registered symbols (wich could never be collected) what is registed symbols? [03:09:13.0650] > <@jackworks:matrix.org> Set object on the global this can get the same result No, because the global can still be collected (when it's realm is collected) [03:09:34.0590] > <@nicolo-ribaudo:matrix.org> No, because the global can still be collected (when it's realm is collected) But WeakMap itself can be collected too [03:09:36.0821] > <@haxjs:matrix.org> what is registed symbols? `Symbol.for()` [03:10:27.0225] > <@jackworks:matrix.org> But WeakMap itself can be collected too (I made the same point in the past, it wasn't me who didn't want symbols as weakmap keys 😅) [03:10:38.0213] Sorry I don't understand leaking issues, is there any link to explain that? [03:11:14.0250] Oh so is that means the Symbols as WeakMap key proposal is dead? [03:11:27.0117] https://github.com/tc39/ecma262/issues/1194 [03:12:21.0845] so why not throw type error if weakmap meet a registed symbol? [03:12:31.0122] If Box / ObjectPlaceholder exists, there is no need for symbols as weakmap keys, and the same semantics can be accomplished by creating a box of an empty meaningless object [03:12:32.0578] * so why not throw type error if weakmap meet a registed symbol? [03:13:54.0829] > <@haxjs:matrix.org> so why not throw type error if weakmap meet a registed symbol? there is opposition to that because it'd require users to understand the difference between registered and unique symbols [03:14:01.0088] > <@mhofman:matrix.org> If Box / ObjectPlaceholder exists, there is no need for symbols as weakmap keys, and the same semantics can be accomplished by creating a box of an empty meaningless object Exactly, they are two alternatives that unlock the same unsecases [03:14:09.0444] MM gave a great summary [03:14:13.0029] So R&T is the only use case for that? [03:15:28.0342] > <@mhofman:matrix.org> there is opposition to that because it'd require users to understand the difference between registered and unique symbols good point, though I don't think it's a big problem, if symbol as weakmap is mainly used to implement box as low-level mechanism. [03:15:48.0116] > <@jackworks:matrix.org> So R&T is the only use case for that? definitely not, `ShadowRealm` based membranes are also a primitive in weakmap use case, but as I mention just above, you can accomplish the same with Box [03:17:24.0858] i don't hate this proposal, but also this seems like one of those things which ~zero people are going to use until after they get the CVE [03:18:21.0781] LOL [03:18:31.0484] regexes are already too complicated for most people to figure out if they're going to have catastrophic backtracking and this proposal proposes to solve that by making them more complicated [03:18:50.0629] so tbh I feel like the "so then they had to rewrite without a regex" is not so bad [03:19:14.0439] Alt: research how to teach regexp systematically [03:19:20.0518] > <@bakkot:matrix.org> i don't hate this proposal, but also this seems like one of those things which ~zero people are going to use until after they get the CVE even they get CVE, I guess they will not use feature but just write a special function to trim end newlines... [03:21:30.0488] For Waldemar's question: It's impl defined? If it sees `\n++$`, and that didn't match, the impl can advance 100k chars, then restart trying [03:27:13.0619] I hate how all these regexp proposals are phrased in terms of a feature and not a problem we're trying to solve [03:27:53.0112] I'm fine for stage 1 for looking into catastrophic backtracking issues, but not okay with committing to this solution, which is how I know it will be mistaken [03:30:06.0106] The atomic operators appears to be a new "middle" counting type. [03:30:22.0766] A greedy non-backtracking type. [03:30:52.0070] The description of backtracking was too terse. Does "(?>...) will not backtrack in the event of a failed match" mean that it turns off backtracking internally only when going into or out of the group? [03:31:01.0768] When does backtracking reset for ++? [03:31:38.0376] For the example /[\r\n]+$/, using the non-greedy quantifier (/[\r\n]+?$/) also solves the O(N^2) case. [03:31:46.0225] A fair amount of the regexp problem space is a known quantity given the broad adoption across multiple languages and runtimes. The biggest issue with catastrophic backtracking is that its not an easy to solve problem. Perl has a significant amount of additional backtracking control verbs over what I've proposed. [03:32:44.0657] What is going on in the 100,000 newlines example? Both backtracking and nonbacktracking should be O(n²) if the description is correct. However, such a huge difference in running time means something else is going on. [03:32:54.0146] Most of which I would consider to be "far to complex" to add to the language. [03:33:25.0998] My concern is that the developer doesn't understand the full implications of the backtracking control. It is an implementation detail (currently shared among most implementations), that they likely get wrong. [03:33:54.0767] Typo: Does "(?>...) will not backtrack in the event of a failed match" mean that it turns off backtracking internally or only when going into or out of the group? [03:34:39.0538] It would have to be just for that group. [03:35:41.0767] What happens if you have something like /a*(?>...)/? Does the ?> lock in the first time it fails and not try some other match with a different number of a's? [03:35:57.0914] how would we even go about specifying the backtracking control if we don't specify the regexp evaluation mechanics? [03:37:12.0224] We do specify RegExp evaluation semantics [03:37:34.0594] rbuckton: and those semantics necessitate catastrophic backtracking today? [03:37:36.0206] Quantifiers are specified here: https://tc39.es/ecma262/#sec-runtime-semantics-repeatmatcher-abstract-operation [03:37:36.0750] I don't think so [03:38:05.0425] The trailing ? is really {0.1} and therefore it should backtrack, but not the (?>...) itself. I think this requires saving the state of the (?>...) for the trailing ? backtracking. [03:38:07.0386] we specify as-if semantics, which does not correspond to what engines actually do [03:38:39.0688] exactly, so I again ask how we would specify this feature [03:38:55.0793] we do not currently put _any_ execution time constraints on regex performance [03:39:33.0546] exactly, so I again ask how we would specify this feature [03:39:39.0259] > <@msaboff:matrix.org> For the example /[\r\n]+$/, using the non-greedy quantifier (/[\r\n]+?$/) also solves the O(N^2) case. It's a failed match, so greedy or nongreedy shouldn't make any difference — they both must check all possibilities, they just do it in the opposite order. Of course that assumes no hidden implementation optimizations that somehow apply to one and not the other. [03:40:24.0580] Michael Ficarra: Specifying Possessive would likely be the similar to specifying Greedy in RepeatMatcher. [03:40:49.0844] > <@waldemarh:matrix.org> It's a failed match, so greedy or nongreedy shouldn't make any difference — they both must check all possibilities, they just do it in the opposite order. Of course that assumes no hidden implementation optimizations that somehow apply to one and not the other. The impl can advance beyond the non-match [03:40:56.0396] * Michael Ficarra: Specifying Possessive would likely be the similar to specifying Greedy in RepeatMatcher. [03:41:07.0083] Huh? [03:41:14.0283] It doesn't have to check index 1, 2, 3, 4, etc [03:41:25.0538] > <@waldemarh:matrix.org> It's a failed match, so greedy or nongreedy shouldn't make any difference — they both must check all possibilities, they just do it in the opposite order. Of course that assumes no hidden implementation optimizations that somehow apply to one and not the other. In the non-greedy case, I don't think you back track each character. [03:41:30.0092] In order to get a non-match, it must check all possible lengths of [/r/n]+. [03:41:34.0511] It tried 100k chars, didn't match, advance 100k chars [03:41:57.0768] That's what I was asking Ron about. [03:42:22.0245] The answer I got at the meeting was that it would retry for each starting index. [03:42:51.0132] If that's not what it's doing, then what it is doing needs to be described better. [03:43:55.0352] I will expand on the proposal for a future meeting, with more details on matching behavior (and possibly a prospective spec) to clarify matching behavior. [03:45:07.0376] The other alternative is that there is some secret optimization that triggers based on regular expression minutiae, and the ++ version just happens to trigger the secret optimization even though it should still be O(n²). If that's the case, then an implementation could choose to apply the same optimization to the original version too. [03:45:32.0939] fwiw V8 implemented an explicit opt in "linear mode" via a flag [03:45:39.0385] but experiment didn't pan out [03:45:55.0802] among other things, the technical challenges to performantly switch between modes were many and difficult to solve [03:46:11.0230] * fwiw V8 implemented an explicit opt in "linear mode" via a flag [03:46:34.0050] oh interesting, I didn't even consider the possible implementation difficulties for this feature [03:46:45.0908] (but i also don't know any more details, not my area of expertise) [03:47:12.0700] does v8 currently have someone working specifically on the regex engine you could float this by? [03:47:31.0152] irregexp is in maintenance mode, but we have someone who knows enough to add new features [03:47:34.0328] i will certainly float this by them [03:48:39.0609] someone is... playing music? [03:48:42.0753] is that just me hearing this [03:48:50.0921] Justin Ridgewell: ^ [03:48:55.0683] _funky_ music [03:49:06.0220] I'm muted? [03:49:12.0920] > <@msaboff:matrix.org> In the non-greedy case, I don't think you back track each character. I checked in JSC and /[\r\n]+$/ takes 11 seconds and /[\r\n]+?$/ takes 7 seconds. Looks like /[\r\n]+$/ is O(2n^2) and /[\r\n]+?$/ is O(n^2). So still n^2. [03:49:23.0381] > <@jridgewell:matrix.org> I'm muted? now you are [03:49:36.0644] I'm assuming a chair muted you [03:49:43.0526] Oh, but I've got no music. [03:50:09.0733] now someone is doing dishes [03:50:09.0742] strange, maybe Jitsi was misattributing the noise to you [03:50:17.0304] is someone cooking now [03:50:27.0322] Breakfast? [03:50:30.0051] sounds like dishwasher [03:50:36.0761] loading dishwasher rather [03:51:08.0134] it was sarahghp muted you Sarah 😀 [03:51:22.0986] The kitchen is closed! [03:51:32.0811] no more dishes for you 😛 [03:51:40.0138] * no more dishes for you 😛 [03:53:45.0482] I'm so sorry. I never explicitly unmuted, so I dunno. It was unloading. [04:07:36.0911] BTW wasm CSP was promoted from phase 1 to phase 3 (implementation phase) two days ago https://github.com/WebAssembly/meetings/blob/main/main/2021/CG-10-26.md (notes are not published yet) [04:09:57.0957] did I miss "Agenda deadline rule clarification"? [04:10:09.0230] no, we haven't done that yet [04:22:52.0638] Are there still plans to have a CoC Committee update? [04:33:14.0840] jschoi: most likely not, unfortunately. [04:42:23.0412] > <@michaelficarra:matrix.org> did I miss "Agenda deadline rule clarification"? no - I'll do it first thing after the break [04:43:27.0487] (or Jordan can!) [04:59:41.0243] we are starting in 1 minute [05:02:34.0096] Auto-merge bot for TC39 org members [05:03:27.0971] Rob Palmer: i would like the opportunity to discuss evaluator attributes still, there's a reason it was a schedule constraint [05:04:23.0327] you can just merge your own PRs [05:04:25.0161] don't need a bot [05:04:40.0031] Ahh [05:06:58.0977] I feel like it's painfully obvious that a PR is sufficient for this requirement [05:07:36.0858] Slides for next presentation are at https://docs.google.com/presentation/d/1MShu-uA_gz1LDpmlckQ9Wgsb0ZLylYV0QWZBnsTAOGk/edit?usp=sharing. [05:08:04.0573] the history of the agenda repo is just "Update" [05:08:42.0523] Rob Palmer: I can try to give a brief CoC update as well, whenever [05:08:56.0405] * Rob Palmer: I can try to give a brief CoC update as well, whenever [05:09:29.0055] > <@ljharb:matrix.org> Rob Palmer: i would like the opportunity to discuss evaluator attributes still, there's a reason it was a schedule constraint we have 10 mins at the end - Guy suggested it too [05:11:25.0486] I completely disagree with the point on the slide that `identity` could ever be clearer than `x => x` [05:12:16.0129] extremely strong +1 [05:12:22.0361] i disagree more strongly with `constant(x)` over `() => x` [05:12:47.0980] shu: it'd be `x => () => x` [05:13:00.0436] wat [05:13:05.0000] that wouldn't be what constant(x) returns [05:13:07.0688] that's how you would define constant [05:13:13.0808] no I mean that'd be `constant` [05:13:23.0827] * no I mean that'd be `constant` [05:13:39.0085] right but instead of `constant(x)` you should write `() => x`, is the point [05:13:40.0732] oh I see what you mean, you mean replacing that whole expression with the arrow [05:13:50.0504] * oh I see what you mean, you mean replacing that whole expression with the arrow [05:14:49.0097] ... what's a "fluture"? [05:15:08.0155] fantasyland promise [05:15:08.0953] i have certainly made a `thunk` helper that is `x => () => x`, but i don't think that needs to be in the language [05:16:14.0791] I don't think this needs to be in the language [05:16:52.0660] `uncurryThis` should be though [05:16:58.0053] and I could see `flow`, maybe [05:17:07.0166] `flow` (function composition) is interesting, but I think it being single-parameter makes it kinda awkward for JS [05:17:07.0482] `once`, also [05:17:22.0794] once is great, I write once all the time [05:17:26.0389] how... can we specify debounce? [05:17:28.0004] and it's annoying [05:17:30.0553] `debounce` and `throttle` don't work without time though, which probably don't belong in JS [05:17:36.0560] yeah these can't be in 262 [05:18:10.0047] HTML would probably add them if you asked them to though [05:18:11.0054] I'm thinking these should be split into separate proposals because many of them *clearly* don't stand on their own [05:18:25.0234] yes [05:19:29.0349] i don't think we should encourage this kind of approach to proposals -- we should work with concrete problem statements rather than giving an arbitrary blank check on "we will add function helpers" [05:20:00.0562] +1 to more scoped problem statement [05:21:44.0737] yeah, I like really lightweight proposals [05:22:02.0231] like, `flow` and `flowAsync` belong in the same proposal, but neither obviously belongs in the same proposal as `uncurryThis` or `once` [05:22:08.0076] yes [05:22:11.0486] I don't want to talk though [05:22:22.0000] someone maybe could put this on the queue [05:26:47.0011] ptomato: you ready for temporal overflow in a few mins? [05:27:26.0171] Over the break I read and reread RepeatMatcher, but I don't think I'm incorrect in my understanding of backtracking. For `/\n+$/.test("\n".repeat(100_000) + "b")` we end up in a stack 100,001 calls to RepeatMatcher deep before we (a) fail to match an `\n` and then (b) fail to match the end of the buffer. We then unwind the stack, attempting to match the end of the buffer for each entry on the stack. This means we test for `$` at offset 100,000, then at 99,999, then 99,998, etc. until we fail at offset 0 (matching no `\n` characters). Now that this has failed, we advance to the next index in RegExpBuiltInExec, and do it all over again. [05:27:48.0568] > <@bterlson:matrix.org> ptomato: you ready for temporal overflow in a few mins? justingrant: ? [05:28:34.0999] Yep! [05:28:52.0579] @ptomato should be on shortly [05:29:15.0337] I'm presenting today (only 2 slides) [05:29:27.0992] rbuckton: The spec doesn't mandate that you implement in that way if it's not observable [05:29:40.0313] Jack Works: you have some music in the background [05:30:48.0924] Michael Ficarra: True, but my point is that backtracking retries the pattern to the right of the quantifier for each possible choice of repeated `\n` characters, starting with the largest. [05:32:52.0398] There are possible optimizations if the remaining pattern is a fixed length set of characters, if the Atom being repeated could not be matched by the continuation, but a regexp can easily be crafted that breaks those optimizations. [05:33:48.0248] rbuckton: so you're saying any implementation of a JS regexp matcher today necessarily has catastrophic backtracking? [05:34:12.0501] Why would we block time-related functions. We have to have time-awareness in JS for `Atomics.wait` or `Atomics.waitAsync`. I think a `Promise.delay` polyfill could be built purely on top of `waitAsync` without depending on the DOM Timers API. [05:34:56.0236] doesn't Atomics only wait for something in another thread to make a change in a SAB? [05:35:05.0496] there's a timeout [05:35:05.0872] * doesn't Atomics only wait for something in another thread to make a change in a SAB? that's not involving time [05:35:07.0893] ah [05:35:25.0059] erights: the timeout in Atomics.wait isn't an issue? [05:35:42.0775] You can use `Atomics.wait` to emulate `sleep` in NodeJS or in a Web Worker. [05:35:56.0070] my concern isn't any SES concern to be clear [05:36:13.0425] i don't think the value add is enough to add more fairly heavyweight hooks to the spec to queue tasks [05:36:18.0702] if we want these just add these to html [05:36:25.0166] have node implement them [05:37:28.0204] Atomics.wait's timeout is special in that the waiting thread is literally blocked [05:37:39.0025] Atomics.waitAsync's timeout is more analogous [05:37:52.0388] IMO, I'm not too enthusiastic about `debounce`/`throttle`, as a purpose-built solution can be more flexible (sliding windows, minimum/maximum delays, etc.) [05:38:18.0779] * Why would we block time-related functions? We have to have time-awareness in JS for `Atomics.wait` or `Atomics.waitAsync`. I think a `Promise.delay` polyfill could be built purely on top of `waitAsync` without depending on the DOM Timers API. [05:38:24.0586] good to know [05:38:25.0724] with throttle, most use cases run the function after the window, but some want to silently drop instead, so to standardize we'd have to have a way to allow both [05:38:44.0080] * with throttle, most use cases run the function after the window, but some want to silently drop instead, so to standardize we'd have to have a way to allow both [05:39:21.0388] lack of standardization in existing methods is arguably a good reason to have it in the platform [05:39:44.0228] what's the chance that Temporal is bug-free by the time it hits stage 4? 0? I think 0. [05:39:48.0826] Michael Ficarra: Is it not true that given the features we have and the semantics we want (e.g. best match), you can craft a regexp with "catastrophic" behavior, and doing that pattern non-catastrophically would result in observably different semantics in some cases? I thought I learned this at one point. [05:40:04.0211] i don't think any userland implementation i've seen commonly used implements the drop use case. but someone asked about it in a chatroom just the other day [05:40:29.0210] bterlson: I'm not sure. I want to know this. [05:41:02.0313] you can absolutely craft a regex that hangs v8 but not spidermonkey, and have been able to for many years; not sure if that's the question [05:41:07.0942] * you can absolutely craft a regex that hangs v8 but not spidermonkey, and have been able to for many years [05:41:24.0848] * you can absolutely craft a regex that hangs v8 but not spidermonkey, and have been able to for many years; not sure if that's the question [05:41:34.0598] ljharb: not talking about existing implementations, talking about theoretical implementations [05:41:34.0992] how can that be possible [05:41:38.0425] SM switched to irregexp [05:41:44.0046] oh maybe it hangs spidermonkey now, i haven't checked [05:41:50.0785] * oh maybe it hangs spidermonkey now, i haven't checked [05:42:20.0694] I feel like I read something recently about an engine which after a while switches to an implementation which is slower in common cases but guaranteed not to be catastrophic [05:42:24.0187] but maybe that was not JS [05:42:55.0746] that's what linear mode turned out to be, but we're not going to ship it [05:43:00.0513] not sure if you're thinking of linear mode [05:43:02.0997] oh, got it [05:43:05.0691] probably am [05:43:40.0592] it was an intern project to add a new flag that opts into a linear only, no backtracking regexp engine [05:43:45.0283] I also think that's only true in theory with like infinite memory, and also might not work with e.g. backrefs or other non-regular features? [05:43:56.0343] > <@ljharb:matrix.org> oh maybe it hangs spidermonkey now, i haven't checked oh that would be weird, we use v8's regexp engine [05:43:56.0978] (or without preserving ES best match semantics) [05:44:13.0384] Best match isn't the issue [05:44:25.0944] It's just the backreferences and unbounded look-arounds [05:44:43.0757] It's not possible to implement all the required features without using a backtrack impl [05:44:52.0277] So everyone implements a backtrack impl [05:45:36.0838] thank you Justin Ridgewell that's what I was expecting [05:52:08.0319] https://v8.dev/blog/non-backtracking-regexp [05:52:13.0533] found the article I was thinking of [05:52:50.0835] relevantly, it only works in the absence of backrefs and lookarounds [05:55:05.0210] that engine could support backreferences with better average performance than irrgexp but they want to keep it separate [05:56:09.0984] Just making sure: There’s going to be a call for incubator topics at the end of the plenary, right? [05:56:49.0621] should be, yes [05:57:08.0386] ljharb: technically i could have Object.prototype.smallestUnit [05:58:03.0475] in that case `{}` wouldn't be an empty object [05:58:37.0776] i think we're using `{}` here to mean "an object for which a Get() of all relevant properties returns undefined", or similar [05:58:58.0435] (`{ x: 1 }` would be an empty object wrt Temporal, eg) [05:59:17.0473] i mean it's not an empty object [05:59:25.0340] it's an object without the property, sure [05:59:51.0128] "an object empty of relevant temporal properties" is the case we're talking about, it's just longer to say [06:16:16.0079] ljharb: i feel very strongly in the opinion that wasm use cases at the boundary *are* JS use cases [06:16:19.0694] as is the case here [06:16:53.0295] it is clear that folks who are invested in wasm feel that way [06:16:54.0509] * it is clear that folks who are invested in wasm feel that way [06:17:29.0811] that's a gross mischaracterization [06:17:44.0644] do we take notes on COC report? [06:17:47.0358] I assume no? [06:17:49.0663] "folks who are invested" are like... several large multinational corporations with lots of product teams devoted to it? [06:17:55.0452] > <@ljharb:matrix.org> erights: the timeout in Atomics.wait isn't an issue? I thought there is no time in the ES spec until I see this `Atomics.wait` [06:17:58.0697] so it's not like a fringe group on the internet [06:20:33.0200] sure, no such "fringeness" was implied [06:21:11.0908] bakkot: high-level notes are fine, probably best not to include discussion of specific moderation actions [06:21:28.0434] ljharb: feel free to redact notes, we have a verbatim transcript as usual atm [06:21:35.0911] cool, will do [06:22:45.0935] Pipe group wants a pipe incubator call for bikeshedding the topic token. [06:31:10.0020] don't forget to review the notes! [07:05:11.0633] happy end of plenary everyone, now go to sleep [07:05:16.0117] :) [07:09:57.0123] > <@michaelficarra:matrix.org> don't forget to review the notes! For anyone new to note-taking. I've been using https://rogueamoeba.com/audiohijack/ so I can pause/re-wind/jump-to-live the audio using global hotkeys. Which I've found makes bot-helping much less stressful. [07:11:05.0269] I did start trying to put something together with the WebAudio apis that could add a delay that I could use on windows but didn't get it to work with routing between different apps and outputs [07:11:37.0666] everytime I did a google for 'windows audio buffer delay utility' I just got results for how to fix my audio delay issues. Not introduce one on purpose [09:08:33.0785] what kind of `ExpressionStatment` is the `let [` negative lookahead trying to guard against? what expression starts with `let [`? [09:09:10.0504] oh duh, let is a valid identifier in sloppy mode