2023-09-01 [21:06:35.0425] @shu We do a thing in SES that Mark calls “enablements” to compensate for the override mistake which may be of interest: We replace the non-writable property with a getter/setter pair. The prototype is still effectively frozen, but assignment-override works. We’d be delighted to be in touch. [09:47:45.0295] Kris Kowal: Yes, we considered taking this approach for `Iterator.prototype[Symbol.toStringTag]` because of this exact issue with regenerator-runtime (see https://github.com/tc39/proposal-iterator-helpers/pull/213), but instead decided to just make the property writable [09:51:04.0788] this is interesting: https://twitter.com/webreflection/status/1697518069554299121 - isn't there some security thing around SAB that this seems to bypass via wasm? [09:54:19.0787] that's always been the case (since COOP/COEP shipped) [09:54:28.0257] it's explicitly allowed, and wpt uses it in testing [09:54:52.0234] the actual capability is the sharing of memory, not the SAB constructor. without COI you still can't postMessage the buffer across workers [09:54:54.0258] the problem isn't getting a SAB, it's being able to share it to workers [09:55:05.0686] see step 13.1.1 of https://html.spec.whatwg.org/#structuredserializeinternal [09:55:59.0074] this is my "fault" technically: https://github.com/whatwg/html/issues/4732#issuecomment-598470434 [09:56:13.0482] but we did it for compat reasons for chrome users [09:56:33.0040] > <@michaelficarra:matrix.org> Kris Kowal: Yes, we considered taking this approach for `Iterator.prototype[Symbol.toStringTag]` because of this exact issue with regenerator-runtime (see https://github.com/tc39/proposal-iterator-helpers/pull/213), but instead decided to just make the property writable I don’t think we’d recommend “enablements” as a general language compensation for override-mistake, but we do recommend replacing certain properties with accessors as a preparation for freezing a prototype in environments that freeze shared prototypes. [09:59:02.0493] the original plan, was, in fact, to make SAB always available [10:15:48.0853] ah ok, thanks, that makes sense [10:50:53.0335] Stage 3 won't become a silver bullet for proposal changes. [11:44:00.0713] of course, changes can be made in response to implementation feedback [11:45:14.0401] the point of this change is to catch necessary changes before we get to the point of implementation so we don't waste implementers' time, not to have an indicator of rock-solid stability [14:28:11.0958] Huh, facilitating feature detection seems like a good thing… [14:28:31.0144] (I saw parts of this controversy but never really followed along closely enough) [14:30:07.0245] I agree with Leo. Actually, HTML integration is already a requirement in practice, just randomly enforced by certain delegates (including me), and it has been this way for years [14:30:14.0064] We should document this [14:30:32.0088] * I agree with Leo. Actually, HTML integration is already a Stage 3 requirement in practice, just randomly enforced by certain delegates (including me), and it has been this way for years [14:30:45.0382] It feels funny to have html be special but it just is [14:30:58.0332] I think that is why we have hesitated to document it so far [14:33:26.0642] littledan: I agree but I don't think it needs to be combined with my proposed process change [14:34:00.0040] as we saw at the last meeting, it is already hard for some delegates to understand the process change [14:34:04.0304] > <@michaelficarra:matrix.org> littledan: I agree but I don't think it needs to be combined with my proposed process change Sure they are separate, maybe good for Leo to put this other point on the agenda for this meeting [14:34:47.0342] As far as I am concerned, HTML integration is already a requirement, just a poorly documented one, unlike your proposal which is a genuine change in how we work [14:49:00.0318] process or no process my personal resolve going forward is i will block stage 3 on proposals where there's non-trivial amounts of semantics in the integration [14:49:16.0542] * process or no process my personal resolve going forward is i will block stage 3 on proposals where there's non-trivial amounts of semantics in the integration, and the integration is not yet done [16:03:50.0015] eh, i guess arguably the right way to feature detect is `self.crossOriginIsolated`, not the existence of the SAB constructor [16:51:42.0541] > I can share that our tamper resistance mode is enabled by default 😩 2023-09-04 [19:43:22.0880] > TDZ, what is it good for? lol shu I expect musical references from you now 🤣 [19:43:27.0365] * > TDZ, what is it good for? lol shu I expect musical references from you now 🤣 [11:42:06.0252] > <@rkirsling:matrix.org> > TDZ, what is it good for? > > lol shu I expect musical references from you now 🤣 it's actually a reference to the original title of War and Peace [16:49:46.0996] all's fair in TDZ 2023-09-05 [10:31:51.0270] > <@michaelficarra:matrix.org> > I can share that our tamper resistance mode is enabled by default > > 😩 yes this gives me concern [14:19:28.0859] Is Daniel Minor (Mozilla) in this channel? I've seen the agenda item proposing demotion of ShadowRealms to Stage 2. I'd love if we can link that agenda item to an open (new?) thread in the ShadowRealms repo. Considering the facts, I'd have to agree with the arguments and recognize there's an amount of work for HTML integration I initially underestimated. Saying that, we have work with Igalia restarting on this in October 1st. This update is as fresh as today. The budget cut happened initially along the mass layoffs and we are putting it back to order to continue the work here. Even if the demotion is unavoidable, I'd love we can set a plan for the next steps for what would be expected for re-requesting Stage 3. Having a thread linked to this agenda item, we can have pre-discussions and champions might be able to draw some estimates as well. [14:19:53.0941] littledan shu [14:20:02.0197] * littledan shu caridy [14:20:44.0283] dminor is here. [14:20:55.0775] Thank you, Kris Kowal ! I couldn't find it. For the ref: https://docs.google.com/presentation/d/1WJd9g3df_ibVHK3LdoKX2FboDwYQBUBJNxuRAWOYYbM/edit#slide=id.p [14:24:49.0446] i agree with dminor's points [14:25:13.0337] i think a demotion to stage 2 would be precisely to make the criteria for getting back to stage 3 clear [14:25:28.0082] (which is html integration) [14:25:54.0942] so any update Igalia or the champions want to provide on restarting that work would be towards the same goal IMO [14:26:19.0019] but the current state, as the slides say, is not implementable nor shippable [14:26:38.0222] also, recall Apple even had to unship because of a misunderstanding of what the HTML integration involved! [14:28:32.0691] I fully understand from this perspective. I just wish we had Michael Ficarra's mid-stage. While we don't have the new stage, hopefully we can agree to settle the current ES-specs as a like-stage-3 quality/stable. Of course this would still be subject to new changes for anything new identified in the HTML integration. Is that agreedable? [14:28:48.0279] * I fully understand from your perspective. I just wish we had Michael Ficarra's mid-stage. While we don't have the new stage, hopefully we can agree to settle the current ES-specs as a like-stage-3 quality/stable. Of course this would still be subject to new changes for anything new identified in the HTML integration. Is that agreedable? [14:29:36.0676] yes, i think it'd be good to reaffirm consensus that the 262 spec is fine as-is [14:29:41.0113] we've done that twice now, with import assertions and something else [14:29:50.0753] and that there are no further plans to redesign [14:30:06.0581] demotion to stage 2, with a consensus about what items are expected to make it re-eligible for stage 3 consensus (implying that other items aren't in scope) [14:31:05.0364] I'd propose we keep the proposed ES-spec as is, being the next steps HTML integration with tests. With the above complete, we reconsider it eligible for Stage 3, formal consensus still needed. [14:31:45.0158] that sgtm. not sure if dminor had more in mind [14:37:35.0476] dminor stated that Mozilla’s position (from last week’s SES meeting, recording forthcoming) is that they cannot ship without HTML integration fully specified and they are not particular about how the proposal gets staged. It could remain at stage 3 and HTML integration could be a follow-up. [14:38:12.0449] They’re also amenable to backing up to Stage 2. I think Leo’s proposal fits in that range. [14:38:39.0250] * dminor stated Mozilla’s position (from last week’s SES meeting, recording forthcoming) is that they cannot ship without HTML integration fully specified and they are not particular about how the proposal gets staged. It could remain at stage 3 and HTML integration could be a follow-up. [14:39:18.0499] ah i think mine is a little stronger, i would prefer demotion to stage 2 over remaining at stage 3 in the holding pattern waiting on HTML integration [14:39:39.0090] This works for me, I haven't discussed this with the other champions yet, but it seems pretty reasonable. Let me summarize the (pre) agreements I'm proposing: - The current ES-spec draft is good as is, there are no further plans to redesign. - We already have the tests for the ES-spec part, so no further Test262 "required". - HTML integration needs to be complete and include some fair coverage of tests. - White redesign is not expected, the champions are open for fixes. I'm doubling down on tests here as I want to make sure it's shippable, a bit more than the formal requirements for Stage 3. [14:39:44.0592] That is dminor’s understanding of your position as well, shu [14:40:04.0001] I'm not sure I'll be able to attend the TC39 meeting, so registering this here in the lack of a thread. [14:40:09.0027] * I'm not sure I'll be able to attend the TC39 meeting, so registering this here in the lack of an open thread. [14:42:35.0940] the summary I proposed is in case the demotion to Stage 2 happens. I don't see a better alternative for that right now so it feels like my best option. [14:55:08.0150] Mozilla’s position https://youtu.be/xbrsdwNVYKQ?t=87 [16:13:26.0836] Just to be clear, our position is that we should either demote to Stage 2, or remove the HTML integration from the proposal and keep it at Stage 3. We're not ok with keeping this at Stage 3 without more specification of the HTML integration. [16:14:16.0792] And V8's position as I understand it, is that removing the HTML integration is not a good idea for the web, so I think that leaves demotion to Stage 2. [16:14:40.0908] But I'm happy for the details to be worked out in plenary. [16:15:20.0065] * Just to be clear, our position is that we should either demote to Stage 2, or remove the HTML integration from the proposal entirely and keep it at Stage 3. We're not ok with keeping this at Stage 3 as it stands. [16:37:01.0325] oh man, cutting it super close with the iterator helpers thing [16:37:19.0240] we were like minutes away from pressing the kill switch button before the GH thread was updated that the upstream fix was rolled out [16:42:28.0299] This all sounds reasonable to me. I don’t think anyone is pushing for changes outside of the HTML integration, and our last couple demotions and repromotions gave me confidence that we as a committee can keep promises to ourselves. I am very glad that this is resuming with Igalia next month. [16:43:31.0279] I don’t think mficcarra’s extra stage has anything to do with this. I would basically hope for html integration to be in place to get to the new, earlier stage (though, sure, maybe it is only a fully hard requirement at Stage 3) 2023-09-06 [19:14:53.0128] ShadowRealms have different use cases, but the ones I need for my company are all Web related. So I agree we can't and shouldn't detach the HTML integration from it. I also see no advantage of the proposal remaining on Stage 3 if I don't have a fully "ready to implement" status yet. I concur to believe this committee will act as its best to continue moving the proposal forward even if needs to take a step back. I'm personally positive with the change and looking forward to continue the HTML integration process with Igalia! [07:18:10.0825] If we're looking for an issue to continue this conversation, I think this one that my colleague Matt opened a few months ago is the place: https://github.com/tc39/proposal-shadowrealm/issues/386 [07:38:33.0163] > <@shuyuguo:matrix.org> we were like minutes away from pressing the kill switch button before the GH thread was updated that the upstream fix was rolled out oh this is gonna make it after all? 🎉 [07:54:41.0471] > <@softwarechris:matrix.org> oh this is gonna make it after all? 🎉 yes [07:55:04.0095] but! given that the tamper-resistant mode that freezes intrinsics is turned on by default... [07:55:12.0451] need to be on the lookout for other breakages [07:56:18.0128] ah.. was hoping they would change their impl [07:57:59.0770] they turned it off for the one broken site that was reported [07:58:32.0345] here's to hoping their other customers have a regenerator runtime <2 years old 2023-09-08 [02:37:40.0059] it'll take 'til next week before I can get my colleagues to fill out the Doodle but it's safe to say that at least one of the days will have more than 24 people [02:58:14.0621] Thanks Ross. Does this also apply to the Wednesday dinner? [02:59:38.0958] Also, the Doodle is just for advertising. If folk want to attend they must fill in the registration for. That's the one I suggest you ask them to fill in if they are coming. [04:06:17.0470] er whoops. consider "Doodle" a misspeak on my part [04:06:49.0901] I'm not certain that any of the three plan to attend the dinner [08:12:53.0689] Q: If I were looking for well regarded criticism of Proxies as they exist in the language (perhaps retrospective "they were a bad idea"), does anyone have any pointers to things that they may not agree with but think are worthwhile viewpoints to consider (I'm seeking this as background to something I'm rolling around) [08:15:39.0570] (also, to be clear, I just want to understand the shape of criticism here) [10:02:37.0525] mgaudet: I think Proxies were a bad idea. Basically it comes down to one thing, with two angles, namely, they make code hard to reason about. this means that a.) any implementation, tooling, or library needs to account for the possibility of side-effects in many more places than they otherwise would and b.) anyone trying to read or maintain code which uses them has to reason about the behavior of that code in a fundamentally different way than any other code. basically, they add an incredible amount of complexity to the language, and the thing you get in exchange - "now objects can have a much wider range of behaviors when interacted with" - isn't even a good thing. [10:04:08.0614] Thank you :) That's a helpful comment. [10:04:44.0188] Should've just added `__method_missing__` [10:44:53.0223] why only hook behavior that's missing [10:45:00.0050] `__on_step__` [11:19:51.0952] I do wish proxies had more strict invariants where it would become inert (traps no longer invoked) once the language invariants says the proxy cannot change its answer anymore. More specifically, there is no good reasons for most proxy traps to be invoked if the proxy is frozen. I guess I'd prefer a mechanism that allows lazily building behavior, but not change that behavior dynamically forever. [11:22:28.0176] > <@bakkot:matrix.org> mgaudet: I think Proxies were a bad idea. Basically it comes down to one thing, with two angles, namely, they make code hard to reason about. this means that a.) any implementation, tooling, or library needs to account for the possibility of side-effects in many more places than they otherwise would and b.) anyone trying to read or maintain code which uses them has to reason about the behavior of that code in a fundamentally different way than any other code. > > basically, they add an incredible amount of complexity to the language, and the thing you get in exchange - "now objects can have a much wider range of behaviors when interacted with" - isn't even a good thing. this. 1000x this. [11:36:09.0221] > <@mhofman:matrix.org> I do wish proxies had more strict invariants where it would become inert (traps no longer invoked) once the language invariants says the proxy cannot change its answer anymore. More specifically, there is no good reasons for most proxy traps to be invoked if the proxy is frozen. I guess I'd prefer a mechanism that allows lazily building behavior, but not change that behavior dynamically forever. related to that, I think it was huge unwarranted complexity to require observable lookup of methods on the handler inside every operation rather than capturing those methods at proxy instantiation [12:28:01.0594] > <@gibson042:matrix.org> related to that, I think it was huge unwarranted complexity to require observable lookup of methods on the handler inside every operation rather than capturing those methods at proxy instantiation 1000% this also, that "live handler object" pattern is absurd 2023-09-09 [16:23:24.0577] oof, another one https://bugs.chromium.org/p/chromium/issues/detail?id=1480783 [16:32:57.0465] transcend again, yeah [16:32:58.0407] alas 2023-09-10 [18:58:14.0169] yeah i'm flipping the kill switch on monday [18:58:14.0840] sigh [18:58:22.0032] bakkot: could you put it on the agenda as well? [20:31:08.0698] shu: are these supposed to be here https://gc.gy/162021598.png [06:13:01.0613] very unlucky. it becomes harder to add new things especially if they're on the prototype. [06:14:18.0293] I can try asking to the regenerator maintainer to npm deprecate old regenerator versions [06:14:32.0136] * I can try asking to the regenerator maintainer to npm deprecate old regenerator versions if that would help [07:47:37.0803] that may help yeah [09:39:59.0037] snek: i believe so, yes [12:32:18.0373] shu: done [12:32:46.0695] listed you as presenter but presumably michael will have something to say as well 2023-09-11 [12:24:15.0613] reminder that the deadline to add things to the agenda is in 4 days 2023-09-12 [19:44:18.0271] time just gets away from us [20:01:12.0979] Which reminds me. Is anyone interested in taking over as reviewers for https://github.com/tc39/proposal-throw-expressions? Both of my previous reviewers had to step down. I can ask at plenary as well, but I was hoping to have reviewers and reviews lined up ahead of plenary to potentially advance it to Stage 3... [20:03:03.0030] rbuckton: you might consider putting it on the agenda anyway, and if you don't find reviewers before ask in plenary on the first day if anyone can review on short notice [20:03:08.0187] the proposal is small enough for that to be practical [01:12:49.0730] I can review [10:26:45.0819] FYI please do not add items to the agenda without listing a presenter 2023-09-13 [03:51:43.0236] anybody interested in picking up the date parsing proposal? https://twitter.com/domenic/status/1701888428244173166 [03:51:52.0389] this problem isn't going away on its own [07:54:29.0431] I’d actually plead to leave the problem unresolved and simply declare `Date` as broken. [07:54:37.0949] Temporal already solves the issue. [07:55:16.0852] So the canonical solution should be to migrate away from `Date` to `Temporal` instead of patching and modifying existing `Date` behaviour [07:55:54.0037] Especially as modifying the existing behaviour carries a risk of breaking the Web for anyone that has fixed this issue based on browser identification [07:56:24.0481] (That’s of course just my highly biased 0.02€) [07:57:33.0437] also, it seems like a single project aiming to match another needing to reimplement another engine's date parser, one time, isn't much evidence of it being "needed" [08:00:32.0116] pipobscure: you aren't considering that engine implementors are one audience of the specification [08:01:11.0609] there's no way for a new engine to implement Date.parse in a web-compatible way from scratch via the spec [08:01:33.0887] > <@michaelficarra:matrix.org> pipobscure: you aren't considering that engine implementors are one audience of the specification I don’t understand what you mean. Could you explain? [08:01:58.0970] > <@pipobscure:matrix.org> I don’t understand what you mean. Could you explain? (as in of course engine implementors are an audience of the spec) [08:02:11.0116] pipobscure: people writing new JS code are not the only ones who may be reading the spec to undstand how APIs are meant to behave [08:02:22.0832] > <@michaelficarra:matrix.org> there's no way for a new engine to implement Date.parse in a web-compatible way from scratch via the spec That’s the key part: NEW implementors [08:02:25.0829] True that [08:03:41.0000] Web compatibility depends on particular behaviour of Data.parse that is not encoded in the spec. It is our job to address that. [08:03:57.0996] I don't see how that could be argued [08:04:05.0318] Is there precedence for “Let’s specify what new implementations should do while leaving all existing implementations alone.” ? [08:04:08.0748] * I don't see how that could be argued against [08:04:24.0582] yes, all the time [08:04:34.0733] and it's "precedent" [08:06:30.0355] unfortunately attempts to gradually specify that in the past have been blocked, and the requirement seems to be "specify everything all at once, or specify nothing", hence nothing's been done [08:06:40.0679] error stacks is in the same boat [08:50:23.0974] > <@pipobscure:matrix.org> I’d actually plead to leave the problem unresolved and simply declare `Date` as broken. I would love to live in a world where we could get people to stop using old features, but alas I suspect it's not going to happen [08:50:38.0502] so I think it's still worth putting effort in, even for existing implementations, so we can avoid stuff like https://bugzilla.mozilla.org/show_bug.cgi?id=1825938 [08:53:02.0147] this is like, "we can't have justice, that's why we have the law", except it's "we can't tell people what to do, so we have standards that reflect reality" [09:17:40.0984] okay now that we all agree that clarifying Date.parse is, indeed, still valuable, does anybody want to take up this proposal again? [09:22:20.0668] if the goal is "_specify behavior of `Date.parse` that is required for web compatibility but not defined in the specification_", I don't think https://github.com/tc39/proposal-uniform-interchange-date-parsing applies—it would be a brand new proposal [09:23:17.0718] * if the goal is "_specify behavior of `Date.parse` that is required for web compatibility but not currently documented_", I don't think https://github.com/tc39/proposal-uniform-interchange-date-parsing applies—it would be a brand new proposal [09:23:55.0243] This seems like it could be done somewhat incrementally: make a list of the cases where some implementation has needed to implement any particular behavior, and write that down [09:24:08.0620] and then say that things not in one of those forms are implementation-defined [09:24:17.0453] and then whenever a new one gets hit, add it to the list [09:29:49.0931] in that case no proposal is necessary, just a sequence of web-reality PRs in (ecma262, test262) pairs [09:37:52.0630] Richard Gibson: Sure, a series of PRs would be fine, but I assume the research into what is commonly supported will mostly need to be front-loaded [10:00:20.0471] to be frank, I don't see this going anywhere unless it's driven by current major implementations, who have pretty much no incentive. A fringe behavior is generally identified as required for web compatibility by observing breakage when it is changed, and some of those will be required in that sense even if they are not uniform across implementations. "Commonly supported" is a different concept but easier to determine, and if the committee establishes that as the criterion (basically encoding Hyrum's Law as a baseline) then what we'll end up with is an expansion of formats that must be accepted (and how to interpret them in ugly cases like "2023-02-30") and no description of what must—or even _may_—be rejected. Which is somewhat better than the current situation in which the same effectively holds but without documentation, although not by enough to motivate the kind of research you describe. but anyway, https://tc39.es/proposal-uniform-interchange-date-parsing/cases.html may be a decent starting point for any aspirational Don Quixote out there [11:37:28.0800] shu: did you see https://github.com/tc39/proposal-iterator-helpers/issues/286#issuecomment-1718129217 ? [11:37:43.0780] i did [11:38:09.0028] i can confirm the killswitch config is rolled out, but something else is wrong that it's not actually disabling the feature [12:09:59.0022] The feature wants to live. [12:10:41.0375] life finds a way 2023-09-14 [17:15:18.0094] I believe my colleagues should have responded to the GH org invites a couple days ago [13:10:14.0720] Two folk from Sony are registered in addition to yourself, Ross. 2023-09-15 [19:05:21.0199] registered, yeah. I'm not sure why the third hasn't been responding to DMs 2023-09-18 [15:15:07.0962] ljharb: 5 minutes for the pattern matching update seems... ambitious [15:19:42.0289] I dunno, I can say "here's a gist you should read" pretty quick [15:36:35.0565] 🙏 as someone whose items are all near the bottom of a full agenda, I am just hoping we make haste and avoid waste wherever we can [15:57:10.0303] It’s not going to be any details, just broad strokes [16:43:22.0226] oh wow we went from a pretty sparse agenda to a really full one [16:43:32.0105] i count 18+ hours [16:43:46.0746] how many working hours do we have? [16:49:38.0377] like 14-15 or so i think? 20 hours - 3 for lunch - 1.5 for coffee breaks - 1 for administrative agenda items 2023-09-19 [18:01:40.0937] > <@shuyuguo:matrix.org> oh wow we went from a pretty sparse agenda to a really full one classic [09:00:08.0545] Why did `promise with resolvers for stage 4 #1453` merge after the deadline to advance? [09:10:38.0260] "must be added (and noted as such) along with links to the supporting materials prior to the deadline, or else delegates may withhold consensus for advancement solely on the basis of missing the deadline." [09:11:23.0710] i.e. you are still allowed to add things if you really want, just that delegates can object to advancement [09:11:35.0316] * i.e. you are still allowed to add things if you really want, just that delegates can object to advancement on the basis of lateness [09:14:20.0277] it is also noted with the emoji indication: `⌛️ late addition for stage advancement and/or schedule prioritization` [09:14:31.0953] * it is also noted with the emoji indication: `⌛️ late addition for stage advancement and/or schedule prioritization` [09:15:26.0836] via Rob on Reflector: We have ~20 hours of content on the agenda and only ~16 hours of capacity. Meaning ~4 hours of content will likely overflow. Please consider if you would like to send a PR to reduce the requested timebox of any of your agenda items. Likewise if you would like to proactively designate your item as low priority (i.e. a candidate for overflow to the next meeting if we don't find time for it), please mark it with a ⬇ emoji. [09:40:52.0570] Rob Palmer: i don't know if you or someone else added the promise withresolvers thing, but i think it's too early for stage 4 just yet [09:41:31.0232] it _just_ shipped and i'd like to wait for it to hit at least beta [09:53:51.0178] peetk: 👀 [13:43:06.0631] oopsie daisy -- will revert agenda item [13:48:30.0988] no need for a PR, just push up a commit [13:48:35.0939] * (btw no need for a PR, just push up a commit) 2023-09-20 [01:06:48.0715] kinda hype for more non-coercion talk tbh [01:06:57.0351] (especially since I missed round one) [09:08:20.0159] rkirsling: If you haven't seen it yet, we have a PR open for what was already decided: https://github.com/tc39/how-we-work/pull/136 [10:31:49.0042] related: https://docs.google.com/presentation/d/e/2PACX-1vSw84uzAT9EWY-xN526UhWpUCzsB8rLQPLfvhavqOf8c-tx6z2DlfrOPpzS61l7JZ9VLohoOUeVSLaa/pub?start=false&loop=false&delayms=3000 [14:04:26.0741] 📢 if you have constraints for this coming plenary, please add them to the agenda md as soon as possible 2023-09-21 [10:09:41.0272] ``` You will not be able to access your workspaces and other resources on HackMD during the times listed below. Maintenance Schedule 00:00 to 01:00 on September 24th (UTC) ``` 2023-09-22 [21:08:04.0796] https://mastodon.social/@hailey@hails.org/111105611822853351 [21:08:17.0526] > How does it work? Turns out oniguruma, the regexp engine ruby uses, supports 'calling' previously defined capture groups with the \g<...> syntax [21:08:19.0675] kind of love this [21:38:45.0957] I brought that to committee but it didn't get stage 1 [21:42:33.0651] Well, it was part of the big regexp features proposal that I had to break down into smaller proposals. I haven't presented it on its own yet because it seemed like it would have a lower likelihood of success, so it hasn't been a priority [21:42:43.0774] regex should not have that feature [21:44:26.0094] It's extremely valuable and let's you compose a lot of small reusable patterns. It's very good for parsing ISO-8601 dates to spec [21:44:42.0143] i mean its certainly cool [21:44:52.0472] but i think any complex enough to warrant it should not be a regex anymore [21:45:03.0702] * but i think anything complex enough to warrant it should not be a regex anymore [21:45:54.0442] It's also present in a lot of engines like Perl, PCRE, Boost.Regex, Oniguruma, and Glib/GRegex [21:46:07.0477] https://rbuckton.github.io/regexp-features/features/subroutines.html [21:46:38.0684] Here's an example of date parsing: ``` (?(DEFINE) (?\d{4}|[+-]\d{5,}) (?0[1-9]|1[0-2]) (?0[1-9]|2[0-9]|3[01]) ) (?(?&Year)-(?&Month)-(?&Day)|(?&Year)(?&Month)(?&Day)) ``` [21:48:38.0496] (that's from Perl, apparently I have the wrong example up for Oniguruma) [21:49:20.0131] ok but like, Temporal.ZonedDateTime.from(s) exists [21:49:42.0611] That's a solution to a singular problem, not the whole domain. [21:51:05.0155] Consider the TypeScript.tmLanguage file used to generate syntax highlighting in many editors. We hacked our own substitution mechanism in to inject a number of reusable regular expressions into the final output file. [21:51:49.0897] (as in, we have named substitutions in the source file, and generate an output `.tmLanguage` file with substitutions applied) [21:52:08.0353] but tree-sitter exists [21:52:44.0672] > <@rbuckton:matrix.org> That's a solution to a singular problem, not the whole domain. my point is not the specific thing, its that in basically every case, a more comprehensive alternative exists, because complex data generally requires complex handling [21:55:26.0725] More comprehensive in some cases is like using a sledgehammer to smash an ant. Sometimes the tools are a lot bigger than what's needed, and bring in a lot of additional overhead. [21:55:52.0122] Regardless, its not the most important feature on my wishlist of RegExp features, which is why its currently on the backburner. [21:56:46.0167] Sometimes the best tool is the one that's at hand. [21:58:17.0419] I also know I'm among the minority that really enjoys regular expressions. [21:59:15.0089] Sometimes you just want to parse your HTML using a RegExp, you know? /s [22:03:42.0257] You can't parse HTML with RegExp. [22:09:43.0682] so sayeth https://stackoverflow.com/a/1732454/632724 [22:57:25.0104] The `
` cannot hold [22:57:44.0490] it is too late [22:58:11.0899] That stackoverflow post has lived rent free in my head for well over a decade. [06:10:19.0031] now that some of us have arrived in Japan for the meeting next week, can we get a Japan matrix room Chris de Almeida Rob Palmer? [08:41:07.0485] Please say if you would like to be in the Japan matrix room and do not see the invite. [08:41:20.0841] I have invited everyone who was registered, I think. [08:42:17.0358] Is this registration for the in people attending in person, correct? [08:44:24.0353] yes - it's only in-person that required pre-registration 2023-09-24 [21:07:51.0512] I was thinking about the old `.{` operator recently, in terms of how it could potentially be used for extraction and injection as an RCU (read/copy, update) mechanism in the shared structs proposal (or possibly as a follow on). I started tinkering with various ideas for the syntax, and while I have something fairly consistent in mind, I came across a wart related to spread and rest assignments in destructuring syntax: ```js a = { ...b }; // spread properties of 'b' ({ ...x } = y); // take the rest of the properties and put them in 'x' ``` One of the ideas I had for `.{` was doing named spread/rest in extraction/injection, in which you would want extraction and injection to be mirrored, and you could either use spread _or_ rest in either operator: ``` b = a.{ x, ...y }; // pick 'x' as 'x', and pick up the rest as 'y' b = a.{ x, y... }; // pick 'x' as 'x', and spread out 'y' a.{ x, ...y } = b; // assign 'x' from 'x', and take up the rest as 'y' a.{ x, y... } = b; // assign 'x' from 'x', and spread out 'y' ``` Which makes me wonder if spread should have been mirrored as `foo...` [21:09:34.0327] * I was thinking about the old `.{` operator recently, in terms of how it could potentially be used for extraction and injection as an RCU (read/copy, update) mechanism in the shared structs proposal (or possibly as a follow on). I started tinkering with various ideas for the syntax, and while I have something fairly consistent in mind, I came across a wart related to spread and rest assignments in destructuring syntax: ```js a = { ...b }; // spread properties of 'b' ({ ...x } = y); // take the rest of the properties and put them in 'x' ``` One of the ideas I had for `.{` was doing named spread/rest in extraction/injection, in which you would want extraction and injection to be mirrored, and you could either use spread _or_ rest in either operator: ``` b = a.{ x, ...y }; // pick 'x' as 'x', and pick up the rest as 'y' b = a.{ x, y... }; // pick 'x' as 'x', and spread out 'y' a.{ x, ...y } = b; // assign 'x' from 'x', and take up the rest as 'y' a.{ x, y... } = b; // assign 'x' from 'x', and spread out 'y' ``` Which makes me wonder if spread should have been written as `foo...` 2023-09-25 [17:46:07.0460] I do not love the thing where the agenda is structurally set up so that proposals are higher priority than larger discussions [17:46:14.0074] seems like it ought to be the other way around [19:02:28.0327] well, backlog is highest priority, so you can always get a time slice for discussions, just every two meetings [19:03:10.0603] also if a discussion should block a proposal, it can always be bumped up (on a case by case basis) [19:06:07.0870] historically, we adopted this prioritization back when we were trying to get out of the pattern of spending all day on some very circular philosophical discussions which should not have blocked proposals [19:06:37.0177] * well, overflow from last meeting is highest priority, so you can always get a time slice for discussions, just every two meetings [19:24:36.0648] if there's a particular discussion that we should prioritize, maybe note that in schedule constraints? [19:25:01.0685] (personally, when I've put discussions on the agenda in the past, I actually wanted them to be deprioritized generally) [19:26:30.0768] > <@rbuckton:matrix.org> I was thinking about the old `.{` operator recently, in terms of how it could potentially be used for extraction and injection as an RCU (read/copy, update) mechanism in the shared structs proposal (or possibly as a follow on). I started tinkering with various ideas for the syntax, and while I have something fairly consistent in mind, I came across a wart related to spread and rest assignments in destructuring syntax: > > ```js > a = { ...b }; // spread properties of 'b' > ({ ...x } = y); // take the rest of the properties and put them in 'x' > ``` > > One of the ideas I had for `.{` was doing named spread/rest in extraction/injection, in which you would want extraction and injection to be mirrored, and you could either use spread _or_ rest in either operator: > > ``` > b = a.{ x, ...y }; // pick 'x' as 'x', and pick up the rest as 'y' > b = a.{ x, y... }; // pick 'x' as 'x', and spread out 'y' > a.{ x, ...y } = b; // assign 'x' from 'x', and take up the rest as 'y' > a.{ x, y... } = b; // assign 'x' from 'x', and spread out 'y' > ``` > > Which makes me wonder if spread should have been written as `foo...` This is definitely interesting, but also makes me a little scared about whether or not people will be able to understand it well [19:27:34.0532] > <@littledan:matrix.org> This is definitely interesting, but also makes me a little scared about whether or not people will be able to understand it well It's less that I would propose the more complex bits initially, but that I wanted to explore the syntax fully to make sure it remained consistent. [19:35:52.0718] > <@littledan:matrix.org> This is definitely interesting, but also makes me a little scared about whether or not people will be able to understand it well * It's less that I would propose the more complex bits initially (if at all), but that I wanted to explore the syntax fully to make sure it remained consistent. [22:10:26.0709] Rob and I are about to do an AV test in a few minutes. If you want to help out, DM me and I will respond with a Zoom link [23:11:36.0485] > <@littledan:matrix.org> if there's a particular discussion that we should prioritize, maybe note that in schedule constraints? well, concretely, I would like to get to the Stop Coercing Things discussion, since it affects the design of all future proposals [23:11:48.0591] And since we started but did not finish the discussion last meeting [23:12:04.0462] I'm fine with deprioritizing my various "withdraw" topics; they can wait until next meeting [23:12:06.0878] But I do not have any related schedule constraints [23:16:18.0333] I think "I want this to happen this meeting rather than a future meeting" is a constraint you're expressing about the schedule... anyway if you don't think this prioritization is a good fit for one section to document the need, maybe you can document it in a new part of the agenda [23:17:31.0622] I want to discuss your topic but ultimately there are going to be a lot of different points of view people have about why their topic should be prioritized; if these are all collected in one place, then it will be easier for the chairs to go and solve as many for as many prioritization inputs as possible. [01:32:43.0366] bakkot: You can always jump to the higher-priority "shorter discussions" section by selecting a 30-minute or less time box [01:33:08.0416] we designed the agenda like this on purpose and I like it how it is [12:38:17.0931] ...I'm reading the Temporal docs, and in the `round()` method they say: > When there is a tie, round away from zero like ceil for positive durations and like floor for negative durations. This is the default, and matches the behaviour of Math.round(). But `Math.round()`, uh, doesn't do that. `Math.round(-1.5)` is -1; it ciels on the half values. [12:39:35.0332] (I was very confused when I read that because I was pretty sure I specified CSS to use ceil semantics on the halves by default, and I did so because that was JS's behavior. And indeed: ) [12:40:14.0701] for the Temporal docs reference, scroll down a bit to get to the rounding modes [12:44:34.0810] waaaaat [12:44:39.0740] I think this is mostly wording issue from my understanding. `Math.round(-1.5)` performs "floor-like" operation in a sense that it rounds to the nearest "bottom" value. It's not taking the sign into account in the explanation here though. [12:45:26.0013] Obviously -2 is "bottom" for -1.5, but it's 1 for "not signed" -1.5 [12:46:13.0527] I guess Tab is saying that the behaviour of `Math.round` corresponds to `halfCeil` and not `halfExpand`? [12:46:23.0260] (to use the rounding mode terminology) [12:50:44.0866] It looks exactly like that. It always rounds towards +Infinity, for both, positives and negatives now [12:55:36.0474] I think Intl.NumberFormat has a default rounding mode of halfExpand too, with this same rationale. I'm not sure which came first, whether Temporal based its default on NumberFormat, or the mistaken belief that Math.round corresponds to halfExpand [13:48:52.0742] Yes, `Math.round()` defaults to `halfCeil` behavior, not `halfExpand` as the Temporal docs state. [13:49:44.0163] I don't think it's a misunderstanding on my reading - the docs are pretty explicit about the behavior. They're just wrong about it being "like `Math.round()`", which might be something that they want to fix. [13:50:12.0222] (Either in the docs, because `halfExpand` is desirable as the default, or in the spec, because `halfCeil` is the actual default behavior in `Math.round()`.) [14:14:47.0169] I didnt mean to say you read it wrong, but rather that maybe person who wrote it used too much of a mental shortcut, which led to a real mistake :) 2023-09-26 [17:23:29.0918] Good morning from Tokyo. Plenary begins in 37 minutes. [17:59:29.0548] We are starting in one minute! [18:13:21.0125] The notes don't have a header for attendee names, org and abbreviation. [18:13:23.0093] is tcq down for anyone else? [18:13:42.0046] yes :( I guess we'll have to go to the google sheets backup? [18:13:42.0240] just now, I think [18:13:42.0633] yes [18:13:42.0863] Yeah, looks down to me. [18:15:25.0074] back on? [18:15:46.0836] LGTM now [18:17:00.0879] Are the task group reports still on for this first section today? [18:17:48.0485] ... we have delegates.txt for that msaboff [18:17:51.0397] jkup: Yes [18:18:10.0700] Would really appreciate having Locale Extensions get onto the agenda in order to surface stakeholders and get a temperature check on the current direction. ( Rob Palmer ryzokuken Chris de Almeida ) [18:18:12.0693] > <@michaelficarra:matrix.org> ... we have delegates.txt for that msaboff Yeah, I was happy to see this section missing, since we have the sign-in sheets (plural!) in addition to the abbreviations list [18:18:33.0497] yes let's not continue this practice for no reason [18:18:37.0879] ah, perhaps it just needed to be made clear that we no longer need it [18:18:43.0309] I was wondering too [18:18:46.0225] > <@rkirsling:matrix.org> ah, perhaps it just needed to be made clear that we no longer need it was the omission on purpose? [18:19:01.0352] (I don't know either way) [18:19:09.0666] oh sorry, I was inferring that it was [18:19:16.0376] I have no idea [18:19:34.0072] msaboff should be good to go now [18:20:04.0847] motion to delete it again [18:20:12.0001] So to confirm, TCQ appears to be working. [18:21:09.0140] > <@usharma:igalia.com> msaboff should be good to go now Now we just need everyone else to add their names. [18:21:31.0451] > <@sffc:mozilla.org> Would really appreciate having Locale Extensions get onto the agenda in order to surface stakeholders and get a temperature check on the current direction. ( Rob Palmer ryzokuken Chris de Almeida ) Is this on the agenda? If not, please PR it. [18:22:02.0460] > <@robpalme:matrix.org> Is this on the agenda? If not, please PR it. It's in the overflow. [18:23:40.0002] we'll try to free up as much time as we can as we go and try to bring items from the overflow to discussion [18:23:59.0808] "pdf has highest downloads" is meaningless; the editor's draft on github does not have statistics [18:24:13.0710] i am laughing on the inside [18:29:58.0799] i'm pretty sure github pages has some analytics [18:31:35.0951] oh nvm i'm thinking of repo analytics [18:32:03.0705] it's nice to have the abbreviation list in the same document, i think [18:32:08.0342] * re notes, it's nice to have the abbreviation list in the same document, i think [18:33:03.0468] at some point all the time spent talking about the PDF is going to successfully annoy me enough to do the automation just so we can stop talking about it [18:33:06.0784] which was the goal I guess [18:33:20.0053] ljharb: we have tabs; when I am taking notes, I just keep delegates.txt open in a tab [18:33:36.0204] true, maybe just a link to the list for easy tab-opening would be better then [18:33:37.0146] the PDF is a fair bit of work and it is hard to motivate because I don't use the PDF at all [18:33:45.0512] which is why we keep trying to get ECMA to hire people instead [18:34:27.0534] i think, in general, practitioners and implementers that engage with the PDFs are rarely doing so on purpose for checking the behavior of a particular yearly version, and because they missed that there is a draft they should be using [18:34:52.0498] i never use the pdf; even when checking a past yearly version i use the HTML form [18:34:54.0291] * i never use the pdf; even when checking a past yearly version i use the HTML version [18:34:55.0232] * i never use the pdf; even when checking a past yearly version i use the HTML versions [18:34:57.0599] so it's primarily for archival purposes, which is mainly consumed by ecma [18:35:23.0494] afaik the concerns aren't about archival tho, they're about readability when printed. webpages can be easily archived as PDFs without any additional changes. [18:35:34.0807] * afaik the concerns aren't about archival tho, they're about readability when printed. webpages can be easily archived as PDFs without any additional changes. do many people even own a printer anymore? [18:35:41.0214] fair, i meant archival-as-printed-physical-artifact [18:35:43.0258] I agree that practitioners should typically use the editor's draft, but I want to note that the market for "archival purposes" is broader than Ecma and that's a good thing. This is shared with ISO, put in libraries, etc. [18:36:03.0676] there's been a lot of stuff lost in the past and it's good to have printed artifacts to avoid that [18:36:48.0402] anyway I think everyone agrees the editors are already doing a lot and no need for this to be all on them [18:36:52.0376] the new font is quite good [18:37:02.0019] _except_ the # [18:37:04.0141] # so weird [18:37:06.0366] oh god [18:37:17.0609] lol [18:37:21.0371] i can't just type the sentence "# so weird", there's Markdown support in Element? [18:37:38.0431] `#` so weird [18:37:48.0229] did we check if there is a font variant for `#` in the font we're using? [18:38:23.0488] is it just the bold `#`? [18:38:37.0522] that's what we thought at first, i think we found out it was the monospace # [18:39:00.0288] https://github.com/tc39/ecmarkup/issues/556 [18:39:09.0165] yes, it is all monospace variants [18:39:16.0939] https://github.com/IBM/plex/issues/401#issuecomment-1727079001 [18:39:49.0778] > > An update for Plex Mono is scheduled for later this year. It will include a reworked version of the # symbol as stylistic alternate. [18:39:53.0391] nice [18:39:57.0015] * > An update for Plex Mono is scheduled for later this year. It will include a reworked version of the # symbol as stylistic alternate. [18:40:12.0413] watch the stylistic alternate remove the horizontal overlapping segments too [18:40:32.0895] https://tc39.es/ecma262/ is somehow slow to the point of unusable for me [18:40:42.0626] slow how? [18:40:46.0754] like, I'm scrolling and it's just blank [18:40:51.0631] rkirsling: yes it is a very big document [18:40:52.0445] try Firefox [18:40:57.0025] ^ [18:40:59.0125] chrome always struggles on long pages [18:41:11.0273] its super responsive for me in firefox, and i'm not even using gpu acceleration [18:41:14.0179] also try the multipage document [18:41:14.0865] this is Safari [18:41:25.0337] but yeah multipage would help [18:41:31.0602] https://tc39.es/ecma262/multipage/ [18:41:32.0392] `m` to switch! [18:41:49.0757] wow the single page is very good in chrome too [18:41:57.0658] like maybe as good as firefox [18:42:36.0378] firefox is definitely more responsive and loads in maybe 1/10th the time [18:42:50.0654] safari takes like 15 seconds to even show the page [18:43:09.0559] * safari takes like 15 seconds to even show the top of the page [18:43:27.0923] oof [18:43:36.0960] ecma404 is my favorite specification [18:43:37.0646] one day chip will surprise us [18:43:45.0418] someday I hope 262 achieves that level of stability [18:43:57.0125] JS is much more like a shark than JSON [18:44:01.0666] i do not hope for that [18:44:11.0483] > <@bakkot:matrix.org> someday I hope 262 achieves that level of stability there are two ways to achieve this [18:44:19.0889] wasm! [18:44:43.0855] > <@shuyuguo:matrix.org> JS is much more like a shark than JSON ... in that it is functionally immortal and will kill you if you show weakness? [18:45:03.0495] something about jumping, probably [18:45:08.0176] no, that if it stops swimming it dies [18:45:20.0341] it's an annie hall reference, i don't actually know if it's true of actual sharks [18:45:24.0196] Safari took ~5 seconds for me and this is a 2019 Intel MBP. [18:45:49.0482] it is true of most shark species [18:46:02.0722] there are a few that can pump water through their gills instead of having to swim [18:46:26.0252] > <@msaboff:matrix.org> Safari took ~5 seconds for me and this is a 2019 Intel MBP. weird i was on m2, maybe i need to use intel [18:47:00.0421] i'd be curious to see how other committees handle security issues [18:48:41.0222] I am curious what vulnerability can happen in ECMAScript since it does not have too much IO [18:50:00.0974] i think the embedded devices folks have added a bunch [18:50:30.0354] actually i guess they're a separate TC now [18:50:31.0674] that's an engine specific thing right? just like v8 bug is v8 only [18:54:13.0340] > <@ljharb:matrix.org> true, maybe just a link to the list for easy tab-opening would be better then there's a "your existing abbreviations" link to delgates.txt in the green box right below the date [18:54:37.0629] > <@jackworks:matrix.org> that's an engine specific thing right? just like v8 bug is v8 only that's a good point, I have usually thought of security bugs as engine bugs [18:54:50.0583] but my knowledge of security is very weak [18:58:05.0922] syg: msaboff To be clear, I'm not saying everything needs to be discussed in TC39 plenary, just that Spectre represented an interesting case to review, as it was a vulnerability at the design level rather than in a particular implementation. [18:59:20.0822] it could have been constructive to discuss SAB at a higher level though idk how different the outcome would have been in practice... will be interesting to see what happens in the future i guess, whatever the next intel vulnerability is. [18:59:45.0073] these are all interesting _properties_ but are not _vulnerabilities_ in my book [19:00:06.0984] vulnerability "potentials"? [19:00:07.0917] in that its about the hardware you're running js on, not js itself? [19:00:13.0539] i don't have any reservations with saying TG3 ought to discuss security properties, and ones that get raised [19:01:20.0985] > <@littledan:matrix.org> syg: msaboff To be clear, I'm not saying everything needs to be discussed in TC39 plenary, just that Spectre represented an interesting case to review, as it was a vulnerability at the design level rather than in a particular implementation. Spectre and Meltdown are issues at the CPU level and not JS design. [19:02:00.0359] sure, but we worsened them through exposure from TC39. Anyway, yeah, there probably wasn't any meaningful discussion to have here at that point, and I don't think you needed to disclose more [19:02:01.0034] i think its a bit ambiguous. ultimately the design of js is guided by how the hardware we run it on works [19:02:02.0842] I am fine with this but would want the disclosure text to make it really clear that we do not expect "vulnerabilities in the language" to really be a thing [19:02:07.0641] and saying you probably want something else [19:06:03.0218] It just seems a little weird to me that an open standards body would discuss vulnerabilities. The CVE and other similar processes provide a means for those with issues to address them before bad actors are generally aware of the vulnerability. [19:06:31.0307] sorry, I probably shouldn't've said anything. I don't feel like you needed to disclose Spectre in any kind of different way. [19:06:41.0495] > <@msaboff:matrix.org> It just seems a little weird to me that an open standards body would discuss vulnerabilities. The CVE and other similar processes provide a means for those with issues to address them before bad actors are generally aware of the vulnerability. yes, i have similar vague reservations [19:06:50.0380] but i am not very hooked into the CVE process either [19:07:17.0428] i am interested to see how it goes at least [19:07:53.0109] vulnerabilities at some conceptual level can exist because there's a mismatch between a thing (an implementation) and a source of truth (a spec), and people depend on properties of the source of truth, making it an vulnerability [19:08:10.0942] but i don't know what that means if it is "a vulnerability in the spec" because it _is_ the source of truth [19:08:34.0173] i am very uncomfortable if the mismatch is in fact with unsaid properties that _could_ be depended upon but we have not otherwise explicitly committed to keeping [19:09:13.0516] shu: surely you can imagine that there are assumed invariants about the language that may not actually hold because of the way we have specified it (which then may or may not be reflected in an implementation) [19:09:47.0491] Michael Ficarra: right. i can also imagine that we don't actually unanimously agree on those assumed invariants [19:10:01.0719] of course, and that is work to be done later [19:10:04.0233] > <@shuyuguo:matrix.org> i am very uncomfortable if the mismatch is in fact with unsaid properties that _could_ be depended upon but we have not otherwise explicitly committed to keeping Yeah, this is the standing disagreement about what constitutes our security model that I was describing. But I thought we all agreed that SAB had a "vulnerability" at some level, which was addressed by various implementations at non-JS levels [19:10:33.0521] I don't think of SAB having a vulnerability? [19:10:42.0596] "the language lets you get a high-res timer" is not a vulnerability [19:10:50.0472] Not really an issue with the JS spec, but something like the Billion Laughs Attack in XML and YAML could be considered as a spec "vulnerability". [19:10:54.0634] "the hardware leaks memory if you have a high-res timer" is a vulnerability [19:11:15.0592] well, it was part of the exploit, sorry I guess I'm using security words wrong [19:13:48.0303] the editors had already raised concerns about it being a note [19:14:39.0518] *262 editors [19:14:59.0174] sorry, 262 editors [19:15:27.0890] yes this is what I was saying [19:15:30.0501] (to Mark) [19:15:42.0206] ... isn't it normative already? [19:15:46.0374] it says it's normative on the agenda [19:15:55.0387] and in the PR title [19:19:40.0374] https://github.com/tc39/ecma402/pull/831 [19:19:56.0660] > <@bakkot:matrix.org> ... isn't it normative already? it's normative [19:20:34.0915] I guess the consensus is to do things without the non-normative label [19:21:26.0173] everything inside notes is non-normative; everything outside notes is normative [19:23:26.0455] some things outside notes are also non-normative, tbf [19:23:31.0916] * some things outside notes are also non-normative [19:33:52.0954] I feel like I'm crazy, this is already what the PR does [19:34:09.0907] `'axc'.replace(/x/, '$01') === 'a$01c'` [19:34:46.0609] > <@michaelficarra:matrix.org> everything inside notes is non-normative; everything outside notes is normative in that case we could move the text out of the notes [19:35:48.0685] > <@michaelficarra:matrix.org> I feel like I'm crazy, this is already what the PR does it's certainly possible that it's an issue in my impl, but it's practically 1:1 with the spec text ¯\_(ツ)_/¯ [19:35:51.0641] > <@michaelficarra:matrix.org> I feel like I'm crazy, this is already what the PR does * it's certainly possible that it's an issue in my impl, but it's practically 1:1 with the spec text ¯\\\_(ツ)\_/¯ [19:36:11.0584] > <@bakkot:matrix.org> `'axc'.replace(/x/, '$01') === 'a$01c'` `'axc'.replace(/(x)/, '$01')` tho [19:36:11.0756] I keep re-reading it and I don't see how you could have any other behaviour [19:36:35.0985] ljharb: link your impl? [19:36:45.0270] still local since i just wrote it 8 minutes ago [19:36:56.0550] i'll share a link if a bit of debugging doesn't reveal the problem on either side [19:36:59.0845] I'm gonna take Occam's razor here [19:37:30.0201] Does anyone know how long implementations had this replace behavior? [19:37:35.0132] ? https://gc.gy/163400847.png [19:38:30.0301] right, exactly - that shows that `$1` and `$01` both hit the first capture group [19:38:52.0859] `'axc'.replace(/(x)/, '•$01•') === 'a•x•c'` maybe makes that easier to see [19:39:14.0059] the difference is if you have, say, 12 captures in the regex, and you use `$012` vs `$12`, the former will grab capture 1, followed by a 2; the latter will grab capture 12 [19:39:39.0036] * the difference is if you have, say, 12 captures in the regex, and you use `$012` vs `$12`, the former will grab capture 1, followed by a 2; the latter will grab capture 12. if you have < 11 captures in the regex, `$0\d` and `$\d` are equivalent [19:40:40.0297] > <@usharma:igalia.com> in that case we could move the text out of the notes Yes, this is what I was proposing. [19:42:27.0059] if we have time which we cannot otherwise use, I am happy to take any >10m slot to get through as much of "stop coercing things" as possible [19:42:44.0720] though IIRC someone wanted to be there for that, which makes it harder to do impromptu [19:43:34.0049] > <@bakkot:matrix.org> if we have time which we cannot otherwise use, I am happy to take any >10m slot to get through as much of "stop coercing things" as possible we're trying to make enough time to bring it forward, but your flexibility is very much appreciated 😄 [19:47:42.0894] Michael Ficarra: occam wins again, i fixed it. either way the test262 PR needs coverage for this :-) [19:48:09.0082] 🎉 [19:52:42.0656] Ladybird, Serenity is the OS [19:53:18.0466] it uh [19:53:27.0375] might be too cold in here, by a bit [19:53:27.0778] > <@bakkot:matrix.org> if we have time which we cannot otherwise use, I am happy to take any >10m slot to get through as much of "stop coercing things" as possible I'd like to delay my my three "withdraw" topics until the end of the agenda (likely pushed to another meeting) [19:54:34.0525] https://chromestatus.com/feature/5073244152922112 [19:54:36.0869] ljharb: https://bugzilla.mozilla.org/show_bug.cgi?id=1841113 [19:54:49.0810] for TG2 proposals, we do this kind of tracking centrally (in a wiki in this case). Would it be useful to do this as part of tc39/proposals or something like that? [19:58:43.0772] > <@msaboff:matrix.org> Does anyone know how long implementations had this replace behavior? This is the relevant v8 code I believe https://github.com/v8/v8/blob/main/src/runtime/runtime-regexp.cc#L208-L251 [20:05:27.0153] > <@apaprocki:matrix.org> This is the relevant v8 code I believe https://github.com/v8/v8/blob/main/src/runtime/runtime-regexp.cc#L208-L251 The second digit thing in there appears to be from when replace was first implemented in C++ in 2009: https://github.com/v8/v8/commit/e2af4529c3a5a31eaf21240ffc6fce42f0af2d3b#diff-df9cd537d3ef3350ae6d69fd7067704522b83ff80efdcfd53d2e30870ab977d2R1457-R1465 [20:26:02.0671] > <@apaprocki:matrix.org> The second digit thing in there appears to be from when replace was first implemented in C++ in 2009: https://github.com/v8/v8/commit/e2af4529c3a5a31eaf21240ffc6fce42f0af2d3b#diff-df9cd537d3ef3350ae6d69fd7067704522b83ff80efdcfd53d2e30870ab977d2R1457-R1465 Seems like a lot of water under the bridge. [20:27:52.0754] I feel it's too cold in the meeting room 🥶 [20:29:29.0653] > <@bakkot:matrix.org> though IIRC someone wanted to be there for that, which makes it harder to do impromptu If you mean me, it was a "best effort" preference to attend; feel free to go ahead if there's a slot [21:03:57.0194] > <@usharma:igalia.com> for TG2 proposals, we do this kind of tracking centrally (in a wiki in this case). Would it be useful to do this as part of tc39/proposals or something like that? we could, but we already track this per proposal - the challenge i think would be the same, people remembering/knowing to update one end from the other [21:04:33.0827] sure, I'm not sure if centralization like this would make it easier to update/provide information [21:04:51.0028] but it'd certainly make it easier to find it, although out-of-context [21:12:54.0973] https://github.com/tc39/how-we-work/blob/main/terminology.md#override-mistake :) [21:14:09.0755] whoa TIL `> [!NOTE]` [21:16:08.0470] it's pretty new, and got a lot of pushback in the first iteration; i think the second iteration addresses most of that tho [21:17:55.0404] FYI https://docs.transcend.io/docs/consent/reference/privacy-and-security#read-before-using-tamper-resistance [21:18:16.0613] Transcend has been great about trying to get their customers upgraded [21:18:19.0590] "Note that an interaction between Chrome 117, Transcend Consent's Tamper Resistance mode, and versions of regenerator-runtime (a common JavaScript library) older than v0.13.8 can cause errors and could negatively impact your website. To resolve these errors please update airgap.js to version 8.11.11 or higher to automatically disable Tamper Resistance mode. If you're using an earlier version of airgap.js and are unable to update, you can also manually disable Tamper Resistance by setting the the data-tamper-resist="off" attribute on your airgap.js script." [21:18:39.0787] So they did change the default to now be off [21:19:52.0210] Yeah SES does also freezing... [21:19:55.0487] hmm, they didn't make a working tamper-resistant mode? [21:20:33.0525] > <@christianulbrich:matrix.org> Yeah SES does also freezing... they freeze in the correct way. ses grabs the Iterator from [].values() not global name [21:21:02.0577] > <@littledan:matrix.org> hmm, they didn't make a working tamper-resistant mode? I think they were trying to get a fix out ASAP [21:21:23.0246] I assume upgrading regenerator-runtime also "fixes" it? [21:21:31.0055] correct [21:21:55.0259] > <@jackworks:matrix.org> they freeze in the correct way. ses grabs the Iterator from [].values() not global name Good to know, there is a correct way. I did not mean it as criticism, but as a response to nicolo-ribaudo asking, whether some other members are using this strategy... [21:21:56.0078] > <@apaprocki:matrix.org> I assume upgrading regenerator-runtime also "fixes" it? it will be much harder. many npm libraries bundles regenerator-runtime [21:21:56.0243] any version after 0.13.8 (inclusive) [21:22:34.0263] > <@christianulbrich:matrix.org> Good to know, there is a correct way. I did not mean it as criticism, but as a response to nicolo-ribaudo asking, whether some other members are using this strategy... Thanks for clarifying! [21:29:48.0102] does pursing a "holistic approach" necessarily preclude the specific pr for this proposal [21:30:24.0235] like say we take some other approach like "freeze but correctly and also without a performance hit somehow", that doesn't fix the existing code that wasn't able to be updated [21:31:09.0411] Could someone provide a link to a summary of what "the override mistake" means? [21:31:23.0000] https://github.com/tc39/how-we-work/blob/main/terminology.md#override-mistake [21:31:30.0916] thx! [21:38:45.0856] Have we considered adding a new descriptor property that, in combination with `[[Writable]]: false` explicitly opts in to a behavior of "if the prototype property is `[[Writable]]: false`, then define the property on the original object being assigned to"? Then workarounds for this become slightly less one-off? I'm not sure if that helps, to be honest. [21:39:26.0316] [[Writable]]: `a secret 3rd thing` [21:39:39.0961] you mean `null` [21:40:22.0459] is it acceptable to the object inheriting though? [21:40:33.0532] or is this something in the domain of the person doing the setting [21:40:40.0425] `[[Shadowable]]: true` or something to that effect [21:41:01.0261] i feel like its something the person doing the setting wants control over, not the object, but idk [21:41:09.0613] maybe nice weird and niche enough that it doesn't matter [21:41:14.0248] * maybe its weird and niche enough that it doesn't matter [21:41:31.0624] if you're doing the setting and want control you'd use Object.defineProperty [21:41:42.0290] > <@rbuckton:matrix.org> `[[Shadowable]]: true` or something to that effect then the question becomes how you add it. if you change how O.freeze works, you're basically fix the whole override mistake [21:42:35.0524] > <@jackworks:matrix.org> then the question becomes how you add it. if you change how O.freeze works, you're basically fix the whole override mistake I would consider my suggestion a worst-case scenario if its not possible to change `Object.freeze` or Set semantics themselves. [21:42:59.0721] but old code is using O.freeze so... [21:43:52.0376] Yes, it would be something you would have to opt-in to, and something like `Iterator.prototype.constructor` would opt-in internally. [21:46:19.0274] * Yes, it would be something you would have to opt-in to, and something like `Iterator.prototype.constructor` would opt-in by default. [22:16:40.0540] thats quite interesting [22:16:50.0891] the done true thing [22:16:59.0011] i think i prefer rust's size hints [22:17:08.0240] > <@rbuckton:matrix.org> Yes, it would be something you would have to opt-in to, and something like `Iterator.prototype.constructor` would opt-in by default. if it's web compat to opt in anything by default, then wouldn't it be web compat to do it everywhere? [22:26:56.0850] my very intelligent comment: I don't like when it runs out of memory either [22:27:13.0525] always a fan of not running out of memory [22:27:47.0337] bakkot: the done:true size hinting you mentioned, that's not *required* for correct behavior right? [22:28:29.0049] this is the internet, can't we just download more memory [22:28:36.0324] oops wrong channel 😛 [22:28:53.0241] you wouldn't download a ram [22:31:26.0552] could someone remind me why do is no longer blocking? [22:31:34.0250] * could someone remind me why do is no longer blocking for throw expressions? [22:32:48.0401] as i recall, throw expressions were considered independently useful even if do expression also existed? [22:33:17.0938] ah, okay, not some technical thing that was resolved, just that we decided it'd be fine to have both [22:33:54.0520] we are doing all this syntax just because of comma operators? [22:33:57.0793] does anyone use comma operators? [22:34:07.0656] minifiers and rebels [22:34:43.0175] Does this mean, that `function(a, b = throw c, c = throw d)` would be _legal_? [22:34:54.0175] No, you have to wrap the first throw [22:34:59.0507] * No, you have to wrap the first throw with this restriction [22:35:03.0339] wait what [22:35:09.0103] oh man yeah we do need to fix this [22:35:12.0018] lol [22:35:13.0748] because `c, c = throw d` is a potentially valid expression [22:35:33.0191] you know what i agree with richard [22:35:38.0637] lets take precedence from import and require parens [22:35:39.0713] so u need to write c = (throw d) ? [22:35:45.0246] so it's either `function(a, b = (throw c), c = throw d)` or `function(a, b = throw (c, c = throw d))` [22:36:01.0671] > <@devsnek:matrix.org> lets take precedence from import and require parens mainly from `**` [22:36:16.0860] _in other words_, how could I write a function, that _throws_ if multiple arguments are not given by using `throw` as a _default value_? Thx. ljharb ... [22:36:23.0471] what about `let x = throw c, d = 1` ? [22:36:36.0806] same, you'd need `let x = (throw c), d = 1` [22:36:53.0230] > <@christianulbrich:matrix.org> _in other words_, how could I write a function, that _throws_ if multiple arguments are not given by using `throw` as a _default value_? Thx. ljharb ... wrap each defaulted throw expression in parens, except for the last one [22:37:00.0713] Seems too strict? [22:37:10.0440] i mean who's going to write that code tho [22:37:22.0948] `let x = throw c, d = 1` will throw and never define `d` in either interpretation [22:37:39.0504] ljharb: But, would `function(a, (b = throw c), (c = throw d))` also work? [22:37:45.0760] > <@christianulbrich:matrix.org> ljharb: But, would `function(a, (b = throw c), (c = throw d))` also work? yes [22:37:51.0385] oh no wait [22:38:00.0962] `a, b = (throw c), c = (throw d)` [22:38:07.0371] * `a, b = (throw c), c = (throw d)` - parens aren't around the `=` part. [22:38:14.0802] what on earth [22:38:16.0809] so either we require these parens or we totally change how the comma operator works [22:38:22.0852] Okay, that would be fine with me, I would not want to explain to devs, that the syntax _depends_ on the position of something... [22:38:36.0400] it's possible in destructing to mean required. `let [x, y = throw new Error(), z] = ...` [22:38:41.0587] > <@christianulbrich:matrix.org> Okay, that would be fine with me, I would not want to explain to devs, that the syntax _depends_ on the position of something... no, just the necessity of the syntax. i'm sure there'd be a linter that either forbids or requires the parens in the terminal case [22:38:42.0577] * Okay, that would be fine with me, I would not want to explain to devs, that the syntax _depends_ on the **position** of something... [22:39:09.0540] > <@haxjs:matrix.org> it's possible in destructing to mean required. `let [x, y = throw new Error(), z] = ...` sure, but that's sufficiently rare that wrapping the throw new Error() in parens isn't that big a deal [22:39:12.0091] > <@ljharb:matrix.org> no, just the necessity of the syntax. i'm sure there'd be a linter that either forbids or requires the parens in the terminal case Fair enough! [22:40:11.0496] I agree it's not a big deal, just ask whether we can loose the restriction... [22:40:35.0578] > <@haxjs:matrix.org> I agree it's not a big deal, just ask whether we can loose the restriction... We can if we agree that `x = throw a, b` being different from `throw a, b` is ok [22:40:51.0938] (the first one throws `a`, the second one `b`) [22:41:15.0256] TCQ is indeed frozen. [22:41:17.0044] Because in `let x = 1, y = 2` it already not follow comma expression. [22:41:47.0239] yeah true, that's not the comma operator so maybe that one would be fine? [22:42:02.0595] > <@ljharb:matrix.org> yeah true, that's not the comma operator so maybe that one would be fine? yeah thats what I ask [22:42:10.0198] I'd like to reply as well. [22:42:11.0795] i still don't get why we're talking about comma operators in the context of human understandability [22:42:30.0941] seems like garbage in garbage out [22:42:33.0851] it's back [22:44:19.0342] can whoever was having TCQ problems check again? [22:44:37.0113] without `Promise.withStaticResolvers()` we need: `let resolve, promise = new Promise(res => resolve = red)` ... :) [22:44:43.0642] Temperature check? [22:45:02.0099] > <@haxjs:matrix.org> yeah thats what I ask could someone ask this? I don't have mic today... [22:46:17.0197] Could it work to follow the pattern of `import` for `throw`. Treat it like a function call - require parentheses like `throw(thingTothrow)` - does that help anything? [22:46:54.0784] > <@bradfordcsmith:matrix.org> Could it work to follow the pattern of `import` for `throw`. Treat it like a function call - require parentheses like `throw(thingTothrow)` - does that help anything? no. [22:46:55.0991] oof, `import()` *is* like a function call, and throwing isn't, that doesn't seem like an ideal workaround to me [22:47:20.0022] because `throw(x), y` also a valid statement [22:47:27.0601] > <@ljharb:matrix.org> oof, `import()` *is* like a function call, and throwing isn't, that doesn't seem like an ideal workaround to me careful you will upset the call/cc people [22:47:36.0786] (i am the call/cc people) [22:47:57.0705] /me waves to the fellow schmers [22:48:07.0392] /me * waves to the fellow schemers [22:48:34.0537] what happened to nicolo's queue item? [22:48:41.0522] > <@ljharb:matrix.org> what happened to nicolo's queue item? I was wrong [22:48:44.0512] ah k [22:48:55.0302] It would be throw using an early error as kevin describes [22:49:01.0697] But not with the current lookahead grammar [22:50:21.0348] isn't `await`'s super low precedence relevant here? [22:50:27.0308] like, `await 1, 2` will never await 2, only 1 [22:50:52.0034] so if `throw`'s precedence is super low also (above or below await's) then would the problem just go away? (because people trying to USE the comma operator would be forced to paren-wrap, and who cares about that) [22:51:07.0840] ljharb: that's high, no tlow [22:51:13.0925] i appreciate that we have the opportunity to have 3 different precedence keyword unary operators [22:51:27.0126] ljharb: the problem is that _statement position_ throw is low precedence [22:51:31.0698] snek: blame allen :-( [22:51:38.0344] so `throw 1, 2` already means "throw 2" [22:51:47.0835] One question is why choose follow `await` not `yield` [22:52:02.0157] which direction is "high" precedence will _never_ not be confusing [22:52:38.0784] things with higher precedence evaluate first [22:52:41.0750] sigh, comma operator's so gross [22:52:44.0000] rkirsling: I think it's person to person, like whether you have left/right and west/east ingrained [22:52:44.0091] simple rule [22:52:57.0983] > <@ljharb:matrix.org> sigh, comma operator's so gross yeah, really want to remove it though impossible [22:53:15.0513] > <@rkirsling:matrix.org> which direction is "high" precedence will _never_ not be confusing yeah, this is a confusing-in-the-common case vs in the uncommon case issue. (And throw not being an expression is already being confusing in the common case) [22:55:39.0071] if we force you to write parentheses in the ambiguous case then no reader will ever have to be confused [22:55:44.0959] so that seems like the best outcome [22:55:58.0843] writers occasionally getting a message like "you gotta use parens here" seems like the least evil [22:56:36.0657] ``` UnaryExpression : throw Expression ``` Can somebody remind me why this is not doable? [22:57:48.0817] > <@nicolo-ribaudo:matrix.org> ``` > UnaryExpression : > throw Expression > ``` > Can somebody remind me why this is not doable? I believe it's doable, just introduce some inconsistence and refactor harzard when switch from throw exp/statement [22:58:20.0483] > <@haxjs:matrix.org> I believe it's doable, just introduce some inconsistence and refactor harzard when switch from throw exp/statement Isn't it the way to remove all the refactoring hazards between expressions and statements? [22:59:00.0780] nicolo-ribaudo: Maybe I misunderstand ? [22:59:44.0577] Throw statements are `throw Expression`, and I'm asking if throw expressions can be the same but with a high precedence on the left side. [23:00:43.0341] UnaryExpression precedence on the left, Expression precedence on the right [23:00:59.0044] I am not sure that `function f(x = throw a, y){}` throwing `y` is actually a good outcome either [23:01:26.0144] > <@bakkot:matrix.org> I am not sure that `function f(x = throw a, y){}` throwing `y` is actually a good outcome either Oh right I don't want tht [23:02:46.0833] I'm beginning to think the only option is to move `throw` to _Expression_ and just always require parenthesis. Every other option is blocked. [23:03:56.0898] Actually, maybe it isn't? We do some grammar tricks with _UpdateExpression_ and could do something similar [23:04:33.0646] I'll have to think on it. [23:06:06.0175] i'n happy as long as we aren't making things weirder to make comma op more readable [23:07:36.0364] I don't think a grammar-only solution is feasible, as it would also trigger ASI. [23:11:35.0585] If I cannot use an Early Error (per waldemar), and we cannot use _UnaryExpression_ without banning trailing infix punctuators (per bakkot), I do not see another solution aside from always requiring parens. I'm open to other suggestions, though. [23:17:29.0674] > <@devsnek:matrix.org> i'n happy as long as we aren't making things weirder to make comma op more readable to be really clear, my goal is not to make the comma operator more readable. My goal is to ensure that people who have encountered the comma operator previously can read regular code which uses `throw`, including code which does not use the comma operator. [23:17:32.0335] > <@rbuckton:matrix.org> If I cannot use an Early Error (per waldemar), and we cannot use _UnaryExpression_ without banning trailing infix punctuators (per bakkot), I do not see another solution aside from always requiring parens. I'm open to other suggestions, though. I agree with your analysis, but I think it's our job as a committee to make this kind of tradeoff [23:17:56.0941] there are four possibilities at play, and *all* violate one or other goal [23:18:07.0483] waldemar: We use an Early Error to ban optional chain followed by a template literal specifically to avoid ASI. I'm not sure why we wouldn't be able to do the same in this case? [23:18:12.0412] (the fourth being, don't advance this proposal) [23:19:44.0428] Yes, it might require a number of SS rules, but we have precedence within the specification. [23:21:11.0166] > <@rbuckton:matrix.org> I don't think a grammar-only solution is feasible, as it would also trigger ASI. Can we extend the ASI section to say that it does not apply there? 🤷 [23:21:37.0304] I also suggested that, but waldemar seemed against that as well. [23:23:02.0542] > <@nicolo-ribaudo:matrix.org> ``` > UnaryExpression : > throw Expression > ``` > Can somebody remind me why this is not doable? the other problem with this is that it makes the grammar ambiguous, in e.g. `x && throw a || b`. right now we ensure the grammar is unambiguous everywhere except the annex B regexp grammar. [23:23:16.0094] I could add a grammar to `throw` expressions that consumes all of the infix operators and the expressions that follow, and then report an early error in static semantics. [23:25:12.0151] that would still make the grammar ambiguous if it was at Unary precedence [23:25:29.0899] and if it as AssignmentExpression precedence then you can't write `a ?? throw b` [23:25:33.0219] * and if it at AssignmentExpression precedence then you can't write `a ?? throw b` [23:26:17.0105] (like you can't do `a || yield b`) [23:26:22.0742] * (like you can't do `a ?? yield b`) [23:26:30.0044] oh my [23:26:59.0433] Or just static semantics rules to each of the infix operators, like: > ``` > LogicalANDExpression : > LogicalANDExpression `&&` BitwiseOrExpressions > ``` > - It is a Syntax Error if LogicalANDExpression is ThrowExpression or something to that effect. [23:27:00.0896] this is the first real use of boxed primitives i've seen i think [23:27:29.0380] we should not encourage boxed primitives [23:27:55.0664] yeah i'm not sure how i feel about it [23:28:05.0102] > <@rbuckton:matrix.org> Or just static semantics rules to each of the infix operators, like: > > ``` > > LogicalANDExpression : > > LogicalANDExpression `&&` BitwiseOrExpressions > > ``` > > - It is a Syntax Error if LogicalANDExpression is ThrowExpression > or something to that effect. that was my suggestion in the thread but waldemar doesn't like having a bunch of early errors [23:28:14.0719] frankly I do not understand the concern about having a bunch of early errors [23:28:27.0979] errors are best encountered early [23:28:37.0714] > <@bakkot:matrix.org> frankly I do not understand the concern about having a bunch of early errors Neither do I, especially since we do the same thing for _OptionalChain_ [23:28:59.0711] > <@bakkot:matrix.org> (like you can't do `a ?? yield b`) oh, it's my first time to know it's a syntax error ☹️ [23:35:28.0585] > <@bakkot:matrix.org> that was my suggestion in the thread but waldemar doesn't like having a bunch of early errors We override ASI via EE for OptionalChain, and we disallow expressions of certain production in `delete`, so we have precedence for both parts of this within the spec as well. [23:39:46.0290] in tdz michael said he like the "force you to always use parentheses" option [23:40:22.0303] Including cases like `a ?? (throw b)`? [23:40:30.0681] Michael Ficarra: ^ ? [23:40:34.0538] not only do I like it, I independently discovered it and thought it was good [23:40:43.0650] * Including cases like `a ?? (throw b);`? [23:40:49.0513] If we did that and also made the RHS be a UnaryExpression, then it would be kind of the intersection subset which everyone can live with [23:40:56.0518] no new early errors, no ambiguity [23:41:02.0968] 😁 [23:41:04.0642] I mean `?? throw x` really seems like _the_ core case though [23:41:12.0633] and we could, in the future, relax the restriction, if people relax their concerns [23:41:15.0190] I'm not a huge fan of requiring the parenthesis since they wouldn't other be necessary for most cases. [23:41:24.0306] * and using UnaryExpression as the RHS means we could, in the future, relax the restriction, if people relax their concerns [23:41:26.0530] rkirsling: and you can do that, you just need to write parentheses or you get a syntax error [23:41:28.0434] * I'm not a huge fan of requiring the parenthesis since they wouldn't otherwise be necessary for most cases. [23:41:46.0406] you_cant_just.jpg [23:42:46.0283] If `throw` is at _Expression_ precedence, then we don't need _ThrowStatement_ anymore, since it would be completely covered by _ExpressionStatement_. [23:42:47.0344] (to be clear I would also prefer the early error route, over forcing parens everywhere, but I could live with forcing parens everywhere) [23:42:59.0791] is shane in here [23:43:10.0093] I too had no idea about `?? yield x` though. does that also apply to `?? await x`? [23:43:18.0603] > <@rbuckton:matrix.org> If `throw` is at _Expression_ precedence, then we don't need _ThrowStatement_ anymore, since it would be completely covered by _ExpressionStatement_. That's true but it would mean that we could not later switch from requiring parens everywhere to only requiring them in some cases [23:43:27.0928] > <@rkirsling:matrix.org> I too had no idea about `?? yield x` though. does that also apply to `?? await x`? no [23:43:29.0345] > <@rkirsling:matrix.org> I too had no idea about `?? yield x` though. does that also apply to `?? await x`? no, `await` is unary precedence [23:43:36.0475] `await` and `yield` parse very differently [23:44:32.0998] fair enough [23:45:03.0887] I don't think we need the EE rules for everything, just `+`, `-`, and `/`, the rest could still just be a lookahead restriction. [23:45:21.0533] And `/=` [23:45:26.0932] > <@rbuckton:matrix.org> If `throw` is at _Expression_ precedence, then we don't need _ThrowStatement_ anymore, since it would be completely covered by _ExpressionStatement_. I think that might change its completion value though [23:45:56.0063] > <@michaelficarra:matrix.org> I think that might change its completion value though They both result in a throw completion? [23:46:06.0275] oh, fair lol [23:52:11.0313] > <@ljharb:matrix.org> errors are best encountered early Exactly! The earliest place to encounter errors is in the grammar. [23:52:49.0681] For a user of the language, there is no difference between "in the grammar" and "as an early error" [23:53:58.0796] The difference is complexity. In most cases, if you're using early errors, then you're doing something more complicated than what can be expressed in a grammar, and that carries a cost. [23:54:42.0487] where is this gist? [23:55:09.0900] The cost is fairly small. Concretely, here's the trilemma: - no early errors, `throw` is high precedence: means that `throw a ? b : c` would throw `a` - no early errors, `throw` is low precedence: means that `x ?? throw y` is illegal - early errors: means you have a little more complexity in the grammar [23:55:24.0910] the third arm of the trilemma seems _obviously_ better than the first two, to me [23:55:37.0631] > <@shuyuguo:matrix.org> where is this gist? https://gist.github.com/bakkot/5a22c8c13ce269f6da46c7f7e56d3c3f [23:55:43.0245] (_wow, I never actually stopped to analyze dilemma into di+lemma before..._) [23:55:44.0796] I am concerned about usability. [23:55:48.0999] I've created https://github.com/tc39/proposal-throw-expressions/pull/18 to show what the Early errors would look like. [23:56:27.0409] Hmm. it didn't publish a rendered spec [23:56:35.0768] > <@bakkot:matrix.org> the third arm of the trilemma seems _obviously_ better than the first two, to me yeah I think I agree that you're kinda unlikely to hit the third one [23:56:41.0021] I mean, the hazard case of the third one [23:56:42.0933] ah, now it did [23:57:02.0627] > <@waldemarh:matrix.org> I am concerned about usability. As a user, the early errors seem like the most usable option of the three I've listed. [23:57:14.0532] > <@bakkot:matrix.org> https://gist.github.com/bakkot/5a22c8c13ce269f6da46c7f7e56d3c3f thanks [23:57:21.0266] I only need to add 3 static semantics rules and remove `+`, `-`, `/`, and `/=` from the banned token list. [23:57:31.0558] I agree it is a little more complicated, but you have to weigh that against the costs of the other options, which seem a lot worse. [23:57:42.0024] Will there be new things need to escape in the future? [23:58:06.0695] The idea is, no [00:01:16.0535] Either a throw expression can be used in a logical expression or not. Having it sometimes be usable in a logical expression and sometimes not is too confusing. [00:01:40.0809] That's what we'd get with the early errors. [00:01:41.0391] I think having it usable only as the RHS of a logical expression is completely fine. [00:01:52.0044] There is no use case for having it as the LHS of a logical expression. [00:01:58.0224] > <@waldemarh:matrix.org> Either a throw expression can be used in a logical expression or not. Having it sometimes be usable in a logical expression and sometimes not is too confusing. Well it's like `-1 ** 2` vs `1 ** -2` [00:02:44.0224] ryzokuken: can we get the queue cleared out? [00:02:46.0477] That analogy is not helpful. [00:03:03.0673] It is an expression that can be used only on one side of a binary operator and not on the other [00:03:21.0841] > <@michaelficarra:matrix.org> ryzokuken: can we get the queue cleared out? oops, thanks for the reminder [00:03:23.0932] How is that relevant? [00:03:24.0360] should be good now [00:03:55.0193] > <@waldemarh:matrix.org> Either a throw expression can be used in a logical expression or not. Having it sometimes be usable in a logical expression and sometimes not is too confusing. I don't find the rule "`throw` has to be the right-most thing, unless you parenthesize it" to be that confusing. [00:04:45.0695] I do. It violates intuition about how operator precedence works. [00:06:35.0393] No user will ever have to learn that `throw` can't be used on the LHS of a logical expression, so they will not have anything to be confused by. [00:07:02.0248] The only reason someone would write `throw x || y` is if they were hoping to throw `x || y`, and that isn't the behavior they'd get with higher precedence and no early errors anyway. [00:07:17.0245] Parenthesizing `throw expr` as `throw(expr)` is intuitive. Parenthesizing it as `(throw expr)` is not. [00:07:55.0490] > <@waldemarh:matrix.org> Parenthesizing `throw expr` as `throw(expr)` is intuitive. Parenthesizing it as `(throw expr)` is not. That's precisely why this requires parens for binary expressions on the right side of `throw`. [00:08:21.0678] If you want to throw `a || b` from an expression position, you write `throw (a || b)` [00:08:52.0340] I gave a counterexample during the plenary. [00:12:36.0935] Can you repeat it here? [00:13:41.0534] b && throw(c) || d [00:14:33.0913] to me that would be akin to how we required parens when mixing `??` and `&&` or `||`. [00:14:43.0909] * to me that would be akin to how we required parens when mixing `??` with `&&` or `||`. [00:14:56.0077] But we can mix && and || without requiring parentheses. [00:15:08.0472] `(b && throw c) || d` or `b && (throw c) || d` [00:15:42.0991] OK, yes, that's a good example. I retract the claim that no one will have to learn that `throw` can't be used as the LHS of a logical expression, but I stand by the claim that this cost is less than that of having `throw a ? b : c` throw `a`. [00:15:48.0161] linters would generally push you towards the parens anyways [00:15:50.0375] * OK, yes, that's a good example. I retract the claim that no one will have to learn that `throw` can't be used as the LHS of a logical expression, but I stand by the claim that this cost is less than that of having `throw a ? b : c` throw `a`. [00:16:24.0181] Making things illegal with early errors means that you're forced to confront the complexity as early as possible, instead of accidentally writing a program whose behavior is not what you thought. [00:16:39.0058] And `throw a ? b : c` seems like a case which will come up a _lot_ if it is not made illegal [00:17:58.0127] * OK, yes, that's a good example. I retract the claim that no one will have to learn that `throw` can't be used on the LHS of a logical expression, but I stand by the claim that this cost is less than that of having `throw a ? b : c` throw `a`. [00:19:06.0657] I see a black screen [00:19:09.0020] for some reason [00:19:18.0606] ah, it fixed itself [00:19:28.0329] > <@bakkot:matrix.org> OK, yes, that's a good example. I retract the claim that no one will have to learn that `throw` can't be used on the LHS of a logical expression, but I stand by the claim that this cost is less than that of having `throw a ? b : c` throw `a`. You can fix that by requiring the `throw(expr)` form. [00:20:03.0443] > <@bakkot:matrix.org> OK, yes, that's a good example. I retract the claim that no one will have to learn that `throw` can't be used on the LHS of a logical expression, but I stand by the claim that this cost is less than that of having `throw a ? b : c` throw `a`. * You can fix that by requiring the `throw(expr)` form for throw-expressions. [00:20:50.0915] Can you elaborate on that? [00:21:22.0855] The argument of a throw-expression must be a parenthesized expression. [00:21:32.0740] If `throw` is at unary expression precedence, then even if the RHS of `throw` is a ParenthesizedExpression, you would still have `throw (a) ? b : c` being legal [00:21:35.0753] Just like the condition of an if-expression must be parenthesized. [00:22:49.0620] The first operand of ?: is rarely parenthesized. [00:28:40.0490] True, but it would be confusing for readers. [00:30:40.0566] Also, personally, I would prefer having `throw` only usable in parentheses, personally. `(throw new Error())` looks a lot more natural, to me, than `throw (new Error())`. [00:31:25.0056] * Also, personally, I would prefer having `throw` only usable in parentheses. `(throw new Error())` looks a lot more natural, to me, than `throw (new Error())`. [00:31:46.0989] (And has fewer edge cases.) [00:33:07.0316] > <@bakkot:matrix.org> Also, personally, I would prefer having `throw` only usable in parentheses. `(throw new Error())` looks a lot more natural, to me, than `throw (new Error())`. I somehow want to both 👍️ and 👎️ this -- I think you should write `throw` without a trailing space like for dynamic import [00:33:16.0989] > <@bakkot:matrix.org> Also, personally, I would prefer having `throw` only usable in parentheses. `(throw new Error())` looks a lot more natural, to me, than `throw (new Error())`. * I somehow want to both 👍️ and 👎️ this -- I think you should write `throw` without a trailing space like usually done for dynamic import [00:33:33.0738] > <@bakkot:matrix.org> Also, personally, I would prefer having `throw` only usable in parentheses. `(throw new Error())` looks a lot more natural, to me, than `throw (new Error())`. I'd be fine with requiring throw-expressions to use the `(throw expr)` form. It's simple, understandable syntax. [00:35:38.0540] I would not block that, always parens is better than, for example, parens-in-function-params-except-for-last-one. I think it looks particularly bad compared to the parens-less version, but better than the current inconsistency with comma-separated lists [00:37:48.0045] real talk my brain is not working very well [00:37:52.0542] please make temperature check real simple [00:39:33.0450] seem need to refresh the page to see the temp check [00:41:55.0709] TCQ feedback: we have two positive options but just one negative [00:42:01.0094] I do not see the temp check, even after refreshing. [00:42:14.0976] same here [00:42:20.0216] tried in two browsers [00:42:24.0449] no options appear [00:43:32.0056] > <@nicolo-ribaudo:matrix.org> TCQ feedback: we have two positive options but just one negative this is sort of intentional wrt our working mode but yeah its definitely confusing [00:44:45.0682] Isn't the API for a proposal supposed to be mostly settled before moving to stage 2? [00:45:09.0346] Well the API is either this or nothing [00:45:31.0264] "Possible API to do the clamping logic" doesn't seem settled to me. [00:45:49.0818] it'd just be a one-arg function [00:45:50.0188] the thing where some specific person needs to say "I withhold consensus" seems like it makes proposals to easy to advance [00:45:57.0197] > <@bradfordcsmith:matrix.org> "Possible API to do the clamping logic" doesn't seem settled to me. There is no interest from anybody to pursue a different API, given that one of the main motivations is consistency [00:46:08.0478] > <@bakkot:matrix.org> the thing where some specific person needs to say "I withhold consensus" seems like it makes proposals to easy to advance and yet [00:46:10.0725] having 40% of the plenary unconvinced does not seem like it should amount to "consensus" [00:46:35.0884] i mean yeah jordan is just being nice [00:47:04.0498] under the pure rules, if jordan wants x and no one has some strong blocker for x, it would move forward [00:47:16.0836] the pure rules say "consensus" [00:47:30.0790] we have been operating in a mode where, if no one says "I withhold consensus", it is regarded as consensus [00:47:44.0815] but that seems absurd after 40% of delegates indicated they were unconvinced [00:48:13.0521] I guess it's a question of whether people need to be "convinced" [00:48:31.0938] as opposed to merely not "convinced of the opposite" [00:48:46.0828] there is no "convinced of the opposite" box [00:48:50.0985] right [00:48:54.0337] there is an "indifferent" box, though [00:49:01.0444] ah true. [00:49:27.0382] oh man symbol.thenable [00:49:37.0862] i was so upset when this didn't get stage 1 [00:49:52.0834] i had an angry thread on twitter [00:50:10.0838] What does it mean to withdraw a stage 0 proposal, doesn't our actual process start at stage 1? [00:50:15.0006] "Stage 0 is just an idea" [00:50:56.0171] i've seen real code hit this problem [00:51:00.0773] yeah I think technically stage 0 and withdrawn are ~equivalent [00:52:11.0418] > <@devsnek:matrix.org> i've seen real code hit this problem i've wrote real code hit this problem and spend hours to find out what happened [00:52:42.0970] thenables are like a top-three mistake in JS, after "accepting things of the wrong type" and "existence of object.prototype" [00:53:05.0446] dunno if i'd put them that high but definitely up there [00:53:07.0219] I really hope we can have Symbol.thenable or any solution to solve the weird behaivor of module with `then` export. [00:53:15.0504] > <@bakkot:matrix.org> thenables are like a top-three mistake in JS, after "accepting things of the wrong type" and "existence of object.prototype" _with enters the room_ [00:53:27.0943] > <@haxjs:matrix.org> I really hope we can have Symbol.thenable or any solution to solve the weird behaivor of module with `then` export. Symbol.thenable wouldn't fix that, since you can't export a symbol name [00:53:40.0375] > <@bakkot:matrix.org> thenables are like a top-three mistake in JS, after "accepting things of the wrong type" and "existence of object.prototype" what the other two?😅 [00:53:40.0792] > <@nicolo-ribaudo:matrix.org> _with enters the room_ we have get rid of with in modern world so it no longer be a problem [00:53:46.0868] > <@bakkot:matrix.org> Symbol.thenable wouldn't fix that, since you can't export a symbol name *yet* [00:53:51.0795] `export { true as "@@thenable" }` 😆 [00:53:59.0844] > <@bakkot:matrix.org> Symbol.thenable wouldn't fix that, since you can't export a symbol name just let module have it automaticlly [00:54:10.0360] > <@haxjs:matrix.org> just let module have it automaticlly and it breaks user code [00:54:10.0483] > <@bakkot:matrix.org> Symbol.thenable wouldn't fix that, since you can't export a symbol name *yet* [00:54:11.0720] people have already started relying on the current the behavior, so we can't just unconditionally add it to all namespace objects [00:54:13.0110] > <@haxjs:matrix.org> just let module have it automaticlly It breaks modules that currently export `then` [00:54:26.0687] "breaks" [00:54:42.0261] wait no i have to avoid getting into this argument again 😅 [00:54:55.0243] Oh well, you could have `then[Symbol.thenable] = false` [00:54:59.0192] * Oh well, you could have `then[Symbol.thenable] = false` on the funxtion [00:55:02.0328] * Oh well, you could have `then[Symbol.thenable] = false` on the function [00:55:34.0346] > <@nicolo-ribaudo:matrix.org> It breaks modules that currently export `then` yeah maybe some modules use such bug as feature... but i still think we should fix it. [00:56:02.0232] if we are willing to break the web I have a lot of higher-priority things I would like to fix [00:56:11.0840] web2 right [00:56:14.0498] unfortunately I think we are not willing to break the web, so we can't fix it [00:56:14.0780] msaboff: ljharb: yes, endianness is about the bytes, not the bits. but clamping clamps something between 0 to 255, i think in a DataView method that is like, all about reinterpreting byte buffers, isn't there a possibility for confusion on whether you're clamping the leftmost byte or the rightmost byte of the Number value? [00:56:33.0666] like the other methods don't combine some operation on top of the conversion to and from number formats [00:56:35.0380] am i too jet lagged [00:58:25.0248] > <@bakkot:matrix.org> unfortunately I think we are not willing to break the web, so we can't fix it We first need to figure out whether it really break the web. [00:58:40.0546] I think, if we have consensus we can do EVERYTHING, how cares about the past. :) [00:59:16.0957] Previously, when `at` land, I already point out it conflict with old corejs polyfill, but no one care. [00:59:20.0834] * I think, if we have consensus we can do EVERYTHING, who cares about the past. :) [00:59:47.0508] IMO, it's really worse than Symbol.thenable. [00:59:57.0340] did it break things? [01:00:10.0157] In this case we know people rely on it [01:00:20.0164] > <@devsnek:matrix.org> did it break things? yes, at that lego site, because they used arrays as hash maps and used `'at'` as a key [01:00:30.0741] we broke lego? :O [01:00:30.0760] but... not in whatever way corejs was doing `at` afaik [01:00:39.0125] bricklink.com, yeah [01:00:43.0171] it was some lego marketplace site [01:00:47.0083] D: [01:00:53.0375] bricklink or something? it had brick in the name [01:01:01.0582] > <@shuyuguo:matrix.org> msaboff: ljharb: yes, endianness is about the bytes, not the bits. but clamping clamps something between 0 to 255, i think in a DataView method that is like, all about reinterpreting byte buffers, isn't there a possibility for confusion on whether you're clamping the leftmost byte or the rightmost byte of the Number value? When I think of clamping, your clamping the value, not part of the value. i.e. you aren't clamping a specific byte of the value. [01:01:24.0603] so we've got lego and nasa on the list [01:01:26.0917] i wonder what else [01:01:35.0794] msaboff: your intuition matches what jordan said, so i withdraw my withholding of consensus based on the possible confusion [01:01:46.0543] since i am off the mark on my intuition [01:01:58.0769] that said i'd be much comfortable going to stage 2 with a clear direction [01:02:18.0693] not 3 possible choices [01:02:23.0168] > <@shuyuguo:matrix.org> that said i'd be much comfortable going to stage 2 with a clear direction Agree. A direction and not a menu of directions. [01:02:50.0056] @snek Wasn't it for `Array.group*` IBM? [01:06:34.0137] `/=` is a strange case for throw expressions. `a ?? throw b /= c` wouldn't be legal even without the token restriction, because `a ?? throw b` isn't a LeftHandSideExpression. [01:08:33.0004] With `/=` you have to be very careful about how things get tokenized, before applying the syntactic grammar [01:09:10.0780] So we must be careful with saying that it doesn't have the same problem as `/` [01:11:30.0303] The issue is this: ``` throw b /= c / d ``` is interpreted as `throw b /= c / d`. But the expression form doesn't allow `throw` on the left of `/=`, so I can't use an EE to get around ASI in that case. [01:21:08.0719] Well, it could work if I added a level between UpdateExpression and LeftHandSideExpression, I guess. [01:25:24.0620] Or just add it to LeftHandSideExpression, since it wouldn't be a valid assignment target anyways. [06:57:35.0921] chairs: shu and I are happy to reduce our TDZ/coercing items (respectively) to 45 minutes if it means getting to discuss both items [06:57:49.0806] (I am also happy to ok with reducing mine further if that's the only way we can fit it in) [07:35:45.0519] > <@bakkot:matrix.org> chairs: shu and I are happy to reduce our TDZ/coercing items (respectively) to 45 minutes if it means getting to discuss both items it would be most helpful if we can reduce the timeboxes unconditionally. this allows us more flexibility to slot things in when time gets freed up [07:37:19.0713] this also increases the likelihood of getting to discuss both items, although we now have time for TDZ already, per time already freed up [10:19:14.0458] I think we just need a `"use semicolons"` parser switch that turns off ASI honestly. [12:52:46.0647] Avoiding parens for `throw` may end up being more complex than it's worth to try to handle `/=`, but I'm not sure I want to give up on the UnaryExpression precedence. I'm thinking about restricting `throw` to be only valid in _ParenthesizedExpression_ for now, while still leaving it's operand to be _UnaryExpression_. While fairly restrictive for now, it would give us the ability to relax the grammar in the future by either resolving the ASI issue somehow, or widening the operand. [13:48:52.0616] so this means we use it like an s-expression? 😁 [14:29:33.0179] Chris de Almeida: then reduce TDZ to 45 mins [14:30:14.0032] Chris de Almeida: further reduce it to 30 minutes if (and only if) that accommodates the coercion item, otherwise keep it at 45 [14:40:32.0549] thank you for being flexible! given these parameters, it's likely we will be able to get to both items in. still, I'm hopeful that we will gain some time today so that we don't have to compromise too much on the original timboxes [14:40:36.0689] * thank you for being flexible! given these parameters, it's likely we will be able to get to both items in. still, I'm hopeful that we will gain some time today so that we don't have to compromise too much on the original timeboxes [14:45:54.0907] * thank you for being flexible! given these parameters, it's likely we will be able to get to both items. still, I'm hopeful that we will gain some time today so that we don't have to compromise too much on the original timeboxes 2023-09-27 [17:01:28.0520] > <@tabatkins:matrix.org> I think we just need a `"use semicolons"` parser switch that turns off ASI honestly. Anti proposal: `"no asi harzards"` parser switch that fix ASI hazards according to developer's expectation. (Yeah , it's very very impossible , especially the committee introduced the very serious new hazards in ES2020) [17:54:49.0093] i doubt anything that even tacitly encourages omission of semicolons will achieve consensus :-) [18:01:01.0249] I've updated https://github.com/tc39/proposal-throw-expressions/pull/18 to use Static Semantics rules to avoid ASI for `+`, `-`, `/`, and `/=`, in keeping with how we also use Static Semantics rules to avoid ASI for optional chains followed by a template literal on a following line. I don't believe the end result is quite so complex, but I'd appreciate if anyone with time could take a look over it as I am still short a reviewer. [18:02:14.0400] * I've updated https://github.com/tc39/proposal-throw-expressions/pull/18 to use Static Semantics rules to avoid ASI for `+`, `-`, `/`, and `/=`, in keeping with how we also use Static Semantics rules to avoid ASI for optional chains followed by a template literal on a following line. I don't believe the end result is as complex as was suggested, but I'd appreciate if anyone with time could take a look over it as I am still short a reviewer. [18:02:25.0385] i was going to say "tcq needs updating" but i refreshed and it's not loading at all for me [18:02:28.0740] TCQ down for everyone or just me? [18:02:30.0410] * i was going to say "tcq needs updating" but i refreshed and it's not loading at all for me now, just hanging [18:02:45.0036] tcqdownforeveryone.status [18:03:17.0945] this would never happen if it was using IBM infra! `/s` [18:03:58.0288] TCQ appears to be operational once again [18:04:09.0407] 🤞 [18:04:23.0496] > <@ljharb:matrix.org> i doubt anything that even tacitly encourages omission of semicolons will achieve consensus :-) yeah , we lost the feasibility forever after ES2020. [18:05:21.0460] not because of that, but because some number of us (at least one :-) ) feel that omitting semicolons isn't a good style to encourage. [18:06:26.0918] * not because of that, but because some number of us (at least one 😄) feel that omitting semicolons isn't a good style to encourage. [18:07:26.0481] * not because of that, but because some number of us (at least one 😄) feel that omitting semicolons ~isn't a good~ is a harmful style to encourage. [18:07:30.0216] * not because of that, but because some number of us (at least one 😄) feel that omitting semicolons ~~isn't a good~~ is a harmful style to encourage. [18:07:33.0583] * not because of that, but because some number of us (at least one 😄) feel that omitting semicolons ~isn't a good~ is a harmful style to encourage. [18:09:25.0661] we should make a t-shirt [18:09:35.0487] "eat your vegetables and use your semicolons" [18:09:54.0889] you should use your whole colon tbh [18:10:00.0020] omitting semicolons is `eval()`! [18:16:56.0618] I never know how to understand the feedback "we would like to see this done but are unwilling to dedicate resources to doing it ourselves" [18:17:20.0621] is there not an inherent conflict there? [18:17:52.0781] Michael Ficarra: i think you know in your heart how to understand that feedback [18:17:59.0549] > <@ljharb:matrix.org> not because of that, but because some number of us (at least one 😄) feel that omitting semicolons ~isn't a good~ is a harmful style to encourage. While I understand there are always people don't like omitting semicolons, also there are always people don't like to be forced to add semicolons. After all, I believe the original design of the language (by BE) encourage omitting semicolon, just like the most recent new application programming languages (swift, kotlin, scala3, etc.) Unfortunately BE made some small mistakes and introduce ASI hazards (though the most ASI hazards patterns were not used by any one in early days), but it still fixable IMO, until ES2020 (the best time is ES5 of coz). [18:20:43.0778] > <@ljharb:matrix.org> not because of that, but because some number of us (at least one 😄) feel that omitting semicolons ~isn't a good~ is a harmful style to encourage. * While I understand there are always people don't like omitting semicolons, also there are always people don't like to be forced to add semicolons. After all, I believe the original design of the language (by BE) encourage omitting semicolon, just like the most recent new application programming languages (swift, kotlin, scala3, etc.) Unfortunately BE made some small mistakes and introduce ASI hazards (though the most ASI hazards patterns were not used by any one in early days), but it still fixable IMO, until ES2020 (the best time to fix asi harzards was ES5 strict mode, of coz). [18:21:36.0244] We should probably take this to TDZ; [18:22:04.0635] this still assumes that removing hazards from something hazardous is a "fix" [18:23:49.0092] this is a cool and relevant pr https://github.com/nodejs/node/pull/48528 [18:25:37.0679] we actually see some huge performance boosts here [18:25:58.0596] Yah, this will be considerably faster than `AsyncLocalStorage` in Node.js [18:28:47.0666] Can you help me understanding this better? [18:33:56.0057] And it is using mechanisms that is already available in V8 [18:33:59.0884] * And it is using mechanisms that are already available in V8 [18:35:43.0362] I was hoping for the same [18:40:06.0233] V8 is a mutable codebase [18:41:56.0541] i'd not consider the state things are today to be immutable -- e.g., don't assume `ContinuationPreservedEmbedderData` and its current performance characteristics to be like, unchanging facts of the world forever and forever [18:42:03.0804] I still not convinced by the motivation of get-intrinsics. it looks tooooo specialized to me, only spec lawyer will use it [18:42:55.0484] > <@shuyuguo:matrix.org> i'd not consider the state things are today to be immutable -- e.g., don't assume `ContinuationPreservedEmbedderData` and its current performance characteristics to be like, unchanging facts of the world forever and forever yeah that's why it hasn't merged yet [18:43:10.0119] upstream discussion [18:43:33.0029] sometimes in readmes, I link to issues for open questions. Or at least I try not to claim that they are already solved. [18:43:50.0980] > <@devsnek:matrix.org> yeah that's why it hasn't merged yet yet champions keep repeating the argument that "no performance problem because V8 already ships this" [18:43:58.0618] I can tell from my perspective how I want to dedicate resources on a proposal I’m championing going through a part that depends dedicated expertise that is out of my domain. This requires cross collaboration and contracting in which I’m doing. Yet I’m not sure if you’re referring to me on ShadowRealm, so I don’t know if that’s the clarification you’re looking for, as you are also not asking for me directly or in a way that makes it seem you’re actually trying to understand. With that said, it took us time, but we are happy to work again with people that can provide the expertise to complete the tasks needed. I’m also glad that TC39 is composed by a diverse set of expertises and backgrounds. We all must aim for the goal of interoperability, which is the best value of JS. [18:44:27.0886] > <@shuyuguo:matrix.org> i'd not consider the state things are today to be immutable -- e.g., don't assume `ContinuationPreservedEmbedderData` and its current performance characteristics to be like, unchanging facts of the world forever and forever It's more like an existence proof that this technique isn't way too slow--I would've assumed the opposite before this had shipped. [18:44:42.0841] > <@littledan:matrix.org> It's more like an existence proof that this technique isn't way too slow--I would've assumed the opposite before this had shipped. or it isn't way too much used [18:44:55.0799] like with. [18:44:56.0045] the copy is being done unconditionally [18:45:15.0720] i understand the state of the world today [18:45:17.0153] > <@devsnek:matrix.org> yeah that's why it hasn't merged yet What is it that hasn't merged? [18:45:22.0993] (but actually I found `with` does not _that_ bad on performance, at least in JSC) [18:45:26.0822] the pr i linked [18:45:32.0897] i am saying, V8 retains the optionality to _become_ unhappy with CPED [18:45:42.0894] because like shu said, google isn't sure that CPED will continue to exist [18:46:09.0450] what is CPED, Carnegie Project on the Education Doctorate? [18:46:18.0239] ContinuationPreservedEmbedderData [18:47:21.0963] > <@devsnek:matrix.org> ContinuationPreservedEmbedderData Still not understand what is it 🤣 [18:48:11.0133] > <@haxjs:matrix.org> Still not understand what is it 🤣 its sort of like [[AsyncContextSnapshot]] in the async context proposal [18:48:14.0838] though it doesn't map exactly [18:48:16.0328] every variadic function makes TS team sweat... [18:49:39.0722] > <@christianulbrich:matrix.org> every variadic function makes TS team sweat... (a: T): [T] (a: T, b: T1): [T, T1] (a: T, b: T1, c: T2): [T, T1, T2] ... [18:49:50.0146] it happens in many languages [18:52:04.0019] i don't think "i don't have an iterable" is a problem in practice [18:52:39.0033] if you have more than 0 things, there is generally a way to turn at least one of them into the head of the iterator [18:52:46.0987] [].values, Iterator.from, etc etc [18:57:37.0289] `Iterator.once(value)` is potentially an option, assuming it were lighter weight than just using a single-element array. [18:57:51.0482] `Iterator.of`, surely? [18:58:24.0821] > <@shuyuguo:matrix.org> i'd not consider the state things are today to be immutable -- e.g., don't assume `ContinuationPreservedEmbedderData` and its current performance characteristics to be like, unchanging facts of the world forever and forever My design for AsyncContext was independent of CPED, it just happens that CPED is the exact same thing that's needed (it's based on the poorlyfill I implemented for Vercel). The priority is today's code is unaffected by the proposal (tasks need to store an additional pointer), resuming a task is unaffected (only a pointer swap), and we can figure out how to optimize creating new context afterwards. I found CPED while digging through the V8 codebase's host hooks afterwards, and it did exactly what I wanted. [18:58:25.0933] But generally, I'm fine with `concat`/`append`. I use them in my own packages. [18:59:03.0803] there is iter::once(value) in rust but i have basically never seen any code that uses it [18:59:05.0603] i'm sure it exists [18:59:15.0094] but its far more uncommon than chaining so i wouldn't want to over-index on that [18:59:21.0562] Justin Ridgewell: i am responding to the argument that's repeatedly been put forth that this will not have performance problems because CPED exists in V8 [18:59:36.0878] When I saw `Iterator.of` I immediately thought of `RxJS.of()` , though it has been while, that I did reactive streams, `.of()` looks like a good choice... [18:59:56.0005] Also `Array.of` [18:59:56.0046] Justin Ridgewell: i just want to make the point that that argument is not strictly true, since V8 retains the optionality to become unhappy with the performance CPED as it stands today [19:00:17.0512] all this being said, i don't know *why* v8 doesn't like CPED [19:00:25.0943] i just know that every time it comes up someone from v8 makes sure to say that [19:00:43.0205] I'll also add the C# has `Concat`, `Append`, and `Prepend` as well. [19:00:48.0238] we don't like it because it unconditionally incurs memory cost on every callback [19:01:24.0413] > <@shuyuguo:matrix.org> Justin Ridgewell: i just want to make the point that that argument is not strictly true, since V8 retains the optionality to become unhappy with the performance CPED as it stands today If CPED is changed, that's fine. I think we're abusing it because it exists. AsyncContext requires something with similar functionality (global pointer, store a pointer on tasks, restore that pointer to resume). [19:01:36.0026] sounds good [19:01:40.0377] that matches my understanding [19:02:10.0512] > <@shuyuguo:matrix.org> Justin Ridgewell: i am responding to the argument that's repeatedly been put forth that this will not have performance problems because CPED exists in V8 It just proves that it can be implemented in a way that gives you the same performance as today's V8, which as Dan said, was unexpected for everyone. [19:02:21.0573] maybe in a few more years, we'll catch up with Python Itertools as of 2007! [19:02:31.0347] great work Michael Ficarra [19:02:43.0919] it is funny how much effort it takes to add a suite of functionality to js [19:02:44.0825] thanks littledan 🙂 [19:03:05.0636] watching how rust has evolved. stuff like "chain" barely gets any attention by anyone, whereas we have an entire proposal dedicated just to it [19:03:17.0511] snek: I actually appreciate that because I didn't realise how many possible shapes of solutions there were to these problem spaces [19:03:32.0205] need conclusion+summary for iterator sequencing 🙏 [19:03:35.0459] oh yeah its definitely important to consider these things [19:03:42.0754] I am confident that our process will produce a great solution here [19:04:16.0451] I think I'm still confused by the use of `.values` [19:04:18.0862] can we advance the queue [19:04:18.0974] * I think I'm still confused by the use of `.values()` [19:04:34.0282] rkirsling: don't worry about it, you will never need to use that [19:05:03.0617] > <@michaelficarra:matrix.org> I am confident that our process will produce a great solution here It's just to get an iterator from which you can call flatMap, which will then do the concat [19:05:27.0135] rkirsling: ^ [19:05:33.0029] TCQ has returned [19:05:39.0267] high level the pattern is just flatMap(iterator of iterators) [19:05:40.0447] oh thank god [19:06:04.0433] petition to add `iter` as an alias for symbol.iterator on all built-in iterators [19:06:14.0183] only if we can use `::` [19:06:23.0302] :( [19:06:41.0693] > <@bakkot:matrix.org> petition to add `iter` as an alias for symbol.iterator on all built-in iterators i think i'd be OK with this [19:08:22.0647] so from the discussion today, I think I will lean toward `Iterator.of/Iterator.prototype.flat` for iterator sequencing stage 2 [19:08:42.0670] :( [19:08:44.0119] and as a bonus, those methods are useful for other things [19:08:46.0246] I do not think people will reach for that [19:08:50.0678] I would really like a method named something obvious [19:08:56.0851] that makes it clear you are doing concatenation [19:09:00.0203] i think a static method is a non-starter [19:09:03.0284] for this problem space [19:09:23.0164] I'd be perfectly happy with `.concat`, `.append`, and `.prepend` [19:09:43.0996] also `flat` is problematic in ways that `concat` is not, wrt handling of non-iterable values [19:10:04.0981] > <@devsnek:matrix.org> i don't think "i don't have an iterable" is a problem in practice it is very common in practice to have something that can either be one thing, or a list of things, and `[].concat(x)` is incredibly useful and commonplace to ensure one always has an array without having to care [19:10:39.0073] i don't think i've ever seen code that has `[].concat(x)` [19:10:41.0700] I have literally never seen that pattern in any code not written by you [19:10:45.0655] i believe you that it exists [19:10:47.0713] lol [19:10:58.0812] OH `cons` [19:10:59.0455] but like, i wrote code with `chain` literally today (in rust) at work [19:11:08.0371] none the less, i didn't make it up, it's common in lots of codebases i've worked in, which is why i use it in all of mine [19:11:19.0833] > <@bakkot:matrix.org> I have literally never seen that pattern in any code not written by you It definitely exists in transpiled emit, not sure how often it is hand-written [19:11:45.0934] i agree concatSpreadable is awful, but not because "concat takes an array or a scalar" is awful. [19:12:16.0956] two things can be awful at the same time [19:12:50.0594] "preferred" is also a bit strong. [19:13:09.0551] sure. i just don't agree the second one is awful, because i don't think in terms of haskelly types [19:13:52.0092] I mean even TypeScript-y types don't unify those things [19:14:18.0027] you don't need some advanced type system to be told that that is inappropriate [19:14:22.0555] waldemar: You don't get a prototype, at least as far as we've been discussing. [19:14:39.0662] As in, `[[Prototype]]` is `null` [19:14:48.0736] > <@bakkot:matrix.org> also `flat` is problematic in ways that `concat` is not, wrt handling of non-iterable values to elaborate on this: either it throws on non-iterable values, or it doesn't; both are problematic. throwing on non-iterable values means you can't use it like `Array.prototype.flat` to flatten a tree. not throwing on non-iterable values means that ever making anything iterable is a breaking change. [19:14:49.0756] imo having a variable number of things is what vectors are for, not vector or item [19:14:49.0883] typescript certainly can't handle `[].concat()` at all, it's been a long standing open issue on the repo [19:14:55.0285] * typescript certainly can't handle `[].concat()` at all, it's been a long standing open issue on the repo. that doesn't mean it's bad. [19:15:29.0900] * typescript certainly can't handle `[].concat()` at all, it's been a long standing open issue on the repo. that doesn't mean it's bad, it's just another gap in TS's ability to describe JS. [19:16:49.0536] I remember the original draft don't allow prototype on shared struct values, now it's allowed but just omitted when transfer? Is my understanding correct? [19:17:12.0630] i'm curious why prototypes are a thing at all [19:17:16.0783] on shared structs [19:17:28.0808] > <@haxjs:matrix.org> I remember the original draft don't allow prototype on shared struct values, now it's allowed but just omitted when transfer? Is my understanding correct? Not quite. If you want thread-local behavior, you must explicitly opt in and supply that behavior in each thread. [19:17:31.0391] i'd expect them to be an underlying implementation detail of some higher level thing [19:17:32.0972] i'm also confused why a struct would have behavior (functions) attached [19:17:43.0387] me hearing "just an ephemeron" just now felt like like most people probably feel hearing "just a monoid object in the category of endofunctors on C" [19:17:47.0075] I don't understand this. Why is throwing on non-iterables bad? [19:17:59.0061] > <@devsnek:matrix.org> i'd expect them to be an underlying implementation detail of some higher level thing There is a lot of complexity to this. Attaching behavior is very important. [19:18:00.0508] maybe just reference counter... [19:18:15.0860] > <@rbuckton:matrix.org> There is a lot of complexity to this. Attaching behavior is very important. *having* behavior is. *attaching* it is just a style choice. [19:18:26.0216] > <@rbuckton:matrix.org> There is a lot of complexity to this. Attaching behavior is very important. * _having_ behavior is. _attaching_ it is just a style choice. functions can live separate from the data they affect. [19:18:29.0958] > <@rbuckton:matrix.org> Not quite. If you want thread-local behavior, you must explicitly opt in and supply that behavior in each thread. Not fully understand... I mean I can always use functions (not methods)? [19:19:10.0022] > <@ljharb:matrix.org> typescript certainly can't handle `[].concat()` at all, it's been a long standing open issue on the repo. that doesn't mean it's bad, it's just another gap in TS's ability to describe JS. https://github.com/microsoft/TypeScript/issues/47351 is the issue presumably [19:19:12.0072] what i read is, "because it's actually an important use case to have an X and a non-X and concatenate them" [19:19:16.0125] > <@ljharb:matrix.org> _having_ behavior is. _attaching_ it is just a style choice. functions can live separate from the data they affect. No, attaching is necessary for many projects, this is a result of feedback from multiple sources experimenting with the origin trial. Not everyone needs it, but many do. [19:19:32.0566] > <@bakkot:matrix.org> https://github.com/microsoft/TypeScript/issues/47351 is the issue presumably (with exactly 0 +1s...) [19:19:37.0834] > <@rbuckton:matrix.org> No, attaching is necessary for many projects, this is a result of feedback from multiple sources experimenting with the origin trial. Not everyone needs it, but many do. i would love to be convinced that it's "need" [19:19:42.0616] > <@rbuckton:matrix.org> There is a lot of complexity to this. Attaching behavior is very important. I think it might be solved by extensions proposal? Don't use prototype, always use extension methods/accessor on shared struct values. [19:19:44.0717] i think sharing code within a struct makes sense and is well motivated. i think the whole prototype thing is weird [19:20:08.0971] > <@rbuckton:matrix.org> No, attaching is necessary for many projects, this is a result of feedback from multiple sources experimenting with the origin trial. Not everyone needs it, but many do. * i would love to be convinced that it's "need", but people quite often incorrectly think their wants are needs. [19:20:17.0987] > <@rkirsling:matrix.org> me hearing "just an ephemeron" just now felt like like most people probably feel hearing "just a monoid object in the category of endofunctors on C" at least ephemeron can be explained in 2 lines and you may need a math phd to know the category theory [19:20:26.0999] I've been experimenting with this in TypeScript. I absolutely cannot use it efficiently without the ability to attach behavior, unless I use Proxy or completely duplicate our AST as regular objects for the public API. [19:20:35.0634] anything else would be a significant breaking change. [19:20:46.0940] > <@michaelficarra:matrix.org> I don't understand this. Why is throwing on non-iterables bad? did you not see the "to flatten a tree" bit [19:20:54.0858] i don't understand why `x.foo()` and `foo(x)` are meaningfully different [19:21:06.0926] (I think garbage collection is more difficult than category theory, but that's probably an issue of motivation) [19:21:07.0090] * i don't understand why `x.foo()` and `foo(x)` are meaningfully different in terms of capabilities [19:21:17.0564] oh you mean like with a depth and stuff? [19:21:18.0036] > <@rbuckton:matrix.org> I've been experimenting with this in TypeScript. I absolutely cannot use it efficiently without the ability to attach behavior, unless I use Proxy or completely duplicate our AST as regular objects for the public API. this makes perfect sense to me. It's necessary to be able to use objects directly, without wrapping them. [19:21:18.0376] > <@ljharb:matrix.org> i don't understand why `x.foo()` and `foo(x)` are meaningfully different in terms of capabilities If you are writing a project from scratch, sure. If you are adapting an existing project, it might not be feasible. [19:21:21.0457] nobody should be doing that [19:21:24.0836] don't do that [19:21:30.0651] I was assuming you would have the depth parameter like on arrays, yes [19:21:34.0335] > <@rbuckton:matrix.org> If you are writing a project from scratch, sure. If you are adapting an existing project, it might not be feasible. that's not a need, that's just difficulty adapting to a different style. [19:21:35.0167] flat should not take a depth, it should always be 1 [19:21:35.0268] > <@rbuckton:matrix.org> I've been experimenting with this in TypeScript. I absolutely cannot use it efficiently without the ability to attach behavior, unless I use Proxy or completely duplicate our AST as regular objects for the public API. to be clear what i'm suggesting is like. you could have a property of a struct, which holds a sharable code value (a function of sorts). it would probably be callable like `a.b()` even. [19:21:35.0313] would the plan be to not do that? [19:21:42.0012] yeah no depth parameter [19:21:47.0073] well [19:21:47.0263] fucking gross [19:21:55.0717] > <@ljharb:matrix.org> i don't understand why `x.foo()` and `foo(x)` are meaningfully different in terms of capabilities DX, and x.foo() could be virtual methods. [19:22:03.0723] why? `.flat(Infinity)` is great [19:22:08.0972] > <@ljharb:matrix.org> that's not a need, that's just difficulty adapting to a different style. That's not an option for a widely used public API, without breaking an entire ecosystem of tooling. [19:22:13.0603] 🤦‍♂️ please [19:22:22.0497] I am ok with this but I think if you're going to push jordan to accept an asymmetry with array methods, you should push for `.concat`, the nice normal thing [19:22:45.0908] And I'm not talking about TS, though we would be included in that. This is feedback from other attempts to migrate other projects to use structs. [19:23:04.0151] what tooling ecosystem? certainly APIs may need breaking changes; asynchrony forces that, for example. [19:23:13.0015] it's perfectly fine if multithreading forces that too. [19:23:18.0291] * it's perfectly fine if multithreading forces that too (even if it's ideal not to) [19:23:51.0195] * it's perfectly fine if multithreading forces that too (even if it's ideal not to) we have semver and code refactoring tools and codemods that can make that easier. [19:23:52.0848] I don't believe that it is, and there are solutions under discussion to make that a non-issue. [19:25:28.0330] Need pipeline and static functions 🤞 [19:25:47.0440] oof, didn't we already make this mistake with global registries with symbols? [19:26:03.0948] * oof, didn't we already make this global registry mistake with symbols? [19:26:15.0941] this is even worse than that; it links objects! [19:26:23.0803] when the solution is "universal state!" then maybe the problem's not worth solving [19:26:26.0309] what global registry mistake? registered symbols are super useful [19:26:48.0169] i'm not sure how, they're just fancy strings. [19:27:04.0436] yeah just use a string [19:27:31.0838] strings can be constructed [19:27:35.0108] from random places [19:27:37.0434] > <@michaelficarra:matrix.org> yeah just use a string Then why did we add `Symbol.iterator`? It's just a fancy `__iterator__`. [19:27:40.0349] i don't think the domain overlap makes sense [19:27:53.0860] yeah, I also don't fully understand the use cases of `Symbol.for()` [19:28:06.0671] snek: that's the same thing as passing the string to Symbol.for... [19:28:10.0914] i think a great example is `Symbol.for('nodejs.util.inspect')` [19:28:13.0968] > <@devsnek:matrix.org> what global registry mistake? registered symbols are super useful this is the first time I've heard anyone express this opinion - what are they useful for? [19:28:24.0136] what does that do that a string wouldn't do? [19:28:30.0032] > <@devsnek:matrix.org> i think a great example is `Symbol.for('nodejs.util.inspect')` not sure how that's great; node would work the same if it used a non-global symbol [19:28:31.0754] > <@devsnek:matrix.org> i think a great example is `Symbol.for('nodejs.util.inspect')` u could also use the string directly as key... [19:28:39.0200] you could use a string [19:28:50.0534] > <@devsnek:matrix.org> i think a great example is `Symbol.for('nodejs.util.inspect')` * not sure how that's great; node would work the same if it used a non-global symbol - and in fact it *did* use a non-global one prior to the change to make it global [19:28:57.0544] but strings can come from random places [19:29:05.0418] so can global symbols [19:29:07.0955] you could end up with that object by accident or maliciously [19:29:14.0406] same with global symbols [19:29:20.0137] say something that you can't say about strings [19:29:24.0559] no, you have to choose to invoke Symbol.for on some random string [19:29:34.0377] its not the default [19:29:37.0443] maybe less likely by accident but equally likely by malice? [19:29:50.0980] To be honest , global symbol might be a little bit safer than string, but just a very little... [19:29:52.0956] > <@ljharb:matrix.org> same with global symbols and if you're using a symbol this way, you're deliberately trying to break things [19:29:56.0436] *using* some random string is pretty unlikely too, especially that java package style node uses [19:30:02.0762] I dunno, I randomly call Symbol.for on things all the time, just in case [19:30:44.0046] ...i don't understand what could possibly be gross about a depth. It's just a shorthand for .flat().flat().flat()... [19:30:47.0096] this is very amusing because I always thought there was secretly a good reason why Symbol.for is a thing and I simply never needed to know it [19:30:56.0427] There have been several attempts to use the origin trial, which is currently data only, to adopt shared structs in existing projects. The feedback has been the same: Without the ability to attach behavior requires a complete rewrite of the project, including the public API, which is a burden that we would rather not enforce on the project maintainers, nor their consumers. That makes the feature unusable for projects that would sorely benefit from the capability. [19:30:59.0375] i am surprised to hear that people don't like symbol.for [19:31:02.0838] And personally, I use `.flat(Infinity)` more than any other value. ^_^ [19:31:13.0415] its definitely rare use cases but i think its well motivated at least [19:31:17.0128] * There have been several attempts to use the origin trial, which is currently data only, to adopt shared structs in existing projects. The feedback has been the same: Without the ability to attach behavior, shared structs require a complete rewrite of the project, including the public API, which is a burden that we would rather not enforce on the project maintainers, nor their consumers. That makes the feature unusable for projects that would sorely benefit from the capability. [19:32:27.0740] > <@rbuckton:matrix.org> There have been several attempts to use the origin trial, which is currently data only, to adopt shared structs in existing projects. The feedback has been the same: Without the ability to attach behavior, shared structs require a complete rewrite of the project, including the public API, which is a burden that we would rather not enforce on the project maintainers, nor their consumers. That makes the feature unusable for projects that would sorely benefit from the capability. what is the difference between `thing = wrap(struct)` and `Object.setPrototypeOf(struct, ...)`? [19:32:42.0547] > <@devsnek:matrix.org> what is the difference between `thing = wrap(struct)` and `Object.setPrototypeOf(struct, ...)`? Performance and memory consumption. [19:33:23.0519] In TypeScript, If you have a large AST, you either double your memory consumption for the AST, or redirect through accessors which is slower. [19:33:47.0007] you want the entire AST to be shared structs? [19:34:09.0386] even in languages with proper thread apis and such i would never want to do that [19:34:11.0167] > <@devsnek:matrix.org> you want the entire AST to be shared structs? That's how I would see us using this proposal in Babel too [19:34:17.0323] > <@devsnek:matrix.org> you want the entire AST to be shared structs? Yes. That is what I'm doing right now to parallelize parse in an experiment. [19:35:01.0750] > <@devsnek:matrix.org> you want the entire AST to be shared structs? * Yes. That is what I'm doing right now to parallelize the TypeScript parser in an experiment. [19:35:01.0781] And we could parallelize transform by having locks on subtrees [19:35:28.0274] have you looked into how projects like rslint work [19:35:36.0642] I could also parallelize emit, so I'd prefer to use the same AST everywhere. [19:36:43.0400] Does rslint operate on a file on a time, or does it require whole program knowledge? [19:37:10.0954] i'm not sure if it does whole program but i was more talking about how it operates on a shared AST [19:37:14.0226] * i'm not sure if it does whole program but i was more talking about how it operates on a shared AST in parallel [19:37:26.0296] TabAtkins: an infinitely-nested iterator will not be able to yield anything [19:38:01.0057] I am not familiar with the internals of rslint. [19:38:04.0332] Yeah and mapping over an infinite iterator will infinite loop too. Is this something that's easy to hit by accident? [19:38:17.0557] it might be good to look at how projects which operate on a "shared ast" as a concept work in other languages [19:38:26.0358] basically nobody uses infinite iterators, that's just not a problem that happens [19:38:30.0867] rslint is one example, but there are lots [19:38:52.0798] anyway i suspect i will end up losing this argument, i don't have the energy to care about typescript internals more than you [19:40:46.0711] JS inability to paralellize and share memory is the main reason we didn't use it for Turbobpack. [19:40:59.0335] I find the idea of _"having non-byte stuff shared"_ , quite easy to grasp, that this _"should work with functions"_ as well (bcause it is JS), seems no to be so far-fetched. Question is, whether this is really doable, not so much to me, whether someone would use it. [19:41:34.0767] We have proper sharing in Rust, but we don't access the same AST in parallel, only split the parsing/transforming between threads [19:41:37.0920] if we just have shared functions of some form, we don't need the prototype hacks [19:41:43.0537] So you're saying that when this goes to Stage 4, Turbopack can get rewritten in JS? [19:41:50.0382] aaaaaanyway this is why I would not recommend trying to move forward with `.flat` [19:42:14.0427] No, Rust offers us a lot more, but this was the non-starter for TS [19:42:38.0229] Rust macros are magic ✨ [19:42:56.0772] TabAtkins: mapping over an infinite iterator works fine, it does not infinite loop [19:43:12.0729] So you say, if we have macros in JS, that turbopack... ah sorry [19:43:13.0123] also people *do* use infinite iterators ljharb [19:43:14.0666] `for of` over an infinite iterator will infinite loop [19:43:21.0447] yeah, that's what i meant [19:43:21.0977] and infinite iterators are way more common than infinitely _nested_ iterators [19:43:24.0830] exhausting it [19:43:47.0756] infinitely nested iterators just don't exist at all, period [19:43:58.0623] I mean. Strings. [19:43:59.0615] there is no (useful) code that would construct them [19:44:12.0541] Because we fucked up. [19:44:18.0349] > <@jridgewell:matrix.org> Rust macros are magic ✨ There is also TS macros ( https://github.com/GoogleFeud/ts-macros ),maybe not very magic 😅 [19:44:41.0738] strings at least would not be a problem here [19:44:51.0845] > <@devsnek:matrix.org> if we just have shared functions of some form, we don't need the prototype hacks Looking at rslint, it looks like they start up a bunch of threads, parse in parallel, and then transmit the files back. Does `std::sync::mpsc::channel` clone the sent data, or does it reuse the same memory? [19:44:53.0068] > <@michaelficarra:matrix.org> infinitely nested iterators just don't exist at all, period you: > an infinitely-nested iterator will not be able to yield anything [19:45:03.0543] if they don't exist, then `.flat(Infinity)` is not at problem [19:45:08.0783] I'm not that familiar with the Rust API [19:45:09.0865] Outside of strings, infinitely nested iterators are indeed virtually never a thing. [19:45:16.0008] depends on what you're sending through it [19:45:20.0836] also they're iterable not iterator, so `.flat(Infinity)` on them wouldn't infinitely recurse [19:45:26.0231] So yeah, I'm also confused why they're an objection to flat(Infinity) [19:45:36.0766] > <@bakkot:matrix.org> if they don't exist, then `.flat(Infinity)` is not at problem it also has no reason to exist [19:45:41.0907] `.flat` would certainly also work on iterables, like `flatMap` does? [19:45:52.0232] mpsc is "single consumer" so in most cases it is a move operation [19:46:10.0970] * mpsc is "single consumer" so in most cases it is a move operation (reuses the same memory) [19:46:20.0562] bakkot: except strings lol [19:46:32.0344] except strings, yes [19:46:35.0365] everyone agrees on that [19:46:48.0341] Why do you think it has no reason to exist? You seem to dislike infinite flat on arrays too, while I use that more than anything else, so maybe this is a mismatch in expectations? [19:46:58.0596] The issue with using module blocks is that it means the worker has no access to the struct declarations until after they are received from the originating thread, which complicates startup. [19:47:13.0041] TabAtkins: infinitely-nested arrays don't exist because you can't even construct them [19:47:16.0555] i would love if we had sharable funclets or whatever [19:47:23.0724] we can just revive domenic's proposal [19:47:32.0884] Sure. But *indefinitely* nested ones do, and that's what I mean by Infinity. [19:47:35.0357] at least you can construct an infinitely-nested iterator, even if you could never iterate it [19:47:45.0049] sure you can construct them. `const a = []; a.push(a)` [19:47:54.0460] lol indeed [19:48:15.0221] people do *that* a bunch, actually, with objects too, which is why there's npm packages to handle describing or serializing them [19:48:30.0626] blöcks [19:48:31.0820] > <@rbuckton:matrix.org> The issue with using module blocks is that it means the worker has no access to the struct declarations until after they are received from the originating thread, which complicates startup. the DX for that order is terrible. If I want to use a `Point` in a module in my worker, I can't import it. I have to receive the constructor as an argument. [19:48:35.0130] (but nobody would be iterating over those, i expect) [19:48:39.0709] yeah blöcks [19:48:49.0190] How does source location work with eval? [19:49:01.0149] source location won't work [19:49:03.0092] that has to change [19:49:03.0989] > <@waldemarh:matrix.org> How does source location work with eval? It breaks [19:49:06.0817] otherwise you can't use bundlers [19:49:10.0543] > <@waldemarh:matrix.org> How does source location work with eval? it does not I believe [19:49:40.0827] but eval has a inferred address right? like "vm:123" [19:49:50.0956] that is also some kind of source text identity [19:50:14.0497] And calling `.flat(Infinity)` on that array just stack overflows immediately. That's fine. [19:50:21.0581] Every `eval` call generates a new source location [19:50:26.0803] As if they were different files [19:50:27.0812] Regarding the source location thing, I had also been working on a mechanism that didn't depend on source location, but a correlation step on the worker thread to do setup to associate a foreign struct with a local prototype. The downside to this approach is that it results in multiple "maps" that affect ICs and require fixup. [19:50:54.0831] > people do that a bunch name them; they do not deserve anonymity [19:50:57.0343] the easiest would just be requiring the registration to use a very qualified name [19:51:10.0175] the DOM [19:51:13.0149] like `struct Foo registered "snek.library.Foo" {}` [19:51:15.0030] * the DOM, for objects :-p [19:51:19.0620] com.google.workspace.sheets.myStruct [19:51:27.0459] puttin the java in javascript [19:51:32.0469] * like `struct Foo registered "dev.snek.library.Foo" {}` [19:51:34.0369] > <@nicolo-ribaudo:matrix.org> Every `eval` call generates a new source location So the correlation from the presentation won't work with eval'd code. [19:51:36.0068] > <@devsnek:matrix.org> the easiest would just be requiring the registration to use a very qualified name We have also considered that. I suggested it as a mechanism to address the bundling issue. [19:51:37.0696] yeah, exactly like symbols [19:51:48.0888] > <@rbuckton:matrix.org> We have also considered that. I suggested it as a mechanism to address the bundling issue. The problem is that it's potentially forgeable [19:51:57.0573] why is that text red? 🤔 [19:52:04.0065] > <@rbuckton:matrix.org> We have also considered that. I suggested it as a mechanism to address the bundling issue. yeah if you have main_thread.js and worker_thread.js, its kind of required i think [19:52:10.0397] since those are different source texts [19:52:12.0881] > <@devsnek:matrix.org> yeah, exactly like symbols There's a difference. You don't define anything about a symbol except the description. [19:52:36.0770] ye the ultimate key in the agent would be the name + the shape [19:52:59.0358] > <@devsnek:matrix.org> yeah if you have main_thread.js and worker_thread.js, its kind of required i think Not necessarily, many bundlers support splitting out common code shared between different entrypoints. [19:53:41.0088] > <@devsnek:matrix.org> ye the ultimate key in the agent would be the name + the shape That's interesting. [19:54:03.0166] I'm not sure if its still not forgeable and thus usable as a communications channel. [19:54:24.0851] it probably contains one of your mention words [19:54:36.0500] > <@waldemarh:matrix.org> So the correlation from the presentation won't work with eval'd code. Yes, it wouldn't [19:54:52.0216] > <@waldemarh:matrix.org> So the correlation from the presentation won't work with eval'd code. * Exactlt, it wouldn't [19:54:57.0039] yeah that's another thing, if you use fast dev mode (eval) your project will break lol [19:54:58.0506] * Exactly, it wouldn't [19:55:13.0421] The mechanism I'd been investigating was to correlate struct types between a worker and main thread: https://gist.github.com/rbuckton/08d020fc80da308ad3a1991384d4ff62 [19:55:33.0145] > <@devsnek:matrix.org> yeah that's another thing, if you use fast dev mode (eval) your project will break lol Well in webpack all those eval calls happen just once per file right? So it's ok if they have their own source location [19:55:50.0476] > <@devsnek:matrix.org> we can just revive domenic's proposal how did that solve any of the problems we're discussing here? [19:56:12.0025] > <@littledan:matrix.org> how did that solve any of the problems we're discussing here? it solves sharable functions, not other things [19:56:17.0986] > <@littledan:matrix.org> how did that solve any of the problems we're discussing here? * it solves sharable code, not other things [19:56:42.0785] > <@devsnek:matrix.org> it solves sharable code, not other things Isn't that proposal essentially what module expressions/module blocks is? [19:56:50.0884] it is quite similar yes [19:56:54.0573] hmmm I have zero keywords [19:56:59.0283] > <@rbuckton:matrix.org> Isn't that proposal essentially what module expressions/module blocks is? yeah that plus closing over things and structured cloning them [19:57:06.0198] i think both could exist [19:57:07.0104] It also didn't solve the shared code issue with respect to the developer experience. [19:57:18.0307] the main thing is whether you are sharing a module or a callable [19:57:30.0673] i think callables are a lot nicer to work with in many cases [19:57:38.0495] this could be my bias from working with erlang/elixir though [19:59:18.0854] I agree that `f()` is much better than `await import(mod).then(m => m.f())`, and module expressions are only a viable solution if "prototype calls" don't look like that [19:59:35.0534] (specifically, I wouldn't want a`await`) [19:59:51.0191] yeah i can definitely see both existing [20:03:46.0761] ah this is my jam [20:09:32.0418] > <@devsnek:matrix.org> mpsc is "single consumer" so in most cases it is a move operation (reuses the same memory) Then that is essentially what I'm already doing. I parse the file in a thread pool thread, which produces a shared AST node that I send back to the main thread. If I had used normal objects sent via `postMessage`, I'd end up producing an entire copy of the AST in the main thread while the worker ends up holding on to the local copy until some point in the future when GC runs, which increases memory pressure and triggers GC more often, and that's would be a huge problem in some very large codebases (it already is, to a degree, so that would just makle it worse). [20:14:04.0010] But since I can't attach behavior to a struct, I still end up having to rebuild the AST as normal objects to hand off to the rest of the compiler. Unfortunately, rewriting the entire compiler just to use a data-only AST isn't something feasible in the time I've spent on it so far. And the TSC compiler is mostly written using the FP style. There are too many bits of code that still expect to be able to call `.map`, `.filter`, etc. on a `NodeArray` that wouldn't otherwise be present in a data-only world. And it's not just arrays. We regularly use `Map` and `Set` as well. [20:17:04.0686] Switching back to a purely functional approach even for working with arrays is not a reasonable ask, as there is far too much to reasonably change, and would have an oversized impact on TypeScript API consumers. Maybe we pay the cost to speed up `tsc` command line compilation, but API consumers wouldn't get that benefit. [20:17:20.0804] hmm.. ok, when I view source, I'm in the mentions block: ``` "m.new_content": { "body": "the DOM, for objects :-p", "format": "org.matrix.custom.html", "formatted_body": "the DOM, for objects :-p", "m.mentions": { "user_ids": [ "@softwarechris:matrix.org" ] }, ``` [20:21:21.0771] i understand what tsc wants to do i just explicitly don't consider it when thinking about how things should be designed, as it is a very "special" codebase. [20:21:49.0073] Just using `f(data)` glosses over the fact that `f` isn't going to be that short in the majority of cases. I have too many places where I've had to write something like `concurrentMap_set(map, key, value)` when it could have been `map.set(key, value)`. I'd much rather we not turn JS into C to use this feature. [20:22:02.0792] like i'd rather have microsoft toil over rewriting tsc than make the design of a feature work [20:22:09.0946] * like i'd rather have microsoft toil over rewriting tsc than make the design of a feature worse [20:22:36.0795] it is subjective of course [20:22:44.0484] I would consider the inability to attach behavior to a struct a worse outcome, especially because I believe that are reasonable ways to achieve this. [20:23:24.0114] i'm cool with attaching behavior to structs, i just don't like the unshared prototype or whatever its called [20:23:37.0294] What about that is problematic? [20:23:49.0595] the aesthetics [20:24:20.0449] Do you mean the `with nonshared prototype;`? That's nowhere near final syntax. [20:25:09.0918] That comes from trying to require explicit opt-in for some things so that we leave room for the potential for _actual_ shared code in the future, and not paint ourselves into a corner. [20:25:33.0696] no not the syntax, i'd rather just skip to having actual shared code [20:26:03.0801] We haven't found a workable solution for that. [20:26:46.0126] JS is not threadsafe, and the way functions work today makes them not threadsafe either. [20:28:24.0947] ye i'm aware of the history there, i was around for blocks and such. i just want to spend more brainpower on that instead of the temporary solution [20:28:48.0378] Neither that proposal nor module expressions are actually shared code. [20:29:07.0586] They are essentially just shared source text. [20:29:27.0431] i'm not sure what you mean by shared code then [20:30:08.0690] If you are talking about just having the same method declarations evaluated in two threads, that's exactly what was being proposed. [20:30:17.0776] i am not talking about that [20:31:00.0709] in v8 terminology i'm thinking of something like bytecode being shared between isolates [20:31:03.0057] If you're talking about the main thread sending the declaration to the child thread, that ends up being a terrible developer experience. [20:31:21.0040] bytecode for the function? [20:31:31.0486] for some given source text [20:31:51.0478] it could also include closed over references [20:32:16.0045] maybe another example would be functions in erlang/elixir, though its hard to say exactly what "closed over" means there because everything is COW [20:32:39.0947] I'm not sure how feasible that would be. If you're just talking about untyped, unoptimized code, maybe, but not optimized representations or every deopt and recompile would stop the world. [20:32:54.0595] And if its just untyped, unoptimized code, that could be achieved with what was discussed as well. [20:33:02.0193] yeah i mean its possible it might have to split apart [20:33:16.0366] these are sort of the two states though [20:34:41.0531] like you write `let add = magicCodeContainerSyntax(a, b){a + b}` and you expect that sending add to other threads and using it is generally a very cheap operation as long as you don't do anything too weird [20:35:56.0774] What was presented was having a single `shared struct` declaration that was addressable by source location, in which case v8 or another engine could leverage the statically known shape of the declaration to generate the same hidden class for a struct in multiple threads. It could potentially even generate shared function information for all of the methods, and let each thread refine those on a per-thread basis. [20:36:53.0357] yeah that sounds like a reasonable application [20:38:21.0839] This has issues with bundling and tree shaking, which I've talked about with shu and others in #shared-structs:matrix.org, though there is an argument to be made that bundlers could work around this by splitting out structs into a separate file reused by multiple entrypoints, which is something many bundlers can already do. [20:39:03.0340] yeah the addressing needs to be... addressed [20:39:08.0826] but the overall concept is sound i think [20:39:16.0345] both in terms of theory and in terms of implementation [20:40:01.0356] My concern with trying to use something like module blocks to encapsulate shared code in the main thread and send it to the worker is that it becomes difficult to use in the worker. You can't just `import` your declarations now, you have to receive them as arguments if you want to create new instances of a struct type to send back to the main thread. That wouldn't work for TypeScript, we have too many different AST nodes. [20:40:32.0926] So I would prefer a DX that allows me to use `import`. [20:41:17.0183] this is similar to elixir. you can send `fn() -> MyModule.foo() end` to another process (or even another physical computer) but that doesn't mean `MyModule` is properly imported for you to use it there. [20:41:44.0836] Have people run into issues with bunders duplicating declarations of classes with private fields? [20:42:18.0080] the issue with bundlers is.... say you have shared_util.js that is imported by both main_thread.js and worker_thread.js [20:42:35.0191] if shared_util is bundled into those two other files, it will have a different source location for each one [20:42:39.0344] which will break the struct addressing [20:42:51.0997] you can leave it split out to fix that [20:43:00.0148] though i'm not personally a fan of that [20:43:07.0911] There is also an argument to be made that I *don't* want to share bytecode between functions in different threads. One of the biggest issues with worker threads today is that you must essentially duplicate large portions of your application code in memory in the worker. One solution to that would be to use tree shaking to remove unused code, but now anything used by a shared struct method cannot be dropped so I have to pay the cost for unused code. [20:44:45.0595] not sure i'm following what you're saying there [20:46:36.0431] anything duplicated in main_thread.js and worker_thread.js results in that much additional memory taken up by the worker, as it constructs its own copies of every function and object as it evaluates the duplicate code. [20:47:23.0502] i feel like you're saying you want things to be shared but then saying that you don't want things to be shared [20:47:47.0874] If main_thread.js and worker_thread.js both depend on shared_util.js, but each only uses part of that file, tree shaking would elide the unused functionality to remove overhead per-thread. [20:48:23.0881] oh i see, you're saying you don't want the pointer from shared_util to the shared bytecode to hang around if you're not using it [20:48:41.0948] yeah definitely something worth thinking about [20:48:57.0246] That is at odds with what shu presented, and what we've discussed, but is also something I've been considering with the various alternatives we've been working through. [20:49:09.0625] if addressing is not based on source location i think that "just works" with tree shaking [20:49:29.0030] I mean, the downside of this all is polymorphic usage sites, right? [20:49:33.0719] It does not make your code crash [20:50:30.0694] i think the worst case is that the engine has to make a full copy for each thread of whatever the backing representation is (which is just the status quo today) [20:50:42.0821] > <@danielrosenwasser:matrix.org> I mean, the downside of this all is polymorphic usage sites, right? Yes, the version of the proposal presented today was heavily motivated by reducing polymorphism, but that is at the cost of the potential for increased overhead since tree-shaking becomes limited. [20:52:03.0535] I've suggested a registration mechanism that would be bundler/tree-shaking friendly, but it imposes other limitations to avoid side-channel communication issues related to a shared registry that are also a concern. [20:52:04.0338] So just bundle split? [20:52:20.0603] > <@danielrosenwasser:matrix.org> So just bundle split? that is what was presented, yes. [20:52:22.0969] this all feels like non-problems [20:53:03.0858] bundle split can be problematic in some cases based on network conditions [20:53:25.0637] as much as we wish everything was http2+ everywhere [20:53:40.0951] its definitely not *that* bad [20:53:55.0973] but creating a worker off of a separate `.js` file isn't? [20:54:57.0608] i more just don't like that the feature strongly informs how code can be processed. [20:55:03.0119] > <@danielrosenwasser:matrix.org> this all feels like non-problems that's my feeling too? [20:55:08.0333] One way to overcome the bundling issue is with a lexical keyword to introduce a shared identity, i.e.: ``` shared struct S { with registration 'e9c1cfb0-e9d6-469c-8fba-99f641e4b64e'; ... } ``` [20:55:25.0158] Or a URN, or whatever you like. [20:55:25.0535] yeah that's what i suggested above, except my example was more human-readable lol [20:56:13.0579] We'd discussed it being an API, or just a decorator as well. The problem with an API or a decorator is that it provides a way to communicate between otherwise isolated code. [20:56:46.0935] i'm curious what that communication channel is [20:57:51.0912] If you have a global registry, in which you can insert a keyed element, which throws if the element already existed, then it can be used to communicate. [20:58:01.0354] oh, don't throw [20:58:09.0705] How do you catch developer mistakes? [20:58:40.0819] like if you write out the same definition in two separate files? [20:58:45.0277] and then they fall out of sync? [20:58:50.0714] `"use strict"` was partly about not silently allowing things that didn't work. [20:58:53.0764] i would consider you to be on your own at that point lol [20:59:46.0165] I'm personally fine with not throwing, but that's also because I work on a type system that could warn you ahead of time about that kind of conflict. [21:00:07.0551] yeah i mean i don't think that's an inherently new problem to structs [21:00:33.0759] we have solutions for it [21:00:37.0742] orthogonal imo [21:03:35.0611] So as not to continue to flood the chat about the `shared struct` proposal, I'd suggest anyone who is interested in discussing further join #shared-structs:matrix.org or one of the working session meetings in the TC39 calendar. [21:04:20.0709] please do! [21:05:10.0521] Type Annotations community call minutes are here: https://github.com/tc39/proposal-type-annotations/issues/184 [21:07:07.0530] (Specifically [the link to the Google Doc](https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit?usp=sharing)) [21:10:09.0939] i like token soup [21:12:10.0797] would be nice to see a future proposal which allows getting the token soup in some way, probably just as a string [21:13:57.0828] when I was skimming the slides before, I assumed "token soup" was intended as an insulting phrase 😅 [21:14:42.0484] like maybe like a Perl-y thing [21:15:38.0739] what if we made this proposal console-only [21:15:46.0734] there was a discussion about having a REPL goal [21:15:50.0681] lmao [21:15:52.0060] chrome could just strip TS types in the console [21:15:54.0321] * (like a Perl-y sort of image) [21:16:00.0515] I would like that better... [21:16:03.0019] i like repl goal [21:17:03.0284] > <@bakkot:matrix.org> chrome could just strip TS types in the console I said the same when it went stage 1 [21:18:06.0887] repl goal needs - sloppy by default - supports redeclarable static import - supports redeclarable let/const - supports type stripping - top level await [21:18:10.0204] * repl goal needs - sloppy by default - supports redeclarable static import - supports redeclarable let/const - supports type stripping - top level await - ??? [21:18:27.0364] gentle reminder, please add yourself to the attendee list at the top of the notes if you have not done so. thank you 🙏 [21:18:58.0856] > <@devsnek:matrix.org> repl goal needs > > - sloppy by default > - supports redeclarable static import > - supports redeclarable let/const > - supports type stripping > - top level await > - ??? annex J: Repl tool modification of the 262 [21:19:03.0556] a repl goal that ignores types would be very interesting, and avoids many of the downsides of the current annotations proposal [21:19:11.0324] I do not understand the analogy to JSON at all [21:19:37.0363] i feel very undecided about this [21:19:47.0766] i want reflective type annotations so i can write cool things [21:20:01.0736] which champions just said is out of scope [21:20:05.0497] You don't want to send extra bytes for JSON comments over the wire, but it sure would be nice if you had them for configuration readability [21:20:06.0232] the reflection part [21:20:09.0179] I think this proposal will impede any reflective type annotations [21:20:15.0836] agreed [21:20:27.0009] i feel like it could come later as like "get the annotation strings" [21:20:40.0703] > <@danielrosenwasser:matrix.org> You don't want to send extra bytes for JSON comments over the wire, but it sure would be nice if you had them for configuration readability right, but MLS's point was that TS is _only_ useful if you have another tool. that's not true of comments in JSON. [21:20:41.0937] but i also feel like it could make trying to rely on that more hazardous if things are used to stripping them out [21:20:45.0773] i... don't think i can ship that [21:20:47.0969] > <@danielrosenwasser:matrix.org> You don't want to send extra bytes for JSON comments over the wire, but it sure would be nice if you had them for configuration readability * right, but MLS's point was that TS is _only_ useful if you have another tool (which can then do the stripping). that's not true of comments in JSON. [21:21:31.0661] msaboff: total strawman, but could your concern be mitigated by also standardizing the semantics of these type annotations, even if JS engines do not enforce these? [21:21:33.0338] have people who are talking about the convenience of not having to strip types used esbuild's watch mode [21:21:35.0177] it is so fast [21:21:38.0364] you literally do not notice [21:22:17.0506] > <@shuyuguo:matrix.org> i... don't think i can ship that i think it would be fine with lazy re-parsing? but i can imagine it would be annoying [21:22:40.0420] we have different definitions of "fine" i think [21:22:45.0633] it is implementable with re-parsing [21:22:55.0920] ok but this proposal does not move to a world where tooling is optional [21:22:58.0325] like, at all [21:23:02.0709] i mean v8 already has a reparser for errors, its just a question of how fast do you want your annotations [21:23:03.0388] > <@lucacasonato:matrix.org> msaboff: total strawman, but could your concern be mitigated by also standardizing the semantics of these type annotations, even if JS engines do not enforce these? No. There is nothing I see an implementation using TA's. [21:23:04.0357] types do nothing for you without additional tools [21:23:06.0491] that is the whole proposal [21:23:17.0742] let's have annex J developer mode to contain all of those things [21:23:20.0755] bakkot: perhaps you should express that on the queue [21:23:23.0491] * re: littledan's comment, ok but this proposal does not move to a world where tooling is optional [21:23:26.0692] the queue is so full [21:23:40.0483] i think it would be valuable to demonstrate that there are skeptics who are not just implementers [21:23:48.0039] > <@bakkot:matrix.org> the queue is so full There is a 60 minute timebox. [21:23:50.0019] bleh [21:23:51.0465] ok [21:25:56.0188] (I do have concerns with the current syntax proposal, and think it needs to be more generic/soupy rather than invasive into the grammar, but it's still absolutely the case that *some* syntax that's valid (and erased) at runtime is useful.) [21:26:12.0359] > <@msaboff:matrix.org> No. There is nothing I see an implementation using TA's. I don't understand what you mean. I am not suggesting runtime implementations of ECMA262 do anything other with TA's than strip them. But we could standardize how tooling itself is meant to interpret the grammar and perform the type checking (so there would be type checking implementations such as TypeScript, and runtime implementations such as JSC / V8 / SM) [21:27:08.0254] The impact is quite high, if we follow this route, we are effectively defining the grammar for types for JavaScript once and for all. [21:27:35.0212] i mean if we have token soup we aren't defining any grammar for types [21:27:38.0847] other than `:` [21:27:46.0935] > <@christianulbrich:matrix.org> The impact is quite high, if we follow this route, we are effectively defining the grammar for types for JavaScript once and for all. which is a pretty permanent thing to do when there isn't even a type system existing that can accurately describe the entire language. [21:27:49.0249] I think I've gotten a bit confused here as to whether this information is meant to be used _statically_ by engines [21:27:58.0984] > <@devsnek:matrix.org> i mean if we have token soup we aren't defining any grammar for types well, assuming we also don't have `interface` and etc... [21:28:02.0159] and `type` [21:28:05.0019] > <@lucacasonato:matrix.org> I don't understand what you mean. I am not suggesting runtime implementations of ECMA262 do anything other with TA's than strip them. But we could standardize how tooling itself is meant to interpret the grammar and perform the type checking (so there would be type checking implementations such as TypeScript, and runtime implementations such as JSC / V8 / SM) So what do you expect an implementation doing with TA's besides throwing them away. [21:28:07.0267] and all the other TS keywords [21:28:14.0876] > <@lucacasonato:matrix.org> I don't understand what you mean. I am not suggesting runtime implementations of ECMA262 do anything other with TA's than strip them. But we could standardize how tooling itself is meant to interpret the grammar and perform the type checking (so there would be type checking implementations such as TypeScript, and runtime implementations such as JSC / V8 / SM) * So what do you expect an implementation doing with TA's besides throwing them away? [21:28:19.0362] but of course if we don't have all the other TS keywords, it does not accomplish the goal of letting people ship TS at runtime [21:28:21.0593] because I thought the answer was an obvious "yes" but maybe it's actually "no" and we're just demarcating a section to be ignored by an engine's parser? [21:28:27.0396] > <@msaboff:matrix.org> So what do you expect an implementation doing with TA's besides throwing them away? That *is* the expectation, yes. [21:28:31.0092] > <@msaboff:matrix.org> So what do you expect an implementation doing with TA's besides throwing them away? A runtime implementation should do nothing other than to throw them away. [21:28:51.0454] > <@ljharb:matrix.org> which is a pretty permanent thing to do when there isn't even a type system existing that can accurately describe the entire language. I am with you, I have the same feeling, that finding a type system, that can actually define all of JavaScript's types might be difficult. Although there surely would be some kind of `any` wouldn't it? :) [21:29:01.0254] > <@lucacasonato:matrix.org> A runtime implementation should do nothing other than to throw them away. So I think you agree with the comment I made that started this thread. [21:29:05.0953] > <@rkirsling:matrix.org> because I thought the answer was an obvious "yes" but maybe it's actually "no" and we're just demarcating a section to be ignored by an engine's parser? it's the second thing definitely [21:29:13.0436] engines cannot use TS types for several reasons [21:29:32.0864] > <@christianulbrich:matrix.org> I am with you, I have the same feeling, that finding a type system, that can actually define all of JavaScript's types might be difficult. Although there surely would be some kind of `any` wouldn't it? :) nope, but `unknown`, yes. maybe there is no such system, but until there is, why would we want to lock ourselves in [21:30:03.0282] > <@bakkot:matrix.org> it's the second thing definitely that at least clarifies for me why "token soup" is meant as a neutral-sentiment phrase [21:33:25.0693] ok I also want to know the answer to WH's question though [21:33:30.0954] > <@msaboff:matrix.org> So I think you agree with the comment I made that started this thread. Ok, let me rephrase the original strawman then: - You do not like that a specific tool or set of tools is picked as the "blessed" syntax, I assume (please tell me if I am wrong) because we (TC39) as the body standardising the grammar, do not have control over how tools interpret this syntax, effectively delegating a large amount of syntax semantics to a different body (TypeScript / flow / whoever we "bless") - I am suggesting this may be mitigated by moving the semantics that a static checker should interpret the syntax with into the scope of TC39, possibly into ECMA262. This way TC39 keeps this control - Runtime implementations of ECMA262 will totally ignore these type annotations. The semantics, if we define them, would only be enforced by other ahead of time static analysis tools [21:33:44.0860] _is_ the goal that in 10 years every TS user will write only the subset of TS which is legal ES? [21:34:11.0870] I suppose that's up to TS and its users, but probably yes. [21:34:46.0921] I don't understand what you mean, shu. [21:34:49.0077] > <@bakkot:matrix.org> _is_ the goal that in 10 years every TS user will write only the subset of TS which is legal ES? JSX: [21:35:04.0569] yeah JSX seems like that makes it obviously not-gonna-happen [21:35:18.0035] TabAtkins: maybe i misread what bakkot said, let me re-read [21:35:29.0005] Python's type syntax is also (a) completely meaningless/erased at runtime, and (b) different tools use different type syntaxes for their purposes, and (c) they all stick within the broad constraints of valid Python annotations, tho. [21:35:35.0967] shu: sorry, there was an implicit "in ten years, assuming we do this proposal as standard ES" [21:35:38.0881] Don't see why that doesn't apply just as well to JS. [21:35:40.0946] TabAtkins: ha indeed i did, i read "10 years every" as "every 10 years" [21:35:48.0470] ahaha [21:35:59.0067] > <@lucacasonato:matrix.org> Ok, let me rephrase the original strawman then: > > - You do not like that a specific tool or set of tools is picked as the "blessed" syntax, I assume (please tell me if I am wrong) because we (TC39) as the body standardising the grammar, do not have control over how tools interpret this syntax, effectively delegating a large amount of syntax semantics to a different body (TypeScript / flow / whoever we "bless") > - I am suggesting this may be mitigated by moving the semantics that a static checker should interpret the syntax with into the scope of TC39, possibly into ECMA262. This way TC39 keeps this control > - Runtime implementations of ECMA262 will totally ignore these type annotations. The semantics, if we define them, would only be enforced by other ahead of time static analysis tools Luca, I was only making the last point in my comment here. I do have other concerns related to the first two points you list. [21:36:43.0694] I, for example, *almost certainly would not* use typed Python if I had to run a build step that produced my actual Python files. The fact that my code is runtime-valid is important. [21:37:07.0358] that seems empirically just not borne out by the vast majority of JS authors [21:37:08.0943] (JS devs appear to have way more appetite for build pain that I do, on average. But still.) [21:37:12.0379] like, everyone uses toolchains [21:37:30.0460] this proposal is predicated on the assumption that you are using a toolchain!!! [21:37:32.0299] and, as kevin said, this proposal itself presupposes you already use TS [21:37:42.0209] > <@msaboff:matrix.org> Luca, I was only making the last point in my comment here. > I do have other concerns related to the first two points you list. Ok, thank you - I'd be interested to learn more about your reasoning for not liking that a specific tool or set of tools is picked as the "blessed" syntax, as that may help find alternative solutions [21:37:56.0773] That you use a toolchain *for production*. Not that you use a toolchain *to make your code run at all*, necessarily. [21:38:06.0285] let me be frank [21:38:09.0386] you do typechecks at devtime [21:38:15.0838] all of the benefit of typechecks is at devtime [21:38:18.0697] Like I said, it's the same as minifying being a good thing to do *for production*, but we don't require you to write minified code to execute locally. [21:38:22.0079] > <@bakkot:matrix.org> you do typechecks at devtime No, you have your editor do this [21:38:32.0822] that is a tool [21:38:33.0326] You do not run `tsc` during dev mode [21:38:33.0463] that [21:38:34.0565] you are using [21:38:36.0714] at devtime [21:38:41.0782] this proposal is asking for engines to ship everything, to everyone, all the time, for a thing that is purportedly not done in production, on the promise that users will also manually strip stuff away at production [21:38:43.0653] you should definitely be running tsc in CI before you merge in code [21:38:48.0704] what's in it for me? why would i support this? [21:38:52.0738] > <@lucacasonato:matrix.org> Ok, thank you - I'd be interested to learn more about your reasoning for not liking that a specific tool or set of tools is picked as the "blessed" syntax, as that may help find alternative solutions I don't like that TC39, an open standard, is blessing possibly one syntax when there are several other possible syntax options. [21:38:56.0895] i.e., if Type Annotations advances to Stage 3/4, TypeScript would also adopt `f::()` for type argument lists. We likely would not ban `f()` in a .ts file, but imagine the community would migrate to the new syntax just as they did for `as` when we added it to avoid conflicts with JSX. [21:38:57.0641] Yes, I do typechecks at devtime. But typechecking is different than executing. Being able to execute my code directly, and then typecheck at some convenient point, is nice. [21:39:10.0744] all other things being equal, i agree it is nice [21:39:13.0427] there are real costs here [21:39:57.0127] Right now on the Babel codebase we use ESLint to lint, TSC to type-check, Babel to strip away types, and Rollup to bundle. ESLint and TSC are run transaprently by my editor and on CI, Rollup only happens on CI, and the only step between me writing the code and testing it in Node.js is to compile away types [21:40:01.0928] > <@msaboff:matrix.org> I don't like that TC39, an open standard, is blessing possibly one syntax when there are several other possible syntax options. Ok, thank you - but isn't this something we always do when adding new syntax? We bless one syntax that we decide aligns best with the needs of the ecosystem and the direction we want to take the language? How is this syntax specifically different? [21:40:21.0137] no, we usually invent new syntax from whole cloth [21:40:27.0770] > <@nicolo-ribaudo:matrix.org> Right now on the Babel codebase we use ESLint to lint, TSC to type-check, Babel to strip away types, and Rollup to bundle. > > ESLint and TSC are run transaprently by my editor and on CI, Rollup only happens on CI, and the only step between me writing the code and testing it in Node.js is to compile away types node can strip types? but also, `esbuild --watch` is like [21:40:30.0846] we look at prior art, but not literally pick existing syntax [21:40:32.0473] not a big burden, given that existing stack [21:40:38.0353] * node could choose to strip types? but also, `esbuild --watch` is like [21:40:49.0988] > <@bakkot:matrix.org> node could choose to strip types? but also, `esbuild --watch` is like Well, browsers can strip types too [21:40:53.0057] wait that was just "token soup" as a negative phrase [21:41:03.0006] * wait that was just "token soup" as a negative phrase from Eemeli just now [21:41:04.0101] > <@nicolo-ribaudo:matrix.org> Well, browsers can strip types too by slowing down parsing for **everyone** [21:41:33.0841] > <@shuyuguo:matrix.org> by slowing down parsing for **everyone** Would it also slow down parsing for code not using type annotations? [21:41:43.0291] yes! [21:41:48.0516] shu: Yeah, I think the final syntax needs to be something super cheap to parse. The current proposal isn't it imo. [21:41:52.0874] > <@nicolo-ribaudo:matrix.org> Would it also slow down parsing for code not using type annotations? Likely YES [21:42:16.0827] *especially* likely if there's cover grammar-like shenanigans involved [21:42:23.0572] yup [21:42:42.0990] > <@shuyuguo:matrix.org> we look at prior art, but not literally pick existing syntax Well but that is what we are doing here too? We don't literally pick TS syntax, we pick syntax that is similar to TypeScript to ease migration (we did this before with decorators), but ultimately it's a subset that is easier to parse and unambiguous. I don't see this as standardising TypeScript, I see this as standardising a syntax space for types that looks similar to TypeScript (inspiration), because it's what folks in the ecosystem are familiar with [21:42:43.0957] The advantage of "token soup" is that typed languages can continue to innovate within that space without requiring advancing a proposal through TC39 for what is otherwise just a comment. [21:42:44.0663] I wonder if there is some perf goal we could aim at. Such as "no cover grammar needed unless there is a token clearly introducing a type context" [21:42:59.0561] the slow part of the annotations is single-char stepping. the slow part of the not-annotations is the other weird complexity layered on top. [21:43:01.0098] > <@rbuckton:matrix.org> The advantage of "token soup" is that typed languages can continue to innovate within that space without requiring advancing a proposal through TC39 for what is otherwise just a comment. but it would not let them do stuff like `satisfies`, etc [21:43:06.0696] TS introduces new keywords... pretty often [21:43:16.0732] > <@rbuckton:matrix.org> The advantage of "token soup" is that typed languages can continue to innovate within that space without requiring advancing a proposal through TC39 for what is otherwise just a comment. there are very few things in this space that wouldn't benefit from going through tc39 [21:43:40.0303] > <@nicolo-ribaudo:matrix.org> I wonder if there is some perf goal we could aim at. Such as "no cover grammar needed unless there is a token clearly introducing a type context" Or if we managed to entirely avoid new cover grammars, so that the check is just "is the enxt token a `::<`/`:`?" [21:43:42.0895] > <@nicolo-ribaudo:matrix.org> I wonder if there is some perf goal we could aim at. Such as "no cover grammar needed unless there is a token clearly introducing a type context" i think that assumes that you've already convinced engines that it's worthwhile to add *anything* here, and i think we are not yet convinced. at least not myself and michael [21:43:45.0401] > <@nicolo-ribaudo:matrix.org> I wonder if there is some perf goal we could aim at. Such as "no cover grammar needed unless there is a token clearly introducing a type context" * Or if we managed to entirely avoid new cover grammars, so that the check is just "is the next token a `::<`/`:`?" [21:44:16.0244] > <@bakkot:matrix.org> but it would not let them do stuff like `satisfies`, etc True, but I think that's an acceptable tradeoff. [21:45:02.0605] though to be clear i do not share msaboff's concerns about picking winners as strongly [21:46:07.0832] i think where i am ending up here is that if we can't get any runtime benefit here, runtimes shouldn't deal with this, and it shouldn't move forward [21:46:24.0476] and its pretty clear at this point that there will be no runtime benefit [21:46:28.0693] I just think there's a lot of terribly misleading verbiage surrounding "runtime" and erasure [21:46:52.0138] every engine has a parser for early errors [21:47:19.0848] "runtime benefit" in my sentence is anything from engines using the type annotations to make code faster to simple string reflection [21:47:42.0180] if you just read this presentation you would think that engines will be using this information statically and _then_ throw it away at runtime [21:48:27.0085] and if that's impossible (which it seems like it is?) then this seems just bad...? [21:49:03.0879] Again, these arguments generally would argue against Python's type annotations as well. [21:49:04.0516] but mostly I'm just concerned about how confused I've felt. [21:49:13.0790] Make sure you actually *mean* for your counterargument to be that strong. [21:49:21.0526] > <@tabatkins:matrix.org> Again, these arguments generally would argue against Python's type annotations as well. python type annotations are reflectable [21:49:32.0702] and this property is used to huge advantage in the ecosystem [21:49:36.0280] > <@devsnek:matrix.org> "runtime benefit" in my sentence is anything from engines using the type annotations to make code faster to simple string reflection So what should an implementation do if the type is violated while processing? Throw? [21:49:36.0679] Mehhhhh the reflection barely matters if at all. [21:49:38.0906] also python is categorically different than JS [21:50:05.0269] * also python is categorically different than JS, because The Web [21:50:09.0500] > <@ljharb:matrix.org> there are very few things in this space that wouldn't benefit from going through tc39 Zooming out (and ignoring the specifics of soup vs concrete grammar), one of the whole motivations of this proposal is to ensure coordination of real-life type syntax with tc39. By default, if we do nothing type syntax will iterate outside tc39 which brings coordination risk. [21:50:11.0099] mypy doesn't execute python and inspect the reflection, it parses itself [21:50:19.0066] > <@msaboff:matrix.org> So what should an implementation do if the type is violated while processing? Throw? i don't think implementations should try to do it. i'm just saying, if everything we can possibly imagine is off the table, then i don't think its worth it [21:50:23.0907] Python also isn't shipped to me over the network every time I want to run it? [21:50:45.0161] sure, i run a build step on my python when i ship a new version to pypi [21:50:45.0659] > <@michaelficarra:matrix.org> Python also isn't shipped to me over the network every time I want to run it? one would hope [21:50:57.0042] just wait [21:53:52.0523] > <@tabatkins:matrix.org> Mehhhhh the reflection barely matters if at all. there are several major libraries that make use of it. some of them are for dependency injection, which i find distasteful, but its still a thing. there are other cool examples like discord.py which uses annotations to build string parsing. i'm talking about packages with hundreds of thousands of downloads per day *minimum* here. [21:54:47.0327] ok sure, annotations for non-type-checking reasons i guess. I've never used these *because* i use the annotations for types instead. [21:54:56.0607] (you can only do one or the other, I believe) [21:55:06.0945] yeah i agree there [21:56:26.0030] to be clear, I don't claim that there are _zero_ projects which are both complex and would benefit from this [21:56:43.0585] > <@rbuckton:matrix.org> The advantage of "token soup" is that typed languages can continue to innovate within that space without requiring advancing a proposal through TC39 for what is otherwise just a comment. As I showed in the presentation earlier in the year, that doesn't actually work. For example, you can't even do something as trivial as using existing ECMAScript expression syntax to calculate a constant inside a token soup. [21:56:53.0610] so, is it really impossible to bring JSX into the language? [21:57:32.0969] i think one of the main challenges is how you can lexically indicate what the syntax is equivalent to - ie `React.createElement`, `h`, etc [21:58:07.0886] otherwise it'd just need to be hardcoded to make an object literal of some kind [21:58:16.0919] yeah it would have to be pojo [21:58:22.0026] > <@ljharb:matrix.org> i think one of the main challenges is how you can lexically indicate what the syntax is equivalent to - ie `React.createElement`, `h`, etc of course our own representation and ui library comes to support us [21:58:41.0346] > <@devsnek:matrix.org> yeah it would have to be pojo or curried [21:58:59.0547] `(

hi

)(h)` [21:59:51.0644] is bloomberg going to get rid of tools? [22:00:20.0535] run code in the void [22:00:46.0434] i got bad news for you if you think JS is directly executed by the metal [22:00:50.0208] one of the stated goals tho is "unfork the ecosystem"; "unfork" means 0 fork, not "less forked" [22:01:04.0221] "spork the ecosystem" doesn't have the same ring to it [22:01:04.0262] ljharb: this is actually a *new* fork! [22:01:16.0120] critical fork [22:01:25.0334] > <@shuyuguo:matrix.org> i got bad news for you if you think JS is directly executed by the metal even the array accesses? 🥺 /s [22:01:42.0185] *especially* the array accesses [22:01:55.0074] 👉️🥺👈️ [22:02:06.0111] is that you putting your fingers in your ears [22:02:15.0727] it can be that too [22:02:17.0269] no i wanted to make that meme where the fingers are together [22:02:24.0679] lol [22:02:25.0852] dunno how to make that on one line [22:02:32.0206] A+ reference [22:02:34.0296] > <@ljharb:matrix.org> one of the stated goals tho is "unfork the ecosystem"; "unfork" means 0 fork, not "less forked" let's bring JSX in! [22:02:42.0321] > <@devsnek:matrix.org> is bloomberg going to get rid of tools? I hope not or I'll be out of a job. [22:02:49.0852] danielrosenwasser: we're very interested in more devtools collaboration with TypeScript :) [22:02:50.0311] i am a little bit disappointed that we didn't get to discuss topics around in-browser devtools more [22:03:10.0532] > <@danielrosenwasser:matrix.org> i am a little bit disappointed that we didn't get to discuss topics around in-browser devtools more i remain of the opinion the most highly impactful thing is that, exactly [22:03:12.0470] That was something that flew by the queue a few times [22:03:14.0894] not changing the standard [22:03:28.0830] Then I'd love to talk about that too [22:03:39.0937] the coolest thing about devtools changes is that you can just pr them [22:03:42.0381] (i say that as a non-devtools representative) [22:03:45.0517] you don't need plenary approval [22:04:15.0239] > <@shuyuguo:matrix.org> (i say that as a non-devtools representative) but i have talked with them about it! [22:04:57.0170] bradley and i talking to v8 about devtools improvements in node is where the "repl goal" stuff came from [22:05:09.0055] it goes full circle [22:05:11.0678] so let me try to summarize my thoughts: - I agree there is would be some benefit for at least some projects, including both beginners and complex projects - I am not convinced that in fact most people will be able to skip the build step: this proposal does not cover all of TS as-is, and _definitely_ won't cover JSX - and this proposal will constrain the growth of TS, e.g. no new `satisfies`-like keywords, which TS has wanted to add lots of historically - the thing where you want to copy-paste code from your editor to the browser console is very real, but could be solved just in the browser console - the grammar in this proposal is massive, which will be a lot of work (and runtime cost) to implement, reason about, and maintain - given all that, the costs do not seem worth the benefits, to me. [22:05:37.0344] BTW we worked on presenting the motivation in this presentation: https://onedrive.live.com/view.aspx?resid=5D3264BDC1CB4F5B!5615&authkey=!ADFHxW4BxojKreE [22:05:59.0036] I probably don't need to say it, buuuut: for the type annotations proposal, our meeting notes, including summary+conclusion get referenced quite a lot, so we should collectively take extra care to clean them up, ensure accuracy, etc [22:06:37.0631] also like, "runtime" as a count noun is one of the worst words our industry has ever devised [22:06:44.0527] > <@devsnek:matrix.org> bradley and i talking to v8 about devtools improvements in node is where the "repl goal" stuff came from right, I still hope we can get back around to the repl goal proposal... [22:07:07.0342] and it's disappointing that people seem to be imagining that we'd never have alignment at that level [22:07:38.0237] yeah i think we can define some minimum behavior pretty easily. just need people who want to spend time on it [22:07:47.0656] ....and also have time to spend on it [22:08:33.0424] > <@bakkot:matrix.org> so let me try to summarize my thoughts: > > - I agree there is would be some benefit for at least some projects, including both beginners and complex projects > - I am not convinced that in fact most people will be able to skip the build step: this proposal does not cover all of TS as-is, and _definitely_ won't cover JSX > - and this proposal will constrain the growth of TS, e.g. no new `satisfies`-like keywords, which TS has wanted to add lots of historically > - the thing where you want to copy-paste code from your editor to the browser console is very real, but could be solved just in the browser console > - the grammar in this proposal is massive, which will be a lot of work (and runtime cost) to implement, reason about, and maintain > > - given all that, the costs do not seem worth the benefits, to me. this captures my main concerns [22:09:21.0084] yeah same [22:09:38.0782] * yeah same, modulo reflection [22:12:16.0696] Why don't we just define a binary AST and require all code to be compiled to that? [22:12:26.0389] lol [22:12:57.0671] i'd like that [22:13:11.0726] are you saying that'd be a bad world [22:13:29.0915] did facebook give up on binast [22:13:35.0199] i haven't heard anything about it in years [22:13:43.0684] Wasn't there already an attempt to propose a binary AST? [22:13:51.0259] yes, that was me [22:14:05.0828] https://github.com/tc39/proposal-binary-ast [22:14:27.0903] Some people were against it 😉 [22:14:59.0803] what if the binast was s expressions, and it had 4 primitive types and a small memory buffer, and used a harvard architecture... [22:15:58.0394] > <@devsnek:matrix.org> what if the binast was s expressions, and it had 4 primitive types and a small memory buffer, and used a harvard architecture... What if we got rid of dynamic types [22:16:17.0879] The moment I used Decimal seriously, the first thing I'd do is write a template function that just does numeric parsing. [22:16:53.0826] My point is if we expect all code authored to go through some tool, just go all the way and make the output of that tool something completely different than what was authored. I believe all proposals around that have never considered making that a requirement. Aka that if the author wrote valid JavaScript, it can still be executed as is [22:16:57.0678] decmath`${price} + ${tax}` [22:16:58.0928] > and this proposal will constrain the growth of TS, e.g. no new satisfies-like keywords, which TS has wanted to add lots of historically This part is definitely on the champions' radar. One path, at least at first, is that TS could add `satisfies` without it becoming JS, just they would initially have a worse developer experience (working only in .ts and not in .js) until a version of that feature (possibly with tweaked syntax) got added to JS grammar. But hopefully we can figure out how to reserve a larger space of grammar such that new features can fit into it. We haven't figured out what that space should be yet, though. [22:16:59.0744] we should just have primitive decimals, this makes no sense [22:17:22.0929] > <@tabatkins:matrix.org> decmath`${price} + ${tax}` it would get a lot of downloads [22:17:39.0000] no sense at all [22:17:49.0460] > <@michaelficarra:matrix.org> we should just have primitive decimals, this makes no sense This is something we can discuss in more detail if we get around to "operator overloading withdrawal"; let's focus on other parts of this presentation for now. [22:18:17.0518] it's pretty important to focus on this part now, i think [22:18:20.0835] > <@nicolo-ribaudo:matrix.org> What if we got rid of dynamic types Then we would have ES262. [22:19:00.0412] > <@ljharb:matrix.org> it's pretty important to focus on this part now, i think well, this isn't going for advancement... I agree it's an important topic but I wanted to give space for other people to give their presentations. [22:19:03.0109] > <@nicolo-ribaudo:matrix.org> What if we got rid of dynamic types * Then we wouldn't have ES262. [22:19:15.0934] Lots of the stuff in this presentation is just orthogonal from whether it's a primitive [22:19:30.0311] my sense is that that stuff is irrelevant if it's not a primitive. [22:19:39.0888] > <@msaboff:matrix.org> Then we wouldn't have ES262. (it was more fun before editing, because the ES262 _spec_ is statically typed 😛) [22:19:42.0080] yes and lots of it doesn't matter at all if nobody is going to use it because it's so unergonomic [22:20:15.0306] > <@nicolo-ribaudo:matrix.org> (it was more fun before editing, because the ES262 _spec_ is statically typed 😛) Happy to make you laugh. [22:20:44.0177] IIRC there are still concerns about using IEEE 754 at all [22:21:04.0467] IEEE-754 Decimal128 is the obviously correct choice here [22:21:13.0185] > <@softwarechris:matrix.org> IIRC there are still concerns about using IEEE 754 at all yeah, this is an example of something interesting to discuss which isn't about whether it's a primitive [22:21:31.0079] /me points to the sign: https://speleotrove.com/decimal/decifaq4.html#signif [22:21:46.0073] > <@tabatkins:matrix.org> The moment I used Decimal seriously, the first thing I'd do is write a template function that just does numeric parsing. ``D`1``` [22:21:50.0579] if its not a primitive is there any benefit to it existing in the language itself [22:22:01.0203] that's my queue item [22:22:01.0246] just perf optimization? [22:22:03.0436] > <@tabatkins:matrix.org> The moment I used Decimal seriously, the first thing I'd do is write a template function that just does numeric parsing. * ``D\`1\``` [22:22:06.0747] > <@bakkot:matrix.org> so let me try to summarize my thoughts: > > - I agree there is would be some benefit for at least some projects, including both beginners and complex projects > - I am not convinced that in fact most people will be able to skip the build step: this proposal does not cover all of TS as-is, and _definitely_ won't cover JSX > - and this proposal will constrain the growth of TS, e.g. no new `satisfies`-like keywords, which TS has wanted to add lots of historically > - the thing where you want to copy-paste code from your editor to the browser console is very real, but could be solved just in the browser console > - the grammar in this proposal is massive, which will be a lot of work (and runtime cost) to implement, reason about, and maintain > > - given all that, the costs do not seem worth the benefits, to me. also, it has been my experience that many of the reported problems with "having to compile typescript" are actually different problems than "I have to run another tool". they're things like "I want to dual-emit CJS and ESM" or "the module resolution in my version of typescript is different from in node" or "module interop is broken" or things like that. and to the extent that this proposal helps those problems, it does so only because it forces you to make TS's resolution-and-etc match your other tools. but that is a tooling problem, not a fundamental problem with having a strip-types step in your build process, and TS has lately been making some improvements in that area already [22:22:10.0039] * D`1` [22:22:11.0668] (Matrix does not correctly handle multi-ticks, don't even bother trying.) [22:22:21.0987] TabAtkins: ``` `yes it does` ``` [22:22:24.0889] like i think performance can be a valid reason [22:22:28.0929] even if its not a primitive [22:22:33.0510] but i'd wanna see very very good performance [22:22:34.0877] * TabAtkins: ```yes it does``` but you may have to "hold it correctly" tbf [22:22:45.0312] * TabAtkins: ``` `yes it does` ``` but you may have to "hold it correctly" tbf [22:22:55.0451] correctness is the main reason (but i agree that ergonomics is p important) [22:23:07.0285] so I worry that a lot of people are experience "compiling with typescript is painful" and assuming that types-as-comments will fix their problems, when those are in fact different problems [22:23:22.0735] Like the "lossless division with fixed precision" isn't trivial to write yourself. [22:23:34.0172] luckily there's packages that implement it already [22:23:36.0436] * luckily there's packages that implement it already, right [22:23:37.0348] * luckily there's packages that implement it already, right? [22:23:51.0749] it would have perf footguns though, like I'd have to do manual interning to avoid repeated string parsing snek [22:24:00.0429] To the best of my knowledge, not really. [22:24:01.0101] > <@bakkot:matrix.org> so I worry that a lot of people are experience "compiling with typescript is painful" and assuming that types-as-comments will fix their problems, when those are in fact different problems has this been a common refrain? [22:24:27.0862] "compiling with typescript is painful" is common, definitely [22:24:49.0421] and upon investigating that turning out to be down to moduleResolution differences or CJS/ESM or whatever is also common IME [22:24:51.0048] I mean the idea that types as comments is the panacea [22:24:51.0650] Me as the poor guy, writing software, I do not care about performance, but about having something, that is so often needed, simply being built into the language, so I do not have to rely on third-party implementations. I think that is also the reason, way everyone is waiting for Temporal. [22:24:55.0224] I will say, even if we didn't get operator overloading, a literal syntax would be *super* helpful without invoking perf issues. [22:25:02.0277] * I mean the idea that types annotations is the panacea [22:25:14.0797] Christian Ulbrich: YES. More batteries included please. [22:25:22.0617] temporal is about dates/times tho, not *numbers* [22:25:39.0578] `Decimal("1.2")` is so obnoxious vs `1.2n` [22:25:46.0430] * `Decimal("1.2")` is so obnoxious vs `1.2m` [22:25:52.0817] > <@softwarechris:matrix.org> I mean the idea that types annotations is the panacea ah, I don't know for sure. I _expect_ that many of the random developers who are excited about the proposal are excited because they think it will fix their problems, but their problems are in fact other things like ESM or whatever.. [22:26:09.0909] `1.2m` is pretty motivating i think [22:28:02.0446] ljharb: Temporal is about giving JS proper date handling. There are other libraries out there, that at least could do theoretically the same, yet we do Temporal. [22:28:06.0819] > <@tabatkins:matrix.org> `Decimal("1.2")` is so obnoxious vs `1.2m` you forgot `new`, it's `new Decimal("1.2")` [22:28:23.0117] How do you feel about syntax for decimals but not primitives? Like regexs [22:28:30.0635] Jack Works: I mean, it doesn't *need* to be. We *can* define it to not require the `new`. ^_^ [22:28:53.0491] > <@nicolo-ribaudo:matrix.org> How do you feel about syntax for decimals but not primitives? Like regexs `1.2m !== 1.2m` will trip everyone up forever [22:29:01.0808] While I *really want* operator overloading, I'd accept it without. And ignoring that, I don't care about primitive vs object. [22:29:02.0974] regexps you don't do arithmetic / comparisons / etc on [22:29:06.0764] > <@tabatkins:matrix.org> Jack Works: I mean, it doesn't *need* to be. We *can* define it to not require the `new`. ^_^ I want to keep the no `new` version for primitives. browsers don't want it for now, but I want to keep the hope [22:29:26.0559] > <@bakkot:matrix.org> `1.2m !== 1.2m` will trip everyone up forever for the same reason, I also require `1.2m` not a thing before primitive happens [22:30:56.0563] if we have primitives in the future, what we have today becomes boxed primitive, and it will not create a breaking change [22:31:19.0254] `1.2m !== 1.2m` clearly just make `valueOf` throw, can't do it then. [22:31:24.0964] because temporal pulls in like 70mb of data [22:31:27.0959] like we don't have number, but `new Number('1').add(new Number('2'))` [22:31:52.0545] > <@tabatkins:matrix.org> `1.2m !== 1.2m` clearly just make `valueOf` throw, can't do it then. `!==` does not use `valueOf`, thank goodness [22:32:00.0288] gosh dang it [22:32:15.0435] > <@tabatkins:matrix.org> `1.2m !== 1.2m` clearly just make `valueOf` throw, can't do it then. a previously throwing code no longer throws is not a breaking change in tc39 IMO [22:32:29.0187] Right! [22:32:59.0055] I was just half-jokingly saying that having the equality test throw would avoid people accidentally relying on it being always-false. [22:33:49.0277] my brother are you asking me to add a typeswitch to === for certain types and to add a *throw* [22:33:55.0417] * my brother are you asking me to add a typeswitch to === for certain object types and to add a _throw_ [22:33:58.0291] > <@tabatkins:matrix.org> I was just half-jokingly saying that having the equality test throw would avoid people accidentally relying on it being always-false. Making `===` throw has the same perf impact as making it work properly: you have in both cases exactly one more branch [22:34:09.0379] is this proposing that we would use d128 [22:34:22.0532] d128 vs bigdec is still an open question [22:34:23.0257] (`new Number(1) === new Number(1)` also false today so I'm very optimistic that Decimal can add boxed primitive first then if the engine see it is widely used they can add primitives later) [22:34:45.0409] > <@nicolo-ribaudo:matrix.org> Making `===` throw has the same perf impact as making it work properly: you have in both cases exactly one more branch it's actually worse I think - throwing operators are special, can't be optimized the same as non-throwing operations [22:35:02.0843] `===` must never, ever throw [22:35:19.0017] IE 8 or 9 did that on one thing and it's very very bad [22:35:29.0561] Ah, if it's cheaper to just do the comparison right then that's easy, ship is shu [22:35:37.0260] * Ah, if it's cheaper to just do the comparison right then that's easy, ship it shu [22:35:41.0798] throwing doesn't really make surrounding code slower anymore. there are certainly some weird cases but in general everyone is on the unwinding train these days i think [22:35:41.0926] * `===` must never, ever throw, that's a hill i will gladly die on [22:35:55.0268] they constrain optimizability [22:36:06.0215] anyone questioning Decimal128, *please* read https://speleotrove.com/decimal/decifaq4.html#signif [22:36:14.0252] you can't DCE stuff that might throw as easily [22:36:22.0426] consider https://en.cppreference.com/w/cpp/language/noexcept_spec [22:36:25.0615] (or do other analysis) [22:36:48.0928] > <@rkirsling:matrix.org> consider https://en.cppreference.com/w/cpp/language/noexcept_spec how is noexcept in C++ be enforced? [22:36:58.0777] panic [22:36:59.0543] ? [22:37:03.0083] noexcept is enforced because unwinding is part of the spec [22:37:12.0819] oh [22:37:18.0153] if a noexcept method throws, it panics the whole program [22:37:19.0785] `window.onerror = () => window.close()` [22:37:24.0681] :D [22:37:40.0193] sick [22:37:56.0728] `window.onerror = () => ud2` [22:37:59.0415] this is the kind of performance trick i would like to subscribe to in a newsletter [22:38:59.0172] > <@bakkot:matrix.org> ah, I don't know for sure. I _expect_ that many of the random developers who are excited about the proposal are excited because they think it will fix their problems, but their problems are in fact other things like ESM or whatever.. Our problem is none of that. It's simply that writing JSDoc is terrible DX, but for our case is still preferable to dealing with generated code. And from what I've seen, we're not the only project with that experience. [22:39:18.0813] I agree that at least some projects would in fact benefit, yes [22:39:41.0326] I certainly do not claim that _all_ of the random developers who are excited about the proposal in fact have a different problem [22:39:48.0650] just that I expect many of them do [22:39:52.0296] try ts-node, ts-node can configured to skip type checking and even use swc for transpile [22:40:39.0007] i should poll at my company about this type annotation thing [22:40:58.0802] i don't think i've ever had the stated problem [22:41:05.0487] pasting typescript into devtools or whatever [22:41:10.0570] or maybe i'm so used to it i don't notice [22:41:17.0393] ts-node has a repl [22:41:41.0058] I agree, the correctness win here is the higher-order bit [22:41:56.0711] we did just switch to rspack, so tool time is definitely a thing some people are thinking about [22:42:28.0192] * we did just switch to rspack this morning, so tool time is definitely a thing some people are thinking about [22:43:57.0467] > <@jackworks:matrix.org> try ts-node, ts-node can configured to skip type checking and even use swc for transpile Not all our code runs on node ;) there are other JS engines and environments! [22:44:01.0556] littledan: please don't jump the queue like that [22:44:04.0564] tschromium [22:45:56.0965] > <@mhofman:matrix.org> Not all our code runs on node ;) there are other JS engines and environments! which other ones can't transpile TS on the fly? [22:46:03.0114] > <@mhofman:matrix.org> Not all our code runs on node ;) there are other JS engines and environments! * which other ones can't be made to transpile TS on the fly somehow? [22:46:18.0449] sffc: PLEASE, I beg you, read https://speleotrove.com/decimal/decifaq4.html#signif [22:46:23.0265] Also saying use deno and tsnode is basically making the argument that the expected DX is for the JS environment to strip / ignore types. I'm just asking for that behavior to be standardized [22:46:43.0791] that's only expected DX tho *in a repl* [22:46:53.0937] * that's only widely expected DX tho _in a repl_ [22:47:04.0807] No those environments are used to run production code [22:50:51.0643] dminor: did adding bigint slow down every JS program? [22:51:01.0390] > <@mhofman:matrix.org> Also saying use deno and tsnode is basically making the argument that the expected DX is for the JS environment to strip / ignore types. I'm just asking for that behavior to be standardized so I think a big disconnect here is the purported benefit is node users, but the cost is imposed on browser vendors and users of webpages [22:51:11.0758] > <@michaelficarra:matrix.org> sffc: PLEASE, I beg you, read https://speleotrove.com/decimal/decifaq4.html#signif Trailing zeros are important as part of the representation / interchange format. `new Decimal("1.0").toLocaleString()` and `new Intl.PluralRules().select(new Decimal("1.0"))` should just work. I don't have a position regarding the impact on arithmetic of these values. [22:51:12.0619] and node can at least make breaking changes, sometimes, like typescript does [22:51:16.0597] (imo the reason bigint doesn't get used is because it doesn't interop with Number, which is a mistake Decimal needn't repeat) [22:51:16.0761] so it's just a very... very different space [22:51:21.0467] * (imo the reason bigint doesn't get used is because it doesn't interop cleanly with Number, which is a mistake Decimal needn't repeat) [22:52:19.0074] > <@ljharb:matrix.org> (imo the reason bigint doesn't get used is because it doesn't interop cleanly with Number, which is a mistake Decimal needn't repeat) Decimal would need to repeat that [22:52:30.0428] sffc: So you're expecting that `new Decimal("1.0")` and `new Decimal("1.0000")` would produce the same results when participating in any arithmetic expression? [22:52:30.0905] decimal interoperating with number would be insane [22:52:54.0977] why? [22:53:03.0435] number → decimal at least, even if not the other way [22:53:13.0590] 1.3 + 1.3m === ? [22:53:19.0286] there is no sensible answer to that question [22:53:26.0205] 2.6m? [22:53:35.0463] > <@ljharb:matrix.org> number → decimal at least, even if not the other way Either Number -> Decimal or Decimal -> Number are inexact. [22:53:41.0472] * 2.6m? or whatever number 1.3 actually is, converted to decimal, added to 1.3m [22:53:41.0793] > <@ljharb:matrix.org> 2.6m? yeah that's impossible [22:53:45.0106] which is why they can't interop [22:54:21.0982] (might be possible in simple cases, not possible in general) [22:54:22.0825] the implicit conversion would have to go number -> mathematical value -> decimal [22:54:35.0495] > <@ljharb:matrix.org> dminor: did adding bigint slow down every JS program? Adding a new primitive meanings adding a new branch for dynamic dispatch based upon type, so it will slow things down, I can't say whether it was a measurable difference for BigInt or not, but adding a primitive has the potential to slow down existing programs, not just things that use the new primitive. [22:54:36.0212] > <@michaelficarra:matrix.org> sffc: So you're expecting that `new Decimal("1.0")` and `new Decimal("1.0000")` would produce the same results when participating in any arithmetic expression? That's not something I said. I assume that spec authors who have gone into the weeds have defined what happens with trailing zeros when arithmetic is performed. The Temporal champions went into the weeds on similar types of problems in datetime arithmetic. All I'm saying is that `new Decimal("1")` and `new Decimal("1.0")` are absolutely distinct values for the purposes of internationalization and therefore from the Intl point of view it is important that the distinction be retained. [22:54:44.0508] so we've got 1) they're not primitives and operators don't Just Work, 2) it can't be made reasonable to interop with Number… i'm having a lot of trouble understanding the remaining value [22:55:06.0159] sffc: then you don't want decimal [22:55:06.0671] no use case of decimal known to me calls for them to inteorp with Number [22:55:07.0961] > <@dminor:mozilla.org> Adding a new primitive meanings adding a new branch for dynamic dispatch based upon type, so it will slow things down, I can't say whether it was a measurable difference for BigInt or not, but adding a primitive has the potential to slow down existing programs, not just things that use the new primitive. sure. but this concern wasn't brought up for BigInt, so how is Decimal any different? [22:55:13.0304] so I don't know why interop with Number would matter [22:55:34.0310] > <@ljharb:matrix.org> sure. but this concern wasn't brought up for BigInt, so how is Decimal any different? Because we learned from the experience of implementing BigInt :) [22:55:36.0925] > <@usharma:igalia.com> the implicit conversion would have to go number -> mathematical value -> decimal How would you represent the intermediate mathematical value? [22:55:49.0343] ljharb: perf improvement is still possibly significant [22:56:05.0237] > <@ljharb:matrix.org> 2.6m? or whatever number 1.3 actually is, converted to decimal, added to 1.3m 2.60000000000000004... [22:56:06.0632] within an engine? we have a way to represent mathematical values in the spec [22:56:16.0969] are you...kidding [22:56:19.0815] > <@devsnek:matrix.org> 2.60000000000000004... fine with me, as long as i can round decimals :-) [22:56:22.0793] Well BigInt, and looking at implementing records and tuples [22:56:26.0199] you think we have a way to represent, in memory, mathematical reals? [22:56:30.0113] > <@devsnek:matrix.org> 2.60000000000000004... * fine with me, as long as i can round/ceil/floor decimals :-) [22:56:41.0327] like, as intermediate values? [22:57:13.0967] we definitely use mathematical values all over the spec [22:57:22.0987] (potentially TDZ): I suggested trading `undefined` _primitive_ for `Decimal` one. I guess no one will notice! [22:57:28.0026] I assume there's something corresponding to that within engines [22:57:34.0305] > <@usharma:igalia.com> we definitely use mathematical values all over the spec because we don't want to accidentally spec error accumulation in our internal arithmetic [22:57:41.0297] > <@usharma:igalia.com> I assume there's something corresponding to that within engines nope [22:57:44.0365] it just does IEEE arithmetic [22:57:49.0377] ryzokuken: they're a fiction [22:57:50.0768] and IEEE arithmetic corresponds to the right thing [22:57:55.0291] say 1/3rd to scare a js engine implementor [22:57:57.0628] welp, nvm then [22:58:08.0367] the use of reals in the spec is just a way to not write down IEEE semantics in the spec [22:58:14.0028] ps those occasional groups in the kitchen are quite loud, is there a polite way to address that? [22:58:21.0294] re: string.prototype.decimalAdd() this sounds like coloring strings in some way? especially for typescript, you'd have to have some sort of colored string to make this not suck [22:58:38.0118] Luca Casonato: phantom types! [22:58:45.0371] > <@usharma:igalia.com> within an engine? we have a way to represent mathematical values in the spec What would be the proposed representation of such an intermediate mathematical value. Number and Decimal have different significant digits and exponent ranges. Number is inexact for decimal values. If we had such an exact mathematical value, we'd use that for Number. [22:58:59.0022] `String` [22:59:16.0111] We could color them by wrapping then in an object as a "marker" [22:59:33.0177] > <@nicolo-ribaudo:matrix.org> We could color them by wrapping then in an object as a "marker" `new Decimal(str)`~ [22:59:35.0406] > <@nicolo-ribaudo:matrix.org> We could color them by wrapping then in an object as a "marker" * `new Decimal(str)`! [22:59:36.0140] > <@lucacasonato:matrix.org> re: string.prototype.decimalAdd() > > this sounds like coloring strings in some way? especially for typescript, you'd have to have some sort of colored string to make this not suck if this proposal means TS makes it easier to color strings, I'm all for it! [22:59:57.0623] > <@usharma:igalia.com> within an engine? we have a way to represent mathematical values in the spec * What would be the proposed representation of such an intermediate mathematical value? Number and Decimal have different significant digits and exponent ranges. Number is inexact for decimal values. If we had such an exact mathematical value, we'd use that for Number. [23:00:01.0842] > <@msaboff:matrix.org> What would be the proposed representation of such an intermediate mathematical value? Number and Decimal have different significant digits and exponent ranges. Number is inexact for decimal values. If we had such an exact mathematical value, we'd use that for Number. right. Sorry I was mistaken in assuming that engines might have some way to represent mathematical values within the spec but I now realize that they're pure fiction 😕 [23:00:06.0169] hell yeah love mauve strings [23:00:09.0532] > <@bakkot:matrix.org> if this proposal means TS makes it easier to color strings, I'm all for it! actually yeah me too :D [23:00:19.0849] > <@bakkot:matrix.org> if this proposal means TS makes it easier to color strings, I'm all for it! `'a'.blink()` color strings? [23:00:38.0845] if you store it as a fraction of bigints and reduce after each step you get something that is both horribly slow and semantically bad [23:00:46.0541] > <@bakkot:matrix.org> so I think a big disconnect here is the purported benefit is node users, but the cost is imposed on browser vendors and users of webpages Our programs should be able to run on a multitude of environments, including browsers and non node/deno based "server" environments. That's the benefit of standardizing this in the language. [23:01:37.0911] > <@mhofman:matrix.org> Our programs should be able to run on a multitude of environments, including browsers and non node/deno based "server" environments. That's the benefit of standardizing this in the language. I agree that is a benefit. I do not think the costs are commensurate with the benefits. [23:02:19.0229] I think that, in this case, having a variant of node which strips TS types has fewer costs in general, even though it does have that one additional cost. [23:02:32.0951] not least of which that it would allow breaking changes ever [23:02:39.0255] and JSX, and so on [23:03:03.0090] but also, more significantly, that it would not impose costs on users of webpages [23:03:16.0790] (by making parsing JS slower/more expensive) [23:06:02.0819] I'll go back to my argument, why do browsers not ask that code they execute be in the form of binary AST. [23:06:20.0747] * I'll go back to my argument, why do browsers not require that code they execute be in the form of binary AST. [23:07:05.0909] how could they? [23:08:10.0240] if thats a hypothetical it requires too many "suppose"s for me to comprehend [23:09:37.0434] is this a serious question [23:09:42.0319] I'm just trying to understand exactly how important the tradeoff between parsing performance and readability of executed code is [23:09:43.0222] I'd love it if browsers could accept a binary AST format. I'm sure it would be much faster to execute. [23:09:47.0398] cuz there can be serious answers [23:10:32.0134] and it could serve as a standard interchange format to move code from one environment to another whose source was different [23:10:40.0831] like if we could cut off legacy and restart from the ground up would js even exist? probably not... wasm is significantly better [23:11:02.0633] And if there is actually a large cost to parsing if the type annotations are not present in the executed code. [23:12:12.0777] Or if there are other avenues we could explore to mitigate the impact of engines being able to parse and ignore type annotations [23:12:32.0437] In production scenarios where performance matters [23:20:31.0639] > <@mhofman:matrix.org> I'll go back to my argument, why do browsers not require that code they execute be in the form of binary AST. we almost certainly would if the option existed [23:20:34.0426] that would be a better world [23:20:38.0906] but the option does not exist [23:20:51.0899] however, do note that when adding a _new_ thing, wasm, we _do_ require it to be compiled rather than accepting WAT [23:21:05.0425] snek: How do you version a BinaryAST? Many proposals add new node to an implementation's AST. How do you handle where the spec needs the source of an expression, e.g. RegExp or a stack trace? There are many more issues. [23:21:43.0004] recall that we went with binary ast as an option because we thought bytecode would be DOA [23:21:55.0139] binary ast is a worse option than bytecode in every way for shipping compiled code [23:21:59.0999] (not for tools, obviously) [23:22:21.0377] perhaps with wasm and the lessons there maybe we can think harder about a bytecode again [23:22:41.0760] if you go through and try to answer every question here you eventually end up at wasm or something similar to wasm... the point of *everything* is that we have an existing ecosystem here [23:23:07.0202] why would i end up at wasm? i'm talking about a JS bytecode that has 1:1 expressivity with source JS [23:23:32.0261] i mean mathieu's and msaboff's questions [23:23:36.0975] ah [23:23:52.0370] can we advance the queue [23:23:58.0664] But Wasm has issues as well. Dev tooling, HTML interop, standard library... [23:23:59.0857] > <@msaboff:matrix.org> snek: How do you version a BinaryAST? Many proposals add new node to an implementation's AST. How do you handle where the spec needs the source of an expression, e.g. RegExp or a stack trace? There are many more issues. i'd assume with semver [23:24:10.0071] > <@msaboff:matrix.org> snek: How do you version a BinaryAST? Many proposals add new node to an implementation's AST. How do you handle where the spec needs the source of an expression, e.g. RegExp or a stack trace? There are many more issues. * i'd assume with semver, but maybe i'm missing something [23:24:10.0283] why does that ping me lol [23:24:29.0437] because element [23:25:22.0711] anyway the reason i mentioned it was because wasm adds new bytecode ops without versioning at all (wasm is still on version 0x1 mvp). it just takes some time to plan everything out. [23:25:37.0170] * anyway the reason i mentioned it was because wasm adds new bytecode ops without versioning at all (wasm is still on version 0x1 "mvp"). it just takes some time to plan everything out. [23:26:18.0363] Is it different from JS adding new syntax? [23:26:40.0463] at a theoretical level no it is not [23:26:49.0673] but humans find it easier to namespace words than numbers [23:27:00.0168] * but humans find it easier to namespace words and symbols than numbers [23:28:58.0019] > <@devsnek:matrix.org> i mean mathieu's and msaboff's questions No I don't think compiling js programs to wasm makes sense. But instead of minifying and to allow making uncompiled JavaScript more useful, I would entertain an efficient source transform of JS that can be efficiently parsed by engines. [23:29:19.0560] i fail to see how "an infinite iterator of empty tuples" is a logical option but k [23:29:43.0427] > <@ljharb:matrix.org> i fail to see how "an infinite iterator of empty tuples" is a logical option but k I guess that'd have to be the tail of everything if it's what would happen for zero things [23:29:46.0001] it would be empty [23:29:46.0595] not all that useful... [23:30:39.0453] producing an infinite iterator anywhere seems pretty harmful to me [23:30:59.0970] network streams are infinite iterators [23:31:07.0380] * network streams are infinite async iterators [23:31:12.0259] I think the current version of Wasm lacks some of what is needed to cleanly compile JS to Wasm. Its Turing complete, but not optimal. Also you'd need to include your own garbage collector, etc. [23:31:27.0939] you should not compile js to wasm [23:32:38.0624] Yeah, I prefer `Iterator.zip([...], mapper?)` (omitted mapping just produces an array of the items) [23:33:03.0518] i got distracted, why does zip have a mapper [23:33:12.0031] snek: it's a combiner [23:33:14.0298] zipWith [23:33:16.0021] i don't like the idea of being forced to wrap multiple iterators in an iterator just to zip them [23:33:25.0708] I mean, it's a temp array [23:33:35.0859] * i don't like the idea of being forced to wrap multiple iterators in an iterator just to zip them, which is why i want varargs or an object [23:33:43.0233] yes, and forcing that imo is not a great design [23:33:47.0301] i don't understand what zipWith means, i should have paid better attention i'm sorry [23:33:52.0756] > <@ljharb:matrix.org> i don't like the idea of being forced to wrap multiple iterators in an iterator just to zip them, which is why i want varargs or an object do you also not like the idea of being forced to wrap multiple promises in an iterable just to await all of them? [23:34:07.0233] > <@devsnek:matrix.org> i don't understand what zipWith means, i should have paid better attention i'm sorry Iterator.zipWith(Math.max, a, b, c) [23:34:07.0604] > <@bakkot:matrix.org> do you also not like the idea of being forced to wrap multiple promises in an iterable just to await all of them? correct, i do not like that and do want a form that takes an object literal [23:34:30.0022] what is the difference between an object literal and an array here? [23:34:45.0000] the thing you asked for was the varargs version, which is not like an object literal [23:34:46.0210] > <@lucacasonato:matrix.org> Iterator.zipWith(Math.max, a, b, c) i don't understand what this does [23:34:49.0728] I think it's easiest to understand zip as transposing an array of arrays, fwiw. [23:34:59.0585] > <@bakkot:matrix.org> the thing you asked for was the varargs version, which is not like an object literal sure, `Promise.all(a, b, c)` would be fine too [23:35:13.0903] i am familiar with zip in other languages, i've never seen it paired with a function [23:35:14.0114] > <@tabatkins:matrix.org> I think it's easiest to understand zip as transposing an array of arrays, fwiw. nothing about that sentence reads "easy" to me ¯\\\_(ツ)_/¯ [23:35:15.0202] > <@tabatkins:matrix.org> I think it's easiest to understand zip as transposing an array of arrays, fwiw. Yeah, the variadic map thing can be called map [23:35:26.0792] (just my intuition) [23:35:27.0800] I wonder how about using methods like it1.zip(it2).zip(it3) instead of function like Rust does. [23:35:30.0600] i don't understand what the function does [23:35:44.0386] > <@devsnek:matrix.org> i don't understand what this does `Iterator.zipWith([a, b], mapper)` is the same as `Iterator.zip([a, b]).map(vs => mapper(...vs))` [23:35:57.0928] it just lets you skip making an intermediate array for results and instead immediately passes them to a function [23:36:00.0566] that's all [23:36:03.0482] > <@rhysd:matrix.org> I wonder how about using methods like it1.zip(it2).zip(it3) instead of function like Rust does. rust has this, and it is used commonly [23:36:10.0755] in this case there is no intermediate array tho, because of iterator helpers? [23:36:12.0714] > <@rhysd:matrix.org> I wonder how about using methods like it1.zip(it2).zip(it3) instead of function like Rust does. * rust has this, and it is used commonly, i think the separate func is less common tbh [23:36:16.0149] * in this case there is no intermediate array tho, because of iterator helpers? it's not like Array.from [23:36:24.0323] > <@ljharb:matrix.org> in this case there is no intermediate array tho, because of iterator helpers? it's not like Array.from there is an intermediate array? `zip` produces arrays [23:36:28.0163] an iterator of arrays [23:36:34.0499] > <@bakkot:matrix.org> it just lets you skip making an intermediate array for results and instead immediately passes them to a function got it, ty [23:36:47.0173] > <@rhysd:matrix.org> I wonder how about using methods like it1.zip(it2).zip(it3) instead of function like Rust does. .NET-based languages like C# make this available as an extension method, so it can be used both as a static method and like an instance method: https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.zip?view=net-7.0 [23:36:47.0738] > <@bakkot:matrix.org> there is an intermediate array? `zip` produces arrays ahhh right, so the mapper lets you skip that step, fair point. [23:36:55.0009] > <@bakkot:matrix.org> there is an intermediate array? `zip` produces arrays * ahhh right, so the mapper lets you skip that step, fair point. that is like Array.from then [23:36:58.0901] * ahhh right, so the mapper lets you skip that step, fair point. that is like Array.from then (in a good way) [23:37:04.0299] idk how convinced i am of zipWith existing but 🤷 [23:37:08.0782] Yup, the mapper is exactly the same reasoning as Array.from [23:37:19.0351] > <@bakkot:matrix.org> it just lets you skip making an intermediate array for results and instead immediately passes them to a function Yeah this sounds useful but is zip the right name, or map? maybe zip should just take the iterators, and not a function, and you use map if you have a function [23:37:24.0135] Could be omitted but it's a common case (in my experience, at least) [23:37:45.0328] either way as long as prototype.zip exists and does the normal thing i'm fine [23:37:54.0407] > <@littledan:matrix.org> Yeah this sounds useful but is zip the right name, or map? maybe zip should just take the iterators, and not a function, and you use map if you have a function I am fine with that outcome personally [23:37:58.0942] it is kind of wild that self-hosted JS in JSC (and presumably not just JSC) uses `var` exclusively to avoid the perf implications of TDZ [23:38:11.0826] the battle against intermediate objects is already hopelessly lost when using iterators [23:38:30.0966] so it may not be worth having a new method solely to allow you to skip some intermediate objects... [23:38:35.0460] `zip` is a useful name because its what many people reach for in many languages, as well as many existing js libraries. [23:38:51.0557] ryzokuken: can you move the queue to shu's topic? [23:39:06.0917] done [23:39:09.0755] apologies I missed it [23:39:11.0850] thanks! [23:39:13.0767] Yeah, def shouldn't be named something other than `zip` imo [23:39:20.0813] > <@bakkot:matrix.org> so it may not be worth having a new method solely to allow you to skip some intermediate objects... sure but variadic map is probably also ergonomically motivated (just it'd be a weird name for zip itself) [23:39:24.0694] (or some variant like `zipLongest` [23:39:27.0542] * (or some variant like `zipLongest`) [23:39:57.0558] or... no, it'd look weird as an iterator method... zip will just read better [23:40:05.0869] > <@littledan:matrix.org> sure but variadic map is probably also ergonomically motivated (just it'd be a weird name for zip itself) variadic map doesn't make as much sense in JS because map is a prototype method rather than being `map(fn, iter)` [23:41:09.0964] anyone know website that chrome publish their telemetry data of language features? [23:41:25.0638] https://chromestatus.com/metrics/feature/popularity [23:41:35.0713] well, not everything has a telemetry thing [23:41:41.0568] > <@devsnek:matrix.org> either way as long as prototype.zip exists and does the normal thing i'm fine would you also be OK with a static method? [23:41:50.0237] static method seems a little more natural to me... [23:42:20.0488] I think static n-iterator version, and prototype 2-iterator version, make sense together. [23:42:32.0029] as long as i can do zipping without ever running into the one that has the function [23:42:35.0211] arr1.zip(arr2, mapper) [23:42:35.0545] * as long as i can do zipping without ever running into the one that has the map arg [23:42:50.0801] and Iterator.zip([arr1, arr2, arr3], mapper) [23:42:52.0895] what if you have an iterable function object [23:43:05.0311] what about it [23:43:14.0668] that example wasn't variadic [23:43:19.0716] either of them [23:43:33.0458] i think having to write zip([a, b]) instead of zip(a, b) would be unfortunate [23:43:33.0614] yeah I'd prefer to keep this simple [23:43:45.0532] like not worth the mapper func [23:44:08.0891] I am fine without the mapper, especially since we *do* want an options bag. [23:44:09.0368] there are other options you'd want beyond the mapper function [23:44:17.0325] like "use this value to fill out the shorter one" [23:44:25.0576] Bc longest *is* necessary in my experience. [23:44:47.0445] though of course we could just have a bunch of different methods, instead of an options bag [23:44:50.0292] isn't that what we designed array holes for? [23:44:50.0442] > <@bakkot:matrix.org> like "use this value to fill out the shorter one" isn't that `zip(a, chain(b, repeat(v)))` [23:44:55.0334] you don't need an options bag for that [23:45:02.0232] only if you know which one is longer up front [23:45:02.0508] ugh tho [23:45:07.0735] also that, yes [23:45:12.0949] if you don't know which one, you can't do it with `zip` [23:45:16.0901] or like you can but it's really really hard [23:45:18.0535] fair [23:45:26.0254] things to think about i guess [23:45:45.0561] previous discussion at https://matrixlogs.bakkot.com/TC39_General/2021-09-11#L3 [23:46:47.0960] zip(a, b) and zipAdvanced([a, b], options, mapper) [23:47:32.0537] I think just making the wrapper array is better [23:47:34.0810] to match Promise.all [23:47:38.0046] `zip(a, b)` and `knit([a, b], options, mapper)` :-p [23:47:47.0286] the wrapper array is "fine" but super annoying to have to write [23:47:51.0379] velcro [23:47:54.0659] what do other languages do about this options thing? [23:47:59.0067] yeah i'm not gonna die on this hill but its unfortunate [23:48:09.0149] python has kwargs [23:48:13.0450] i wish js had kwargs [23:48:26.0254] littledan: Python just has several variant functions, with each taking extra args as necessary. [23:48:32.0829] and yeah, kwargs man [23:48:34.0769] kwargs [23:48:46.0216] in sujitech we ship es2022 to users [23:49:04.0660] if we had a variant of js [23:49:06.0537] without hoisting [23:49:15.0315] would that fix this tdz stuff [23:49:16.0103] > <@tabatkins:matrix.org> kwargs we just need real named arguments in JS, that's all [23:49:16.0806] we only this year stopped supporting IE9... [23:49:40.0834] same! [23:50:40.0023] Is @shu saying we should have stopped with ES5 😉 [23:51:22.0178] can't become unmodern if the definition of modern never changes :rollsafe: [23:57:37.0097] why does the bytecode not rewrite itself into a direct lookup once it observes that the slot is initialized [23:57:54.0614] For Bloomberg Terminal we ship ESnext (Stage 4) to users as much as possible, which is also capped by the min-support of each piece of the toolchain that needs to transform that code, because relatively modern Chromium gets embedded. [23:59:44.0784] > <@devsnek:matrix.org> why does the bytecode not rewrite itself into a direct lookup once it observes that the slot is initialized Isn't that overhead part of the problem? [00:00:02.0281] which overhead [00:00:15.0816] You're not patching one place. You're patching every place the variable is referenced. [00:00:30.0830] > <@devsnek:matrix.org> why does the bytecode not rewrite itself into a direct lookup once it observes that the slot is initialized you have a bunch of different versions of the function also [00:00:36.0250] it's not like functions only get compiled once [00:00:45.0407] And that involves GC as well [00:01:10.0649] ah yeah same underlying sfi 🥲 [00:08:19.0060] danielrosenwasser: re: "we assume the runtime will catch it" - does that mean your type analysis treats `let` and `var` differently? [00:11:02.0438] depending on transpilers to inform engines about eliding TDZ checks doesn't benefit developers not using transpilers. [00:13:30.0115] > <@bakkot:matrix.org> danielrosenwasser: re: "we assume the runtime will catch it" - does that mean your type analysis treats `let` and `var` differently? *well* I certainly thought so [00:14:28.0095] But no, we just take the optimistic path on that [00:14:49.0310] you can observe an `undefined`-initialized `var` or `let` in downlevel emit [00:15:02.0829] ok cool, that's what I thought [00:15:26.0240] it would make using `var` super annoying if it were treated differently [00:17:47.0454] interestingly v8 implements tdz checks as two separate bytecodes [00:18:06.0400] load variable and then throw reference error if loaded value is uninitialized [00:18:19.0306] the_hole [00:18:24.0267] yeah that one [00:18:26.0252] or whatever it's called [00:18:33.0515] love to have another kind of `null` [00:18:45.0504] i'm feeling like, if this was a single bytecode, it would be a single branch instruction instead of an entire bytecode clock cycle, which is significantly cheaper? [00:18:58.0877] but idk maybe i'm missing something obvious [00:19:17.0617] surely most of the cost is the branch, not the bytecode clock cycle? [00:19:23.0106] branches are expensive [00:19:49.0372] What Mark is suggesting (moving `let` above all of its uses), is exactly what we had in our codebase when we discovered this regression. [00:20:22.0037] the branch exists either way, the bytecode dispatch is a jmp+lea+maybe smth else idr [00:20:47.0914] rbuckton: you should say that out loud, mark doesn't read chat [00:21:15.0518] Mark's point is that the engines need to optimize for that, which they don't. [00:21:55.0193] So, Mark is saying "lets encourage people to rewrite their JS into something that will force engines to do TDZ checks", right? [00:22:23.0397] * So, Mark is saying "lets encourage people to rewrite their JS into something that will **not force** engines to do TDZ checks", right? [00:22:23.0947] Hold it the right way!™ [00:22:32.0531] it really sounds like "if engines never have to encounter a `let`, then `let` won't be unperformant" [00:22:45.0912] right, and also suggesting the engine do more/smarter checks than they currently do [00:22:54.0830] but of course more/smarter checks are also expensive... [00:23:06.0080] at the very least this sounds like it would take at least two passes [00:23:07.0395] I cannot imagine a developer who wants `const` being willing to rewrite it as a `let` with no assignment and a later assignment. [00:23:08.0988] I think Mark is saying "fix this one case, and depend on linters to suggest you use that case", which doesn't help for `const` since it may depend on calculations and can't be hoisted. [00:24:49.0287] Linters also generally don't do inter-procedural analysis either, so this sounds like a big ask. [00:25:11.0401] is it difficult to figure out that a variable is *not* referenced inside a closure, and also not referenced prior to the declaration? [00:25:25.0208] more like "encourage everyone, particularly transpilers, to emit code in which `let`/`const` binding references are dominated (i.e., their TDZ is empty), and encourage implementations to statically detect such dominated bindings and eliminate any corresponding runtime penalty for them" [00:25:33.0642] > <@ljharb:matrix.org> is it difficult to figure out that a variable is *not* referenced inside a closure, and also not referenced prior to the declaration? I think those are the cases that *are* optimized today. [00:25:53.0412] At least, when they are run in a hot code path such that they get optimized. [00:26:01.0148] what about if it's a function statement vs a declaration? [00:26:02.0855] As Shu said, not all code gets optimized. [00:26:06.0688] I am almost certain that gets checked literally during parsing [00:26:09.0643] like can the perf issue be avoided simply by not using function declarations [00:26:11.0823] * like can the perf issue be avoided simply by not using function declarations? [00:26:14.0493] slight correction, the closed-over bindings are generally not top-level [00:26:23.0607] * like can the perf issue be avoided simply by not using function declarations? (which many linter configs discourage anyways due to exposure to hoisting) [00:26:31.0564] they act as state intentionally captured by closures for major components [00:26:32.0742] * like can the perf issue be avoided simply by not using function declarations? (which many linter configs discourage anyways due to it adding exposure to hoisting and use-before-define) [00:27:15.0029] yeah I think this discussion is basically centered (or at least, can be centered) on code which is _not_ reaching top-tier JIT [00:27:18.0736] * I am almost certain the not-closed-over bit gets checked literally during parsing [00:27:45.0353] so like, in the example on the screen, if the function is written as an expression and not a declaration, then the resulting reorganization it would force seems like it'd avoid this perf hit? [00:27:46.0682] in the simple cases engines skip the TDZ checks even in the lowest tier [00:27:55.0630] because the simplest cases can be checked during parsing, in a single pass [00:28:07.0945] right. simple cases are fine [00:28:14.0447] if the only codebases suffering are ones that use function decls and rely on hoisting i'm much less interested in trying to address a problem [00:28:22.0598] The main reason we have this mess is that function definitions *can* hoist, even if most of them may not be used that way. If one turns a function statement into a const binding initialized with a function expression, that is known never to hoist, and thus the implementation can trivially see that it's dominated by any prior bindings in the scope. [00:28:39.0995] ^ that suggests to me another reason to avoid using declarations [00:28:43.0364] * ^ that suggests to me another reason to just avoid using declarations [00:28:59.0471] Lint rules can do that, or transpilers might be able to do that. [00:29:14.0117] this is why i asked above if adding a no-hosting mode would help. ultimately i'd like to look at a lower level investigation of this problem space from v8, assuming they've written something up somewhere [00:30:24.0290] no-hoisting means that `let x = 1; { x; let x = 2 }` sees 1? [00:30:32.0658] Unfortunately a lot of people are attached to a style which relies heavily on hoisting, so I think it is unlikely we'll convince people to move away from that [00:30:41.0630] i agree, it's very unfortunate [00:30:53.0705] > <@nicolo-ribaudo:matrix.org> no-hoisting means that `let x = 1; { x; let x = 2 }` sees 1? it's only hoisting _of function declarations_ which we're talking about I believe [00:31:06.0781] > <@nicolo-ribaudo:matrix.org> no-hoisting means that `let x = 1; { x; let x = 2 }` sees 1? no i mean a mode where you can't call functions before their declaration [00:31:14.0821] oh no, dminor, you removed your topic from the queue? [00:31:15.0131] it would also let us have good decorators [00:31:21.0471] * oh no, dminor, you removed your topic from the queue? I was gonna + 1it [00:31:22.0549] Oh ok I got confused by the previous discussion about manually hoisting let [00:31:25.0047] * oh no, dminor, you removed your topic from the queue? I was gonna +1 it [00:32:23.0618] > <@devsnek:matrix.org> it would also let us have good decorators using `const x = function(){}` also lets you have good decorators [00:32:27.0204] > <@devsnek:matrix.org> no i mean a mode where you can't call functions before their declaration Function decorators would also require a non-hoisting mechanism, even if that mechanism is "a decorated function doesn't hoist" [00:32:53.0763] where "good decorators" of course means _normal function calls_ instead of a special syntactic form for calling functions in a different way [00:33:20.0897] > <@bakkot:matrix.org> where "good decorators" of course means _normal function calls_ instead of a special syntactic form for calling functions in a different way *snek will remember this* [00:33:23.0023] shu: this sounds like a fun investigation, one way or another [00:34:08.0530] ryzokuken: advance queue? [00:34:15.0924] queue is advanced for me [00:34:23.0713] I think TCQ got stuck for me [00:34:28.0618] oh, i see the topic changed but the queue isn't empty [00:34:30.0543] > <@bakkot:matrix.org> where "good decorators" of course means _normal function calls_ instead of a special syntactic form for calling functions in a different way That would conflict with the feedback I received that function decorators had to exist for parameter decorators to advance beyond stage 1, and is the reason that parameter decorators currently only covers class methods. [00:34:31.0649] TCQ is down :-( [00:34:43.0227] > <@ljharb:matrix.org> oh, i see the topic changed but the queue isn't empty that is another weird TCQ bug [00:35:12.0312] shu: is there a doc from v8 that explores tdz at a lower level? i'd be interested in seeing analysis of the bytecode and assembly and such without profiling it myself if such a thing already exists. [00:35:15.0327] I removed myself from the queue, but I'll say it here, SpiderMonkey is cautiously interested in removing TDZ and we've started investigating the impact on our engine. [00:35:33.0077] > <@devsnek:matrix.org> why does the bytecode not rewrite itself into a direct lookup once it observes that the slot is initialized you're patching bytecode of a function that can be called multiple times? [00:35:38.0951] a closure that can be allocated multiple times? [00:35:51.0047] yeah i forgot that bytecode is shared [00:35:53.0230] > <@rbuckton:matrix.org> That would conflict with the feedback I received that function decorators had to exist for parameter decorators to advance beyond stage 1, and is the reason that parameter decorators currently only covers class methods. correct, I personally do not think there is a viable path for function decorators or parameter decorators to exist [00:36:20.0497] > <@devsnek:matrix.org> shu: is there a doc from v8 that explores tdz at a lower level? i'd be interested in seeing analysis of the bytecode and assembly and such without profiling it myself if such a thing already exists. alas no, lower level like at the cycle-counting level? [00:36:31.0167] yeah [00:37:03.0895] > <@shuyuguo:matrix.org> you're patching bytecode of a function that can be called multiple times? Uhm, if the TDZ check does not trigger the first time it will never throw [00:37:19.0311] for any particular activation of a function [00:37:28.0183] but not for subsequent activations, especially if it's a newly allocated closure [00:37:31.0070] so you can't patch the bytecode [00:37:37.0914] Oh right [00:37:50.0559] if bytecode was not shared it would work but then you'd have big memory usage [00:37:56.0592] i want to have a general gripe [00:38:09.0080] when engines complain about something, it is not before we do a lot of work to try to make it a non-problem [00:38:18.0390] i am not a fan of being told, "have you tried being smarter" [00:38:44.0436] Yep sorry [00:38:56.0551] it wasn't towards you per se [00:39:03.0713] more towards mark [00:39:08.0502] > <@bakkot:matrix.org> correct, I personally do not think there is a viable path for function decorators or parameter decorators to exist I'm not sure why parameter decorators are not viable, at least for class elements. They're extremely valuable, and we have plenty of evidence for that in the TypeScript ecosystem. [00:39:13.0147] right, that tone really surprised me [00:39:25.0765] As engineers, we mostly can't help ourselves. We see a problem and immediately think "I bet I could fix that..." [00:39:34.0976] shu: you could try complaining about things before you do such work [00:39:35.0818] > <@dminor:mozilla.org> I removed myself from the queue, but I'll say it here, SpiderMonkey is cautiously interested in removing TDZ and we've started investigating the impact on our engine. has the analysis i wrote been improved upon? [00:39:48.0508] i bet i could fix that with the "javascript load and branch if the hole" instruction [00:39:49.0029] In all fairness, one might add, that YOU, might not mean YOU, personally. :) [00:39:50.0053] > <@michaelficarra:matrix.org> shu: you could try complaining about things before you do such work but then "have you tried being smarter" would be a valid criticism! [00:40:05.0521] exactly, I've fixed it [00:40:08.0275] > <@rbuckton:matrix.org> I'm not sure why parameter decorators are not viable, at least for class elements. They're extremely valuable, and we have plenty of evidence for that in the TypeScript ecosystem. I do not think parameter-decorators-but-only-for-class-elements is an reasonable outcome, as I believe I said when they were presented [00:40:39.0449] also I do not think function decorators make sense, though it is possible I could be convinced of that [00:41:01.0148] if in addition someone believes parameter decorators cannot advance without function decorators, then there is no option which satisfies all of these constraints [00:41:01.0288] > <@bakkot:matrix.org> correct, I personally do not think there is a viable path for function decorators or parameter decorators to exist aww, I really want function decorators... they aren't viable because of hoisting? [00:41:14.0237] i get so annoyed that js doesn't have decorators on functions whenever i come back to it from python [00:41:40.0469] bakkot: Couldn't we achieve some poor woman's function composition with function decorators and isn't this, what everyone wants in lie of pipeline operator? [00:42:29.0753] We could easily have function decorators for function expressions and arrow functions, if we wanted them. [00:42:45.0464] We've always been stuck on the hoisting behavior of function declarations. [00:42:59.0084] i don't think either of those should have decorators on them :P [00:43:55.0337] any use case to decorate any kind of function applies to decorate any other kind of function. [00:44:31.0757] * surely any use case to decorate any kind of function applies to decorate any other kind of function. [00:44:39.0584] > <@devsnek:matrix.org> i don't think either of those should have decorators on them :P I'm confused by this and your previous statement, they seem to be in conflict. [00:45:08.0182] i think function declarations should have decorators. i don't think function expressions or arrow arrow functions should have decorators [00:45:08.0490] > <@devsnek:matrix.org> i don't think either of those should have decorators on them :P "You don't believe in 2,999 gods. And I don't believe in just one more" [00:45:25.0717] well maybe function expressions that are not in a variable declaration are ok [00:45:50.0888] > <@devsnek:matrix.org> i think function declarations should have decorators. i don't think function expressions or arrow arrow functions should have decorators It may be that function expressions are the _only_ way to have function decorators, unless we are willing to disable hoisting of decorated function declarations. [00:46:03.0187] yeah i'm aware [00:46:17.0256] didn't we just lightly establish that function declarations are bad because hoisting [00:46:29.0447] I would be fine with having this mean the function doesn't hoist: ```js @dec function f() {} ``` [00:46:33.0263] in this particular lens, but i actually don't think they're bad [00:46:35.0702] * didn't we just lightly establish that function declarations are bad because hoisting (altho a non-hosting function declaration sounds great!) [00:46:46.0021] i think implicit function declaration hoisting behavior is actually much better than TDZ [00:46:51.0995] implicit letrec without special syntax is great [00:46:52.0989] i am also very ok with decorators making functions not hoisted [00:47:03.0084] can i just do `@ function f() {}` to have a non-hoisting function declaration without any decorator? i'm all on board with that [00:47:07.0470] most of my code is actually written with a rule that prevents using hoisting anyway [00:47:44.0811] At one point I was considering something like this: ``` let function f() {} const function g() {} ``` [00:47:54.0893] `fn` [00:47:54.0927] i smell more tdz [00:47:57.0144] `def` [00:47:59.0720] Please no. [00:48:20.0947] PROCEDURE [00:48:31.0598] Yes, `function` is long, but `fn`, `impl`, `def` are not friendly to the reader. [00:48:48.0557] i do wish everything was just `function`. i always mix them up when switching languages [00:49:11.0255] `good function f() {}` [00:49:25.0229] `'use good;` [00:49:29.0248] * `'use good';` [00:49:51.0569] But, `let function f() {}` seemed like a good alternative to `let f = function () {}` when it came to decorators. [00:50:15.0006] `l'function f() {}` [00:50:18.0344] `@let` [00:50:25.0829] Especially since decorators expose the name of a thing, thus `let f = @dec function() {}` seems like it wouldn't get the name. [00:54:29.0149] > <@devsnek:matrix.org> i am also very ok with decorators making functions not hoisted yes, this is what I was hoping would happen. Of course, then we need to decide whether they get tdz... [00:54:57.0706] i'll let shu decide [00:55:46.0803] ``` var function f() {} ``` hoist the name, like a 'var', but not the value :) [00:56:44.0523] why not all three, var functions have no tdz, let functions are reassignable and have tdz, const functions aren't reassignable :-p [00:57:08.0910] > <@ljharb:matrix.org> why not all three, var functions have no tdz, let functions are reassignable and have tdz, const functions aren't reassignable :-p I mean, that's what I'm suggesting, mostly unironically. [00:57:10.0010] const functions can be used in constexprs [00:57:17.0096] > <@rbuckton:matrix.org> Especially since decorators expose the name of a thing, thus `let f = @dec function() {}` seems like it wouldn't get the name. well, class decorators can find themselves in the same position, and get undefined [00:57:54.0892] > <@littledan:matrix.org> well, class decorators can find themselves in the same position, and get undefined And that's exactly why I would want to be able to decorate function declarations as well. [00:58:30.0396] yes, I think we should focus on decorating function declarations, and live with the non-hoisting (and presumably starting at undefined, given Shu's presentation) [00:59:15.0217] > <@littledan:matrix.org> yes, I think we should focus on decorating function declarations, and live with the non-hoisting (and presumably starting at undefined, given Shu's presentation) I would be happy with this. The function hoisting issue held up decorators for years, and was why it was split off from the original proposal, IIRC. [01:00:31.0582] Luca Casonato: I'm not convinced by snapshotting, just dump everything you care about yourself [01:03:54.0871] eemeli: I just wanted to make sure you have understood that a solution here would look more like "give me the ISO-8601 representation of this" or "sort this according to some defined non-locale-specific Unicode operation", etc, not a "give me the stable string repr of this" [01:04:15.0699] that's the thing I was trying to say that I couldn't put to words in the moment [01:04:29.0826] but it was basically what bakkot had said [01:04:38.0777] > <@michaelficarra:matrix.org> Luca Casonato: I'm not convinced by snapshotting, just dump everything you care about yourself but if your app has localization features that are subject to change, you cannot do snapshot testing unless you make some kind of Intl stub [01:04:55.0471] in this case you could just test with the `zxx` locale and get it working [01:05:25.0594] > <@usharma:igalia.com> but if your app has localization features that are subject to change, you cannot do snapshot testing unless you make some kind of Intl stub why can't you just read all of the properties you care about? [01:05:32.0768] ryzokuken: I think that is an unrelated problem [01:05:33.0235] if the answer is "they are not exposed", we should fix that [01:05:56.0731] > <@michaelficarra:matrix.org> eemeli: I just wanted to make sure you have understood that a solution here would look more like "give me the ISO-8601 representation of this" or "sort this according to some defined non-locale-specific Unicode operation", etc, not a "give me the stable string repr of this" this is how I understood the motivation myself (not the latter case I mean) [01:06:59.0861] > <@bakkot:matrix.org> why can't you just read all of the properties you care about? no I literally mean if you have a website that is rendered localized, you cannot do snapshot testing unless you have some sort of null locale to use in the testing environment [01:07:16.0419] or work on engines without Intl support [01:07:42.0089] say more about why? [01:07:55.0787] why can't you stub intl.whatever to just return "AAAAA" [01:07:56.0426] why can you not do your own serialization, of all of the properties you care about? [01:08:06.0511] > <@devsnek:matrix.org> why can't you stub intl.whatever to just return "AAAAA" yeah, that's one solution I mentioned [01:08:42.0763] oh you mean snapshotting _the entire website_ [01:08:48.0407] yeah [01:08:58.0524] yeah I am not convinced that use case is worth solving, stubbing out intl seems fine for that case [01:09:04.0069] you also need to stub `Math.random` and so on [01:09:09.0333] `new Date` [01:09:10.0717] lots of stuff [01:09:10.0730] right, true [01:09:19.0670] (off to dinner, back later) [01:09:22.0494] but there's other cases apart from that [01:09:29.0605] I was just elaborating on the one Luca mentioned [01:09:31.0311] like i see this the same way as if we said "we need a special deterministic url for using fetch() in snapshot tests" [01:09:40.0668] same, talk to you all after lunch! [01:09:58.0417] > <@devsnek:matrix.org> like i see this the same way as if we said "we need a special deterministic url for using fetch() in snapshot tests" what about engines without Intl support [01:10:58.0280] not sure what you mean [01:10:59.0475] if you design localized interfaces that use Intl, you need to guard every call or again, use an Intl stub [01:11:24.0606] but if there were a null locale that was supported on all implementations, you would have a clean fallback [01:11:35.0965] like how the `iso8601` calendar works in Temporal. [01:11:51.0618] i think a null locale would be an explicitly bad thing [01:12:09.0760] Ideally you'd want to use `gregory` for many real use cases, but in the absence of any of these Intl calendars, you can always use the programmatic one [01:12:15.0652] we used to have something similar in nodejs [01:12:23.0204] and it caused so much pain that we now ship node with full locale data by default now [01:12:48.0034] * and it caused so much pain that we now ship node with full locale data by default [01:12:48.0760] well, except we shipped an awkward stripped down locale data [01:12:59.0273] that was like en-US or something IIRC [01:13:26.0857] no matter what you put in you got out en-US but it wasn't real en-US because there wasn't even cldr data for en-US bundled [01:13:40.0793] damn [01:13:46.0400] but that's not what is being proposed here [01:14:03.0200] although I guess motivations could be similar [01:14:59.0037] i think my intuition is still that this is not a good thing and i'd rather code polyfilled intl in some way that makes sense to them [01:15:02.0392] anyway, I don't want to cause any damage and will let Eemeli explain the merits of the proposal, I was hoping to add a supportive voice but I'm not involved yet [01:43:00.0246] > <@michaelficarra:matrix.org> Luca Casonato: I'm not convinced by snapshotting, just dump everything you care about yourself If it’s a simple, stable, easy to read, string base representation of the value, I’d prefer to use that over a structured representation for debugging & snapshot testing [01:43:54.0174] > <@bakkot:matrix.org> you also need to stub `Math.random` and so on Not unless your runtime provides a way for you to run tests deterministically at a fixed fake time (which many test runners do) [01:45:35.0350] > <@devsnek:matrix.org> like i see this the same way as if we said "we need a special deterministic url for using fetch() in snapshot tests" Why, url already has a simple and stable human readable serialization of the contained properties? Dates for example, may not [07:03:20.0992] 92 unread messages in a thread (or threads?) I cannot identify. Thanks, Matrix. [07:41:26.0743] I think one necessary next step for Stable Formatting is to enumerate the cases where Intl APIs are currently being used badly or dangerously because they're providing the most ergonomic solutions to developer problems. [13:13:08.0901] > <@shuyuguo:matrix.org> i am not a fan of being told, "have you tried being smarter" I have no context on the particulars here, but I can say that around the Agoric virtual water cooler, we have tremendous respect for your intelligence. I have no doubt we could be kinder. [13:29:19.0662] are you a fan of being told "have you tried being kinder" ? `/s` [13:30:24.0759] It’s always welcome feedback, regardless. [15:52:43.0890] > <@kriskowal:matrix.org> I have no context on the particulars here, but I can say that around the Agoric virtual water cooler, we have tremendous respect for your intelligence. I have no doubt we could be kinder. thanks. the context is i would appreciate the assumption that we have done our due diligence on performance problems, which involves judgments in a tradeoff space. disagreements on the judgment call that was made _can_ be productive, but i would like the intellectual humility to appreciate our tradeoff space rather than making an opposite call in plenary like "i don't think you're trying hard enough" [16:38:25.0115] @shu, I just went through the transcript, I wasn't online anymore then, but putting aside the debate over due diligence and tradeoff judgements, I actually do not understand in which scenario a `let` declaration without initialization that occurs as the first statement of a scope can ever execute after any other code declared in that scope. [16:46:43.0693] * @shu, I just went through the transcript, I wasn't online anymore then, but putting aside the debate over due diligence and tradeoff judgements, I actually do not understand in which scenario a `let` declaration (without initialization) that occurs as the first statement of a scope can ever execute after any other code declared in that scope. [16:50:47.0152] * shu: I just went through the transcript, I wasn't online anymore then, but putting aside the debate over due diligence and tradeoff judgements, I actually do not understand in which scenario a `let` declaration (without initialization) that occurs as the first statement of a scope can ever execute after any other code declared in that scope. [16:57:05.0043] littledan: re disposable AbortController, https://github.com/whatwg/html/issues/8557#issuecomment-1724193449 2023-09-28 [17:10:26.0237] > <@mhofman:matrix.org> shu: I just went through the transcript, I wasn't online anymore then, but putting aside the debate over due diligence and tradeoff judgements, I actually do not understand in which scenario a `let` declaration (without initialization) that occurs as the first statement of a scope can ever execute after any other code declared in that scope. could you rephrase with a concrete code snippet? [17:10:47.0605] like, are you talking about the case where there are also no escaped, hoisted function declarations? [17:12:06.0880] but the general answer is that hoisted functions hoist above the lexical binding initialization: https://tc39.es/ecma262/#sec-blockdeclarationinstantiation [17:13:38.0830] > <@shuyuguo:matrix.org> like, are you talking about the case where there are also no escaped, hoisted function declarations? How can an escaped hoisted function execute before a let declaration that appears as first statement in the scope is my question [17:14:42.0920] ah, i don't think in that particular configuration it can [17:14:48.0730] Maybe they hoist above, but their utterances cannot be in any code that is executed before the declarations [17:16:22.0235] to anticipate your next question: currently no engine fully elides all inner accesses even in that configuration, however, i imagine due to two factors [17:17:33.0878] 1) people don't actually write code like that 2) every engine lazy compiles. the dominance information is available when compiling the outer function that contains the inner functions, but we need that information when compiling the inner functions, which occurs lazily when those functions are called. this means that we need to plumb that parse-time information and save it until those inner functions are compiled. nobody AFAIK incurs the memory cost for this [17:17:45.0164] * 1. people don't actually write code like that 2. every engine lazy compiles. the dominance information is available when compiling the outer function that contains the inner functions, but we need that information when compiling the inner functions, which occurs lazily when those functions are called. this means that we need to plumb that parse-time information and save it until those inner functions are compiled. nobody AFAIK incurs the memory cost and the complexity for plumbing this [17:17:57.0197] we _could_ start doing it if more code were written like that [17:18:38.0068] but that creates a world where optimal performance depends on a tight coupling of what tooling does and what engines do, which is in general brittle, and undesirable for both tools and engines [17:18:46.0763] since when one or the other makes a move for whatever other reason, users might complain [17:20:30.0087] to expand more on (1), you can't do this source transform with consts because you can't emit the unutterable `init=` thing [17:20:41.0428] My understanding from the transcript was that mark believed these semantics could be optimized by engines with a simple static pass, and you seemed to say there were cases where it couldn't be optimized, that a simply static analista was not possible. [17:20:53.0343] yes [17:21:04.0775] it's probably not possible to do in a single pass [17:21:13.0231] and we do not want to do things that require more than a single pass [17:21:22.0145] Then I agree there remains a question whether such an optimization and tight tooling coupling is advisable [17:21:41.0116] since function declarations are hoisted, we won't know if mark's code pattern in fact holds until we reach the end of the block scope and know all the function declaration names [17:21:54.0074] like it's probably still fine to check if the pattern holds, not too expensive [17:22:34.0603] Then I'm still confused. Why is the presence of a let declaration as the first statement of a scope not a sufficient indicator to disable tdz checks on that binding [17:23:14.0835] as a property, i agree with you that it is [17:23:38.0937] as a practical matter of implementing the elision, it is not trivial because of lazy compiling as i've described above [17:23:43.0179] and that it does not apply as easily to consts [17:24:18.0119] * as a practical matter of implementing the elision, it is not trivial because of lazy compiling as i've described above. but also we just don't do it because we don't see code like that [17:24:45.0036] any additional analyses is complexity we'd have to maintain forever and ever, so the tradeoff isn't quite there today for this [17:25:30.0832] though it is strange to me to suggest that a solution is for tooling to _compile away the TDZ_ [17:25:55.0917] if you're okay with users not getting the runtime checks... why fight to keep it in the language? [17:27:15.0207] Right this is about the feasibility of optimizing such let declarations that would be emited by tooling. Whether that's advisable is a separate question [17:27:32.0732] as a general rule of thumb, all things are feasible [17:27:42.0422] or rather, all things are possible to implement [17:27:49.0799] most of the time we just don't wanna [17:31:37.0052] I personally believe that there are different authors. Some care about such performance optimizations, but I'm not sure that means the language semantics should change for them. Yet I am sympathetic with their goal and this could be a way to support it. [17:32:17.0784] fair enough, if we had accurate demographic info we could settle this more dispassionately [17:32:19.0905] alas [17:32:48.0196] like, we _could_ have a `let2` or whatever as waldemar suggested [17:32:53.0584] but personally i feel like that's a worse choice for the language [17:33:11.0683] though putting my personal feelings aside i can certainly live with that outcome [17:34:20.0693] back to the different authors point: i was hoping to show that the majority either don't care, either via ignorance or via choosing performance over runtime checks [17:36:11.0962] a nuance here is that most developers don't care about performance either! and there lies our deeper disagreement. i think web users (not authors) are better served by a language that values performance as the default, if the correctness gains are marginal. i think you and others take the other side of that polarity (or think that TDZ runtime checks aren't marginal in value) [17:38:24.0667] I think that the state of web tooling means that authors don't have to make that choice or understand it, and that the tooling can make it for them [17:40:39.0438] we're already in that world, people just use `var`s [17:40:52.0681] And the Web (or node) is not the only JS environment that should be considered when it comes to consider the impact of changing the semantics [17:42:18.0255] i don't think we, as a committee, _should_ be okay with speccing stuff that is transpiled forever [17:42:36.0468] that's a crappy value prop for us engines and disincentivizes things in a way i think everyone would dislike [17:44:55.0452] Unless we stop all syntax changes for the language, can we really ween the ecosystem off transpilation? [17:45:04.0545] that's not what i said [17:45:09.0590] what i said was, transpiled _forever_ [17:45:24.0338] most syntax features are still incentivized for the long-tail adoption untranspiled [17:45:48.0901] transpilation itself is not going to go away because new features are going to be adopted transpiled for the initial N years [17:48:31.0763] what i'm interested in (and led with in the slides) was the adoption inflection point. if i get a whiff that that inflection _can't_ happen because the incentives are aligned against it, then i want to change that [18:02:08.0916] I guess it's a weird case this one. It probably has high adoption in authored code, but low usage in code executed by engines. The question is whether tooling should be able to keep the code as authored or need to keep transpiling it past engine support because of performance concerns. [18:02:47.0620] * I guess it's a weird case this one. It probably has high adoption in authored code, but low usage in code executed by engines. The question is whether tooling should be able to keep the code as authored or need to keep transpiling it past the point all engines support it because of performance concerns. [18:04:08.0172] an interesting annex b change in jsc: https://bugs.webkit.org/show_bug.cgi?id=163209 [18:05:42.0264] Which is why I believe mark suggested a lint fix approach to this problem, which would change the author code literally at the source, but that means adding cognitive load to authors to understand the potential performance trade-offs [18:09:22.0233] tcq down? [18:10:48.0953] how are we gonna do queue? [18:10:54.0734] > <@ljharb:matrix.org> an interesting annex b change in jsc: https://bugs.webkit.org/show_bug.cgi?id=163209 Ugh annex B... [18:11:34.0442] I assume Rob is going to post the spreadsheet soon [18:11:38.0949] we have a backup: https://docs.google.com/spreadsheets/d/1Us6MFx3WB6E8K5jJ7m1j5jEa9OUOuwgx60RXwzfI7JE/edit#gid=0 [18:11:48.0993] 👏annex b👏is👏praxis👏 [18:15:33.0276] I reached out to Brian to see if he knows what's going on with TCQ, he said he'll see if he can find out what's wrong. [18:16:42.0122] > <@rbuckton:matrix.org> I reached out to Brian to see if he knows what's going on with TCQ, he said he'll see if he can find out what's wrong. I was seeing ws failures in console, not sure if that's helpful but let him know if you still have that comms channel open [18:17:21.0245] There is a "OK with or without streaming" on the queue without name, please add it [18:17:24.0301] ``` app.build.js:6 WebSocket connection to 'wss://tcq.app/socket.io/?id=MypE&EIO=3&transport=websocket' failed: WebSocket is closed before the connection is established. r.doClose @ app.build.js:6 ``` [18:18:05.0654] and 504.0 GatewayTimeout reloading [18:18:16.0281] eventually renders ":( Application Error If you are the application administrator, you can access the diagnostic resources." [18:19:13.0521] if anyone wants to help DDoS TCQ, that seemed to help yesterday 😅 [18:19:24.0395] `Nmap` for fun and profit [18:19:37.0141] The TCQ app service is down. [18:20:31.0290] it's back! [18:20:42.0521] killing my DoS [18:20:55.0308] it is indeed back [18:21:10.0879] disambiguate: DeDoS vs. DDos [18:22:00.0765] Disk Operating System [18:24:31.0364] TCQ is not back [18:24:43.0775] TCQ is so over [18:25:01.0592] Everyone DDoS'd it [18:25:28.0893] ^For the chairs in case they accidentaly reload and loose it [18:25:40.0753] surely in this case it's a CDOS [18:26:02.0190] why did we stop using the spreadsheet?! [18:26:20.0096] Because it was working again 🤷 [18:26:22.0771] Still looking into the issue. [18:26:32.0845] TCQ comes back for one full second and we assume it's all roses? [18:26:51.0404] we've been doing that throughout the entire meeting... sadly. [18:27:51.0162] > <@michaelficarra:matrix.org> TCQ comes back for one full second and we assume it's all roses? all too human [18:27:57.0242] historically it was alright for a while, then craps out, wash, rinse, repeat [18:28:02.0968] how is usefulness of streaming supposed to imply that single-shot is not useful? [18:28:39.0674] I don't understand the philosophical argument, I kinda think we *should* be prioritizing the most useful things, and not trying to design the 100% universal thing, sometimes [18:29:26.0880] and we definitely *do* chop up proposals at times [18:29:27.0000] littledan: especially when the former does not block us from doing the latter later [18:31:33.0697] +1 to Luca [18:31:49.0908] Another +1 if he mentions usabilty [18:33:01.0660] If the concern is the inability to use native Base64 support in a memory constrained environment, I'm not 100% sure the solution is to spend more of that memory on a 3rd-party library or wrapper to do that for you. [18:33:22.0975] well, I guess on Moddable that could be ROM, but most embedded JS has this stuff in RAM... [18:33:27.0065] > <@rbuckton:matrix.org> If the concern is the inability to use native Base64 support in a memory constrained environment, I'm not 100% sure the solution is to spend more of that memory on a 3rd-party library or wrapper to do that for you. I would assume the web would provide a web stream [18:34:13.0787] > <@nicolo-ribaudo:matrix.org> I would assume the web would provide a web stream I'm not talking about the web platform, though. I'm talking about embedded. [18:34:58.0345] Embedded can also provide their own implementation. It's better to have two different streaming primitives in different platform (XS and browsers) rather than two in the same platform (browsers) [18:35:06.0099] I'm kinda worried about this objection in a more fundamental way--I want TC39 to be a place where we can develop these kinds of useful standard library functions. [18:35:46.0804] TC39 streams ? [18:35:47.0457] littledan: I think it's vaguely possible we could get web streams in TC39 someday, but I don't think we should block the one-shot version of this proposal on that [18:35:55.0545] Do we want to design a sync streaming API in 262? [18:36:06.0189] * Do we want to design a general-purpose sync streaming API in 262? [18:36:45.0396] > <@bakkot:matrix.org> littledan: I think it's vaguely possible we could get web streams in TC39 someday, but I don't think we should block the one-shot version of this proposal on that Agreed. I'm surprised at the length of argumentation here when there is such strong support and it's such a small API. This is what makes me worried. [18:36:59.0404] > <@jridgewell:matrix.org> Do we want to design a general-purpose sync streaming API in 262? Are iterators streaming, or they have different properties? [18:37:06.0778] I'd _like_ to see a streaming API at some point. I haven't been partial to the actual API design choice, since it involves creating numerous nursery objects to pass arguments in and pull arguments out, so it's not efficient for memory and/or cpu constrained environments. [18:37:42.0548] how would the options get passed in without changing the code? [18:38:27.0394] Good point. `bytesToBase64(bytesIterator: Iterator): Iterator` [18:38:56.0153] Brian said TCQ will be back up again soon, but folks will have to log in again since he needs to clear out the sessions as part of trying to resolve the issue. [18:39:16.0632] OK if he will take Jordan's word on it, does that mean it's OK for this to proceed? [18:39:26.0599] > <@rbuckton:matrix.org> Brian said TCQ will be back up again soon, but folks will have to log in again since he needs to clear out the sessions as part of trying to resolve the issue. Let's use the spreadsheet until the end of this presentation [18:44:09.0207] I'd much rather have a standard solution that *doesn't* depend on non-browser runtimes implementing more of the DOM so that their users can write portable code. [18:46:37.0286] Base64 is independently useful regardless of platform. While I believe the streaming API needs work, I fully support it existing either as part of this proposal or as an independent proposal. [18:47:23.0383] i also support it existing. just not coupled to the one-shot. [18:48:17.0595] I am concerned that splitting the proposal is an opportunity for detractors to block the streaming portion indefinitely. [18:48:31.0608] a "constraint" would be like "we cannot implement single-shot", not "we want extra stuff" [18:48:34.0666] phoddie: is moddable unable to implement the one-shot due to its constraints? [18:48:51.0257] browsers don't have infinite buffer space either... [18:48:54.0562] this is an abuse of our process [18:49:01.0158] It seems like the concern is that they could implement it but it wouldn't be usable in that environment due to the single-shot nature. [18:50:08.0077] > <@michaelficarra:matrix.org> this is an abuse of our process Yes, I think this isn't about "removing lone objectors" entirely, more like, the objection has to be for a reason (a long-standing principle that we have) [18:50:09.0925] I would personally just bring it back for stage 3 and, if no reasonable objections were voiced, ask for a vote [18:50:11.0452] > <@rbuckton:matrix.org> It seems like the concern is that they could implement it but it wouldn't be usable in that environment due to the single-shot nature. But does having the streaming api in tc39 make the single shot one more usable? [18:50:40.0584] > <@rbuckton:matrix.org> I am concerned that splitting the proposal is an opportunity for detractors to block the streaming portion indefinitely. that is a valid concern we've all had at times, but that isn't a valid reason to be a lone objector on a proposal - as i myself have relented when in that very position multiple times. [18:50:57.0737] > <@nicolo-ribaudo:matrix.org> But does having the streaming api in tc39 make the single shot one more usable? As opposed to having it in WHATWG? Having it in WHATWG doesn't help embedded at all. [18:51:09.0237] for example, that mindset would have blocked decorators until they worked on all functions [18:51:21.0011] * for example, that mindset would have blocked decorators until they worked on all functions. but that's not how we operate. [18:51:28.0116] * for example, that mindset would have blocked decorators until they worked on all functions. but that's not how we prefer to operate. [18:51:32.0948] > <@ljharb:matrix.org> for example, that mindset would have blocked decorators until they worked on all functions. but that's not how we prefer to operate. IIRC, decorators were held up for years for this very reason. [18:51:45.0345] indeed. but not indefinitely. [18:51:57.0104] I agree that this feels like an abuse; I don't think the comment that this doesn't stop the proposal but simply moves it to a less sensible standards body was taken seriously enough [18:51:57.0140] > <@rbuckton:matrix.org> As opposed to having it in WHATWG? Having it in WHATWG doesn't help embedded at all. The proposed options for this proposal are either to have one or both APIs. Moddable does not implement those WHATWG standards [18:52:02.0323] and, because it's syntax, not with the risk it'll be shipped, worse, in other standards bodies. [18:52:07.0772] Decorators are completely different, as this was a widespread implementability concern. There isn't an implementability concern, more that it wouldn't be applicable enough. [18:52:19.0489] * I agree that this feels like an abuse; I don't think the comment that this doesn't stop the proposal but simply moves it to a less appropriate standards body was taken seriously enough [18:52:31.0748] * and, because it's syntax, not with the risk it'll be shipped, worse, in other standards bodies, which has happened with APIs multiple times already. [18:52:33.0903] Yeah I would absolutely just recommend we do this in WHATWG, then. [18:52:44.0312] that will be the outcome, and it would be a worse one [18:52:47.0424] * that will be the outcome, and it would be a worse one than advancing it here [18:52:50.0679] * that will be the outcome, and it would be a worse one than advancing just the one-shot here [18:52:56.0879] * that will be the outcome if we do nothing, and it would be a worse one than advancing just the one-shot here [18:53:01.0280] can we update tcq to the current proposal? i want to add an agenda item [18:53:12.0621] We're not TCQing for the rest of the day [18:53:17.0290] using the spreadhseet instead [18:53:24.0628] https://docs.google.com/spreadsheets/d/1Us6MFx3WB6E8K5jJ7m1j5jEa9OUOuwgx60RXwzfI7JE/edit#gid=0 [18:53:30.0948] oh, but i see tcq is alive now? [18:53:31.0749] Looks like there is an issue with the docker container TCQ runs under, it may not be up for the rest of the session. [18:53:41.0358] down again [18:53:48.0561] It may be up, but docker keeps killing the application with no indication as to why. [18:54:48.0853] i think peter is being myopic here [18:55:01.0542] Brian said he may be able to look into it more in a few hours, but it may not be reliable until then. [18:55:33.0968] practically, what is going to happen here next is: - it becomes part of some web platform API via another body - they are pressured to implement it anyway for interop, because their users want it (which is a goal, as he has said) - they are now out of the loop for future design decisions [18:56:18.0345] and this is, to be clear, actually fine for most of us [18:56:22.0726] but it seems like a lose-lose for them [18:56:58.0671] let's give this at least another two months to try to resolve this rather than immediately do a venue switch [18:57:02.0471] This is exactly what happened with cancellation [18:57:20.0314] > <@littledan:matrix.org> let's give this at least another two months to try to resolve this rather than immediately do a venue switch kevin has said he's spent 2 years on this [18:57:34.0594] promise cancellation shipped in fetch during one of those 2 month gaps [18:57:39.0563] We should not allow our process to fail in this way. I am fine with failing due to a lone objector, but not due to capriciousness. [18:57:42.0800] * promise cancellation shipped in fetch during one of those 2 month gaps, without notice to tc39 [18:58:00.0358] * promise cancellation shipped in fetch during one of those 2 month gaps, without notice to tc39, and now we might never be able to have cancellation in the language as a result. [18:58:24.0175] This is exactly the kind of scenario where we should subvert unanimous consent. [18:58:31.0804] > <@shuyuguo:matrix.org> but it seems like a lose-lose for them It's also a lose for web platform. I am relatively sure an in engine implementation will be significantly cheaper than a web platform implementation (because strings don't need to be exported from the engine and can instead be walked directly in engine) [18:58:33.0733] > <@rbuckton:matrix.org> This is exactly what happened with cancellation Yes. With cancellation, Domenic withdrew it because he didn't like how I was advocating for it to be just library-based, without syntax extensions. In the end, it shipped in the web without those syntax extensions. So this is a good example of how doing a venue change also doesn't help get everything that you want. [18:59:04.0458] > <@lucacasonato:matrix.org> It's also a lose for web platform. I am relatively sure an in engine implementation will be significantly cheaper than a web platform implementation (because strings don't need to be exported from the engine and can instead be walked directly in engine) eh that can be worked around. streams are implemented directly in SpiderMonkey. the fact that engine codebase lines follow standards org chart is mostly accidental, and can be worked around easily enough [18:59:13.0525] Does XS implement `atob`/`btoa`? [18:59:24.0455] > <@shuyuguo:matrix.org> eh that can be worked around. streams are implemented directly in SpiderMonkey. the fact that engine codebase lines follow standards org chart is mostly accidental, and can be worked around easily enough not anymore I don't think! [18:59:27.0519] > <@littledan:matrix.org> let's give this at least another two months to try to resolve this rather than immediately do a venue switch I just don't see what else there is to be said, here. Several people have said streaming doesn't make sense as part of this proposal. phoddie has said that the proposal cannot advance without streaming. [18:59:37.0320] > <@ljharb:matrix.org> promise cancellation shipped in fetch during one of those 2 month gaps, without notice to tc39, and now we might never be able to have cancellation in the language as a result. kinda; it was under development for some months in WHATWG. [18:59:41.0646] I am willing to give it another try next meeting if there's some hope of advancement but I don't see what there is. [18:59:54.0719] > <@lucacasonato:matrix.org> not anymore I don't think! oh boo, really? well, for blink, structured clone is implemented in V8, so is console, and some weirdness [19:00:05.0690] > <@lucacasonato:matrix.org> not anymore I don't think! * oh boo, really? well, for blink, structured clone is implemented in V8, so is console, and some other weirdness [19:00:44.0198] NaN again [19:00:57.0398] > <@littledan:matrix.org> let's give this at least another two months to try to resolve this rather than immediately do a venue switch I mean I could come back and force a vote, I guess. But I would prefer not to do that. The web streams version is independently useful anyway and it just seems more worth spending tie there. [19:01:01.0377] Outside of the terrible corner cases they are indeed negations, this is too pedantic. [19:01:19.0836] > <@shuyuguo:matrix.org> eh that can be worked around. streams are implemented directly in SpiderMonkey. the fact that engine codebase lines follow standards org chart is mostly accidental, and can be worked around easily enough let's talk about this during lunch. we are considering shipping some custom .tq for v8 just to handle utf8 encoding (for `TextEncoder`) because host calls and string exporting adds significant overhead. chrome likely has a similar overhead for `TextEncoder` [19:01:41.0887] sure [19:02:10.0336] Node Buffer has base64 functions. A WHATWG proposal would just be a modernized version of atob/btoa. Then base64 can be done in both browser and non-browser environments, just with different APIs. So that's the outcome we're heading toward. [19:02:32.0586] > <@sffc:mozilla.org> Node Buffer has base64 functions. A WHATWG proposal would just be a modernized version of atob/btoa. Then base64 can be done in both browser and non-browser environments, just with different APIs. So that's the outcome we're heading toward. and likely node would implement the whatwg version [19:02:50.0305] > <@bakkot:matrix.org> I mean I could come back and force a vote, I guess. But I would prefer not to do that. The web streams version is independently useful anyway and it just seems more worth spending tie there. I implore you to just bring it back for stage 3 and force a vote. [19:03:08.0472] > <@littledan:matrix.org> Yes. With cancellation, Domenic withdrew it because he didn't like how I was advocating for it to be just library-based, without syntax extensions. In the end, it shipped in the web without those syntax extensions. So this is a good example of how doing a venue change also doesn't help get everything that you want. The `AbortController`/`AbortSignal` API has been deficient in many areas and built a dependency on the DOM that required any interoperable implementation to bring those dependencies along. And the current status of cancellation w.r.t. WHATWG is essentially that ECMA-262 can only have native cancelation if it is via a host hook. [19:03:09.0608] yes, that wouldn't be the end of the world *for this proposal*, but I really want us to figure out how to get through these situations in general. That's why I'd want to bring this back in 2 months. [19:03:29.0578] shipped that fmt change since yesterday in `deno fmt` and `dprint`: https://dprint.dev/playground/#code/IQMw9mAECWB2DOAXAhrAxgUzCSAhZATkA/language/typescript [19:04:01.0454] > <@littledan:matrix.org> yes, that wouldn't be the end of the world *for this proposal*, but I really want us to figure out how to get through these situations in general. That's why I'd want to bring this back in 2 months. if you want to put a process topic on the agenda for the next meeting, I would be ok with putting base64 on the agenda to follow that item conditional on the outcome of that discussion [19:04:05.0206] I would love for base64 to set precedent for how our consensus process actually works. [19:04:16.0525] I do not myself have the heart for leading a process discussion [19:04:25.0362] we don't need a process discussion [19:04:33.0189] I believe this to already be out process [19:04:41.0552] * I believe this to already be our process [19:04:51.0047] people other than peter disagree, though, like msaboff [19:05:13.0993] shu: on what grounds? [19:05:14.0213] I'm going to guess that changing operator precedence for `in` and `instanceof` would probably break something somewhere. [19:05:15.0905] it did not sound like msaboff disagreed with the utility of the single-shot version [19:05:48.0482] if we did a vote, IMO it should be a large supermajority and only be deployed in cases where we really don't feel like the objection makes sense [19:05:50.0055] sorry, i meant, other people than peter disagree on what is already our process [19:05:51.0716] I think this would be clearer if we pronounce ! as bang 😅 [19:06:09.0959] i do not think msaboff disagreed with the technical parts of the proposal at all [19:06:20.0240] but he said he does not think we have a consensus process, but a single dissenter process [19:06:25.0974] which, we sometimes do imo [19:06:30.0707] > <@shuyuguo:matrix.org> sorry, i meant, other people than peter disagree on what is already our process yes, there would be a process discussion if someone proposes a vote [19:06:56.0711] i would support a discussion here but i am skeptical it will be productive [19:07:05.0016] Let me explain my comments. [19:07:05.0071] `a not instanceof b` looks like we need NLTH [19:07:10.0391] * `a \n not instanceof b` looks like we need NLTH [19:07:10.0818] I think a process change should center more around the nature of objections rather than just allowing a majority vote to push things through. That sounds like dangerous precedent. [19:07:26.0082] Do people think a JSON stream parsing API would have utility? [19:07:45.0700] > <@sffc:mozilla.org> I think a process change should center more around the nature of objections rather than just allowing a majority vote to push things through. That sounds like dangerous precedent. I agree that the nature of the objection should be a factor here. None of us want to go around voting all the time. [19:08:01.0602] Is TCQ down again? I logged out of GitHub and back in again, but I still get a blank page for TCQ [19:08:11.0355] > <@sffc:mozilla.org> Do people think a JSON stream parsing API would have utility? I know some programmers I know are looking for a JSON parse streaming API [19:08:19.0835] > <@sffc:mozilla.org> Do people think a JSON stream parsing API would have utility? * Some programmers I know are looking for a JSON parse streaming API [19:08:34.0625] > <@bradfordcsmith:matrix.org> Is TCQ down again? I logged out of GitHub and back in again, but I still get a blank page for TCQ Yes. WE're using Sheets now [19:08:38.0995] https://docs.google.com/spreadsheets/d/1Us6MFx3WB6E8K5jJ7m1j5jEa9OUOuwgx60RXwzfI7JE/edit#gid=0 [19:08:54.0101] yes I think this is the thing we are all saying [19:09:27.0080] > <@sffc:mozilla.org> I think a process change should center more around the nature of objections rather than just allowing a majority vote to push things through. That sounds like dangerous precedent. We've talked about this plenty. We're not limited solely to "unanimous, any objector can block indefinitely" and "majority wins". W3C consensus is an existing and reasonably well-working middle ground. [19:09:30.0889] > <@jackworks:matrix.org> Some programmers I know are looking for a JSON parse streaming API Newline Terminated JSON? How would you stream the out the result of regular JSON streaming? [19:09:42.0829] also as a reminder, Ecma process allows for a vote on anything, we just have an internal and non-binding TC39 agreement to work on unanimous consent [19:09:43.0826] Consensus is consensus, if you want to add some kind of "mechanism to overcome minorities" it is not consensus anymore. I do not think, that idea of consensus is wrong. People have to compromise, to make consensus work. The question is, if we have explored all compromise options. I have the feeling, from Kevin's side, we did and I have the same feeling, that we did not explore all compromises on peter's side. [19:09:48.0645] TC39 does NOT have a consensus process. It has a single blocker process. Many of us have been on both sides of the blocking process. In this case, one member asked for an accommodation, add a streaming API and I'll support. The committee, as a whole, wasn't willing to accept the addition. The member blocked. [19:09:51.0001] For context, the suggested syntax for relational patterns in pattern matching via `is` would have this as: ``` x is not in y // true if 'x' does not match 'in y' x is not y // true if 'x' does not match 'y' via custom matcher semantics. // optionally: x is not instanceof y // true if 'x' does not match 'instanceof y', but is probably unnecessary ``` [19:10:06.0514] > <@littledan:matrix.org> if we did a vote, IMO it should be a large supermajority and only be deployed in cases where we really don't feel like the objection makes sense Procedurally, in different forums votes like this sometimes need to pass in two separate meetings. Which would give time for useful offline discussions. [19:10:28.0606] > <@msaboff:matrix.org> TC39 does NOT have a consensus process. It has a single blocker process. Many of us have been on both sides of the blocking process. In this case, one member asked for an accommodation, add a streaming API and I'll support. The committee, as a whole, wasn't willing to accept the addition. The member blocked. i do not think the first sentence itself has unanimous agreement within committee [19:10:36.0162] here is the thread from _two years ago_ on streaming https://github.com/tc39/proposal-arraybuffer-base64/issues/13 [19:10:45.0170] I am not convinced that more time for discussions is the thing needed, here [19:10:47.0527] > <@shuyuguo:matrix.org> i do not think the first sentence itself has unanimous agreement within committee YOu just made my point. [19:10:56.0018] > <@shuyuguo:matrix.org> i do not think the first sentence itself has unanimous agreement within committee * You just made my point. [19:11:02.0733] ...wat [19:11:09.0397] (W3C consensus is that single objectors *can* object, but the WG can choose to override the objection. It requires escalation to W3C management with an explanation of why the override was necessary.) [19:11:17.0239] * (W3C consensus is that single objectors _can_ block, but the WG can choose to override the objection. It requires escalation to W3C management with an explanation of why the override was necessary.) [19:11:26.0657] > <@christianulbrich:matrix.org> Consensus is consensus, if you want to add some kind of "mechanism to overcome minorities" it is not consensus anymore. I do not think, that idea of consensus is wrong. People have to compromise, to make consensus work. The question is, if we have explored all compromise options. I have the feeling, from Kevin's side, we did and I have the same feeling, that we did not explore all compromises on peter's side. Can you elaborate on what you think hasn't been explored? [19:11:53.0753] > <@jridgewell:matrix.org> Newline Terminated JSON? How would you stream the out the result of regular JSON streaming? no idea, maybe emit by enter-leave (enter key a, enter array item 0, ... leave key a)? [19:12:01.0844] > <@christianulbrich:matrix.org> Consensus is consensus, if you want to add some kind of "mechanism to overcome minorities" it is not consensus anymore. I do not think, that idea of consensus is wrong. People have to compromise, to make consensus work. The question is, if we have explored all compromise options. I have the feeling, from Kevin's side, we did and I have the same feeling, that we did not explore all compromises on peter's side. What compromises did we not explore? [19:12:53.0355] The compromise was "add a streaming api" which the committee as a whole did not accept. As such, what else can the champions do to advance this? [19:13:39.0918] > <@christianulbrich:matrix.org> Consensus is consensus, if you want to add some kind of "mechanism to overcome minorities" it is not consensus anymore. I do not think, that idea of consensus is wrong. People have to compromise, to make consensus work. The question is, if we have explored all compromise options. I have the feeling, from Kevin's side, we did and I have the same feeling, that we did not explore all compromises on peter's side. also, we do unavoidably draw lines about what we mean by consensus. We actively seek out community feedback and support, but we do not consider non-members as possible objectors to proposals. We have also defined things around what constitutes a meaningful objection, e.g., we don't permit blocking Stage 4 because you disagree with the design. [19:14:01.0984] i invite other delegates to read about a historical instance of a single-veto process: https://en.wikipedia.org/wiki/Liberum_veto [19:15:03.0437] > <@jridgewell:matrix.org> Newline Terminated JSON? How would you stream the out the result of regular JSON streaming? More like, a parser that remembers where it is in the ECMA-404 grammar and can take more chunks and then stops reading chunks once it reaches the end of the grammar [19:15:28.0681] I still don't understand [19:16:01.0651] The usefulness of streaming is that you can get partial responses out, I don't see how this can work with JSON objects becasue you have to wait for a closing `}` [19:16:25.0689] streaming also relates to streaming things out without holding everything in memory, something which doesn't make sense for json [19:16:36.0025] request from note takers: speakers, please add conclusions to your talks [19:16:42.0176] sometimes you don't want the whole result [19:17:32.0508] The usefulness is that you don't need to store the whole buffer in memory in order to parse it, though a partial-result API is worth exploring [19:17:34.0360] let's say i want `engines.node` from package.json; once i know i've parsed the "node" property in the "engines" object i can stop parsing json [19:17:44.0335] * let's say i want `engines.node` from package.json; once i know i've parsed the "node" property in the "engines" object i can stop parsing json, there's no need to wait for anything else [19:18:01.0516] But what are you getting out of the stream? [19:18:19.0757] > <@jridgewell:matrix.org> The usefulness of streaming is that you can get partial responses out, I don't see how this can work with JSON objects becasue you have to wait for a closing `}` it can optimistically parse it. for `{ a: [1, 2] }` it can be a stream of event: enter "a"; start array; enter 0, value 1; enter 1, value 2; end array; end "a"; [19:18:19.0858] > <@littledan:matrix.org> Can you elaborate on what you think hasn't been explored? As many others, I do not get it, why "the single shot one" has to be "objected" to, if there is not a "streaming one". Advancing the singleShot one would not prevent another new take at the streaming one in the future. Why is this compromise not being explored, or at least given some thought to reconcile on this in some weeks... [19:18:35.0856] streaming makes sense even for a syntax that requires a closing bracket [19:18:46.0309] > <@jridgewell:matrix.org> But what are you getting out of the stream? `{ "engines": { "node": "something"` is all i need to extract `engines.node` [19:18:54.0017] > <@christianulbrich:matrix.org> As many others, I do not get it, why "the single shot one" has to be "objected" to, if there is not a "streaming one". Advancing the singleShot one would not prevent another new take at the streaming one in the future. Why is this compromise not being explored, or at least given some thought to reconcile on this in some weeks... it _has_ been considered and explicitly object to by moddable, i'm confused [19:19:00.0355] what is "more exploration" here? [19:19:01.0809] > <@christianulbrich:matrix.org> As many others, I do not get it, why "the single shot one" has to be "objected" to, if there is not a "streaming one". Advancing the singleShot one would not prevent another new take at the streaming one in the future. Why is this compromise not being explored, or at least given some thought to reconcile on this in some weeks... Could you give an example of a hypothetical compromise? I think this is what bakkot has been working on for 2 years... [19:19:47.0157] > <@jackworks:matrix.org> it can optimistically parse it. for `{ a: [1, 2] }` it can be a stream of event: enter "a"; start array; enter 0, value 1; enter 1, value 2; end array; end "a"; This looks like good-olde SAX! [19:20:04.0110] A use case I have for JSON streaming is that I get JSON objects through a WebSocket and I want to pipe chunks to the parser and get notified once a whole object has been consumed [19:20:33.0419] > <@littledan:matrix.org> Could you give an example of a hypothetical compromise? I think this is what bakkot has been working on for 2 years... No, as I've said, on Kevin's side there are no more compromises to be made any more. He did everything he could do. It is the other side. [19:21:01.0652] the use case I heard is they're dealing with GB-size of JSON so I think they'll need parse a single JSON in stream, not many JSONs concated [19:21:16.0532] If I am correct, bakkot indicated that if the proposal was split, they would not be taking up the streaming API portion as champion. phoddie, would you be willing to champion the streaming API independently if the proposal was split? [19:21:31.0457] I have my own json streaming parser because some JSON files are too big to be stored in a string in V8 [19:22:06.0690] > <@nicolo-ribaudo:matrix.org> I have my own json streaming parser because some JSON files are too big to be stored in a string in V8 is it on github? [19:22:20.0346] Christian Ulbrich: I am having trouble understanding what you meant by "Why is this compromise not being explored, or at least given some thought to reconcile on this in some weeks..." -- do you see a potential compromise besides the two options (including or excluding a streaming API) that either side could take? [19:22:29.0349] > <@jackworks:matrix.org> is it on github? https://gist.github.com/nicolo-ribaudo/c5b09c43a10a99fd92c90e81e60732ec [19:23:13.0672] neat [19:23:29.0221] https://github.com/tc39/proposal-arraybuffer-base64/issues/13#issuecomment-1738345569 > I understand your position to be that the one-shot APIs are sufficient because they can be used to implement streaming with reasonable efficiency and without significant future compatibility concerns. If that is indeed the case, I will withdraw my objection. [19:23:33.0887] > <@nicolo-ribaudo:matrix.org> I have my own json streaming parser because some JSON files are too big to be stored in a string in V8 interesting that the object then does fit in memory [19:23:35.0747] * breaking news: https://github.com/tc39/proposal-arraybuffer-base64/issues/13#issuecomment-1738345569 > I understand your position to be that the one-shot APIs are sufficient because they can be used to implement streaming with reasonable efficiency and without significant future compatibility concerns. If that is indeed the case, I will withdraw my objection. [19:24:01.0883] > <@littledan:matrix.org> interesting that the object then does fit in memory You need the magic Node.js flag to increase memory limit :P [19:24:12.0050] > <@ljharb:matrix.org> breaking news: https://github.com/tc39/proposal-arraybuffer-base64/issues/13#issuecomment-1738345569 > > > I understand your position to be that the one-shot APIs are sufficient because they can be used to implement streaming with reasonable efficiency and without significant future compatibility concerns. If that is indeed the case, I will withdraw my objection. yay! [19:24:37.0809] > <@littledan:matrix.org> Christian Ulbrich: I am having trouble understanding what you meant by "Why is this compromise not being explored, or at least given some thought to reconcile on this in some weeks..." -- do you see a potential compromise besides the two options (including or excluding a streaming API) that either side could take? Quite frankly, I have the impression, that someone is not open for a compromise and if we reach this point, consensus becomes very hard. There are possible compromises, as rbuckton has for example suggested. [19:25:41.0757] you mean splitting the proposal? yeah, that's what most of the committee was advocating for. [19:26:10.0086] > <@nicolo-ribaudo:matrix.org> You need the magic Node.js flag to increase memory limit :P I have a wrapper for `node`, that sets `--max-old-space-size=16384` all the time, to consume my GB-JSON's! :) [19:26:23.0464] There are people who don't use kelvin for temperature? [19:26:36.0435] > <@christianulbrich:matrix.org> I have a wrapper for `node`, that sets `--max-old-space-size=16384` all the time, to consume my GB-JSON's! :) you can set that in NODE_OPTIONS and not need a wrapper ftr [19:27:33.0273] > <@ljharb:matrix.org> you can set that in NODE_OPTIONS and not need a wrapper ftr I know! :) [19:27:49.0830] > <@waldemarh:matrix.org> There are people who don't use kelvin for temperature? Of course I don't, I use the *reasonable* Degrees Temp system xanthir.com/b58m0 [19:28:06.0901] > <@nicolo-ribaudo:matrix.org> https://gist.github.com/nicolo-ribaudo/c5b09c43a10a99fd92c90e81e60732ec oh but it does not emit JSON as stream [19:28:56.0767] Jack Works: You are looking for a SAX-parser for JSON [19:29:14.0603] > <@tabatkins:matrix.org> Of course I don't, I use the *reasonable* Degrees Temp system xanthir.com/b58m0 climate change means that 100F is no longer a reasonable upper limit for day-to-day temps tho :-/ [19:29:18.0168] tabperature [19:29:20.0277] does someone have a link to these slides? [19:29:28.0509] i missed the rationale for why this is worth doing in TC39 [19:29:44.0719] > <@ljharb:matrix.org> climate change means that 100F is no longer a reasonable upper limit for day-to-day temps tho :-/ Luckily 100T is 108F, so we're still good fo9r a bit [19:29:52.0727] > <@shuyuguo:matrix.org> does someone have a link to these slides? it was not posted in the agenda [19:29:58.0708] Something like -> https://stackoverflow.com/questions/4373233/is-there-a-saxparser-that-reads-json-and-fires-events-so-it-looks-like-xml although I have not checked it all... [19:29:59.0778] yes, that's why i'm asking [19:30:06.0217] > <@shuyuguo:matrix.org> i missed the rationale for why this is worth doing in TC39 This affects Intl's locale data model [19:30:21.0372] I mean, the rg idea at least [19:30:50.0762] new APIs would probably come from the web (I think Ben said this already) [19:32:35.0101] also, mu isn't part of Intl.Locale yet [19:33:30.0275] would love to know how `mu` ended up being the key (evidently "measurement unit" but that doesn't suggest temperature at all...) [19:33:39.0216] what is the addition then? is it to 402? [19:33:58.0617] > While the freezing point is pretty rando, it does at least mean that the 0 point is roughly as cold as it gets in temperate parts of the world. (And measuring subzero is basically just for fun anyway; below that it's all "lethally cold" and the precise number doesn't matter anyway.) This is very SF bay centric. Many parts of the US regularly see entire months where the temperature doesn't go above 0. They're not Antarctica. This is just wrong. [19:34:02.0344] In fact, Ecma leadership has in the past encouraged us to *not* apply the single-objector model and use a more flexible consensus interpretation, as other TCs do [19:34:34.0618] > <@rkirsling:matrix.org> would love to know how `mu` ended up being the key (evidently "measurement unit" but that doesn't suggest temperature at all...) I think the intention is to allow future extension beyond temperature [19:34:48.0726] fair enough [19:35:18.0159] > While the freezing point is pretty rando, it does at least mean that the 0 point is roughly as cold as it gets in temperate parts of the world. (And measuring subzero is basically just for fun anyway; below that it's all "lethally cold" and the precise number doesn't matter anyway.) * > While the freezing point is pretty rando, it does at least mean that the 0 point is roughly as cold as it gets in temperate parts of the world. (And measuring subzero is basically just for fun anyway; below that it's all "lethally cold" and the precise number doesn't matter anyway.) This is very SF bay centric. Many parts of the US regularly see entire months where the temperature doesn't go above 0 Fahrenheit. They're not Antarctica. This is just wrong. [19:35:34.0071] wait why fahrenhe [19:35:41.0914] eight chars [19:35:44.0914] it's already so long, what's 2 more characters [19:35:48.0411] there's some hard limit on 8? [19:35:50.0036] e.g., "en-GB-u-fahrenhe-horsepow" [19:36:03.0683] this is the BCP47 grammar [19:36:07.0096] OH horse pow [19:36:07.0476] i see [19:36:18.0195] > <@shuyuguo:matrix.org> there's some hard limit on 8? yes: https://unicode.org/reports/tr35/#Unicode_locale_identifier [19:36:28.0195] Yeah but as I said at the end of that quoted section, it doesn't really matter. Those temps are all lethal and without major differences in effect. [19:36:47.0754] lethal like if you're outside naked? [19:37:01.0861] yeah, if you're exposed without protection [19:37:03.0318] I definitely notice a difference between when it's 0 and -20 and -40 [19:37:19.0886] > <@rkirsling:matrix.org> would love to know how `mu` ended up being the key (evidently "measurement unit" but that doesn't suggest temperature at all...) It was decided recently in https://unicode-org.atlassian.net/browse/CLDR-15933. I pushed back against the accepted syntax but didn't die on the hill. The idea is that you can eventually stick arbitrary units in `-u-mu` not just temperature units. [19:37:28.0929] hmm, I don't think being outside naked is the most practical basis for measure [19:37:54.0907] > <@gibson042:matrix.org> yes: https://unicode.org/reports/tr35/#Unicode_locale_identifier https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1 is also related right? [19:37:58.0110] good thing i'm not basing it on that? [19:38:17.0643] > below that it's all "lethally cold" and the precise number doesn't matter anyway [19:38:24.0783] this sentence is only true for naked people [19:39:19.0001] if you're going for a practical system, you should assume people can use clothing and/or technology to compensate for the weather in the place they live [19:39:19.0595] No, incorrect. You said you feel a difference between -20 and -40. That's not "a precise number"! Those are very large increments and reasonable to be detectable. [19:39:53.0310] people can and do care about small differences, a mere few degrees, across most of the 0-100 range [19:40:06.0376] 🤔 hmm okay [19:40:58.0664] i care about the 0-100 range covering a useful temperature range (tho at a lower priority than the other numeric reasons) [19:41:27.0502] if I was designing a temperature scale, I guess the size of the unit, and not the bounds, would be the most important thing to get right [19:41:31.0149] for the same reason that people set up % ranges so that 0%-100% are the useful range, even if numbers outside of that range occur [19:41:31.0327] but what about -0? [19:42:02.0362] yes, that's the reason. RFC 5646 is part of BCP 47, which UTS #35 explicitly aligns with. And the specific RFC text is "_All subtags have a maximum length of eight characters._" [19:42:05.0312] Yeah, the size is important, and I think F has a better size than C. T has a similar degree size to F. [19:42:23.0279] like if I wanted to change the thermostat by integral amounts, those integral amounts should be the minimum increment that I would want (something like 0.25 degrees F) [19:42:32.0757] 10F differences roughly correspond to significant changes in clothing [19:42:52.0728] ...you want to adjust the temperature of a room in *quarter degrees*? [19:42:57.0384] and 0.25F differences are about the minimum you can detect in air temp [19:43:08.0133] no, I want them to be whole numbers [19:43:23.0265] meaning my temperature system would choose unit sizes of about 0.25F [19:43:30.0664] and the bounds would be less important [19:43:45.0314] that's a lot of confidence in heating and cooling systems [19:43:53.0520] i was surprised at the fineness of the difference you apparently want to control, not the way they are expressed [19:44:16.0444] yes, I've read that that's about the limit of human differentiation in air temp [19:44:17.0764] yeah, that's a degree of precision that's not realistically obtainable, and i'd say not actually meaningful even if it were obtainable [19:44:52.0465] "ah, I prefer the room to be at 72.5, 72.25 is just too chilly" [19:45:11.0738] hey, maybe we will one day have better technology [19:45:16.0269] (Even expressing single F degree preferences is on the edge of silliness imo. I think 2-degree increments is about right.) [19:45:19.0452] history shows we will [19:45:28.0183] So C degrees are about the smallest *meaningful* unit for room temperature, I think [19:45:33.0003] 1 degree F makes a *very* big difference in my household [19:45:33.0586] I have occasionally found going to turn the thermostat down by a single degree, then after a while going to turn it up by a single degree, and so on [19:45:55.0914] it is possible this is just my own internal regulation being off but it is also possible that I really do want a finer level of control than 1 degree F [19:45:57.0717] sure, thermo systems have hysteresis and overshoot [19:46:15.0120] it may not be overshoot [19:46:15.0627] i'm saying that the precise difference of 1°F is indeed perceivable and matters [19:46:50.0709] i hate thermostats in celsius because it's much harder to get the precise control i want [19:46:59.0079] yes, a thermostat's interval should be somewhere between 0.25 and 1.0 F [19:47:02.0764] i agree it's perceivable. i don't agree it matters to most people, especially not enough to affect the degree size such that the useful temperature range would be 300-400 degrees wide ^_^ [19:47:43.0798] TabAtkins: maybe the temperature system is fine-grained around room temp and coarse as it goes out from there? [19:47:49.0886] like floating point where 0 is room temp [19:47:50.0719] omigod no [19:48:03.0760] ... maybe yes though [19:48:05.0381] The best scale should preferably get rid of fractional units, because then it would work flawlessly in the browser! [19:48:11.0001] get that experimental metric system nonsense out of here ^_^ [19:48:30.0399] non-linear measurements are completely out [19:48:44.0326] hey, don't knock it until you've tried it [19:48:50.0176] I have! [19:48:57.0010] and it was great? [19:49:05.0874] it's not a vector space, no it's terrible [19:49:38.0279] now I want to try it [19:49:45.0972] the concept of a temperature range is completely destroyed. you can only talk about specific endpoints [19:49:54.0590] "10 degrees" is a meaningless expression [19:50:36.0654] it would also completely destroy the other pillar of my proposal, which is "trivial conversion between human-relative and absolute" [19:50:36.0853] Just add `° C` and it becomes useful! [19:50:51.0104] Christian you're fired [19:50:57.0468] but you instead you could ask people to turn up the thermostat by a "major third" :P [19:51:04.0443] * but instead you could ask people to turn up the thermostat by a "major third" :P [19:52:26.0860] did the negated in/instanceof operators get stage 1 [19:52:38.0767] The temperature setting in my not-so-cheap car is definitely broken. 20° C is cold and 21° C is too hot. TabAtkins you should probably come over to Germany to get your ideas into ACs in German cars! [19:52:46.0246] yes [19:52:51.0067] (an *exponential* range is reasonable in some contexts, like decibels, but it needs specific reasoning) [19:53:04.0032] > <@devsnek:matrix.org> did the negated in/instanceof operators get stage 1 I thought so [19:53:06.0463] nice [19:53:17.0799] yeah everyone had to say "i support this" in the spreadsheet [19:53:40.0963] when you say spreadsheet do you mean hackmd or something else [19:53:53.0960] the tcq-replacement spreadsheet [19:53:55.0943] the TCQ replacement [19:54:02.0407] snek: google docs spreadsheet [19:54:17.0508] I kind of feel like the imminent problem got resolved but the meta discomfort lingers [19:54:31.0263] i might be blind but i don't see a link to that in the reflector issue [19:54:44.0825] phoddie: Thanks for giving this more thoughts. [19:54:54.0714] https://docs.google.com/spreadsheets/d/1Us6MFx3WB6E8K5jJ7m1j5jEa9OUOuwgx60RXwzfI7JE/edit#gid=0 [19:54:56.0190] the meta discomfort has lingered since i first started showing up to these meetings and was dismayed by the "we say consensus but mean unanimity" process [19:54:56.0600] > <@devsnek:matrix.org> i might be blind but i don't see a link to that in the reflector issue "draft schedule", second bullet on the page [19:54:59.0714] well broad use of floats implies it's broadly useful [19:55:06.0025] or, sorry [19:55:10.0446] that's the agenda not the queue [19:55:15.0182] we need to still talk about the process imo [19:55:36.0735] that's why we use exponential ranges, in fact, to avoid fp errors for large numbers [19:55:52.0086] possible but I am personally not willing to drive such a discussion [19:55:53.0887] "that's 120 decibels" rather than "that's 10^12 units" [19:56:21.0974] (assuming a context where bel is a x10, it depends on usage) [19:56:57.0372] like, kevin is still being asked to prove something that only peter cares about? companies care about "culture", and this is a... dispreferred, let's say, part of our culture [19:57:32.0445] that's something that's asked all the time [19:57:38.0498] > <@tabatkins:matrix.org> yeah everyone had to say "i support this" in the spreadsheet look, I just wanted to be clear ok? 😅 [19:57:53.0035] i've been asked to prove the utility of Symbol.isRegisteredSymbol, for example :-p [19:58:09.0476] i think this is a fine and reasonable outcome for the base64 proposal [19:58:13.0857] Sometimes people need to be convinced and cared for, one by one, that's a consequence of consensus. [19:58:26.0363] okay i will fight some of you at lunch then [19:58:33.0396] (ง'̀-'́)ง [19:58:43.0711] definitely down for a lunchtime chat [19:58:44.0717] i'm alright with advancement by cage match [19:59:42.0425] ➡️ #TDZ [19:59:59.0327] > <@ljharb:matrix.org> i've been asked to prove the utility of Symbol.isRegisteredSymbol, for example :-p i don't think we're at an impasse though, but i also asked for use cases, not like... a lot of extra work? [20:00:18.0153] sure, fair, i was mostly just ribbing with that particular example [20:00:24.0653] we had to do that for RegExp.escape too tho [20:00:27.0813] peter did say he would help with the work [20:00:31.0247] * we had to do that for RegExp.escape too tho, and that research was a lot of extra work that kevin did [20:00:33.0111] very well [20:01:22.0700] i do kind of agree with you shu, but i don't think this particular instance was too unreasonable [20:01:36.0137] i'm not looking at the outcome [20:01:58.0610] > <@shuyuguo:matrix.org> okay i will fight some of you at lunch then One-on-one fights, no ganging up. [20:02:13.0444] i'm looking at how the process to reach the outcome involves, invariably, undue emotional labor [20:02:23.0143] this incentivizes behaviors and the kind of people the committee attracts [20:02:41.0651] that sounds like a reasonably stated concern [20:04:13.0805] > <@ljharb:matrix.org> we had to do that for RegExp.escape too tho, and that research was a lot of extra work that kevin did it wasn't just Mark who had that opinion, tbf [20:04:26.0726] Michael Ficarra e.g. also felt that the "no context escapes" thing was important [20:04:29.0018] I did too actually [20:05:37.0095] also very good points [20:05:57.0733] How can test262 use cleanupSome when it is only stage 1? I'm confused [20:06:10.0190] it's stage 2 [20:06:10.0424] I think, albeit is was a bit rough, consensus worked today. I would not questioning consensus, whenever there is heat in a discussion. [20:06:16.0282] * it's stage 2, and it *was* stage 3 [20:06:22.0482] tests were written with it before it was split into a separate proposal [20:06:38.0690] Ah, it's listed as stage 1 on the agenda [20:07:37.0596] tcq is... "back"... [20:15:17.0741] we're going to give TCQ a whirl in the next session... be prepared to quickly revert to the spreadsheet though. big thanks to Brian Terlson for stepping in to turn it off then on again (and write+host TCQ in the first place) [21:08:32.0590] if something isn't currently supported [21:08:36.0074] but could be supported in the future [21:08:43.0276] isn't throwing a reasonable thing to do still [21:08:46.0680] as like a placeholder [21:09:54.0602] Yes. [21:10:15.0283] Usually better than hoping that a behavior change is web-compatible. (It usually isn't.) [21:12:39.0938] Except for the override mistake. Throwing there hasn't made it easier to change to a behavior that does not throw [21:13:22.0387] > <@rbuckton:matrix.org> Except for the override mistake. Throwing there hasn't made it easier to change to a behavior that does not throw there have been several cases of this (e.g., adding literally anything at all changes a throw into a no-throw), it's just that our *default* assumption is that it's OK. [21:13:40.0541] i hope we don't go too far into this specific example, it sounds like a reasonable answer was already given [21:20:36.0730] Disagree; I think we *should* have those debates. [21:20:44.0905] And having an explicit guidance for defaults is good. [21:21:10.0814] yeah i suspect people want to argue about whether these intl apis should throw [21:24:59.0840] Agree -0 is fine, you very very rarely want to distinguish it. [21:26:16.0605] this one is much spicier [21:26:47.0638] my chaotic user side wants this to remain but my implementer side wants this to go away [21:27:01.0414] listen to your implementer side [21:27:14.0373] If we do reach a point of also erroring when outside of the domain of int32/uint32 we should consider ramifications within the ecosystem. Many packages tend to do the same kind of rounding that ECMA-262 does, mostly because they end up forwarding arguments to ECMA-262 functionality that performs the same rounding. If we opt to restrict inputs to the domain of a 32-bit signed or unsigned integer, we may want to consider adding `MAX_INT32`/`MIN_INT32`/`MAX_UINT32` to `Number` so that library authors can more easily validate that domain as well. (i.e., not everyone will know to reach for `x === (x | 0)` or `x === (x >>> 0)` to validate the domain). [21:28:53.0536] definitely can't not support this as an implementer [21:29:54.0609] I'd be wary of not coercing to boolean. truthiness/falsiness is too ingrained into the community at this point. [21:29:59.0575] er yeah [21:30:03.0667] bool is special [21:30:24.0054] like if we have stdlibFunction(v: bool), it should accept objects? [21:31:09.0315] > <@devsnek:matrix.org> like if we have stdlibFunction(v: bool), it should accept objects? Possibly, yes. [21:31:22.0013] if bool is special, numeric string might also special?? [21:31:42.0211] well it just kind of feels like you can compare `if (...)` and `foo(...)` [21:31:46.0135] * well it just kind of feels like you can compare `if (...)` and `foo(...)` here [21:32:16.0528] > <@rbuckton:matrix.org> Possibly, yes. Unless you expect to overload the API with a boolean or an object, perhaps. [21:33:40.0728] I would _prefer_ we validate booleans, but I'm not sure how realistic that is. [21:33:51.0513] It seems people sometime write "x.foo = true" to mean "x.foo = {}" (though I don't like it) [21:34:10.0683] in what context do they do that? [21:34:39.0084] this is adding detail to shu 's point earlier: how much time has been sent writing test262 tests for weird stuff...which is *still* incomplete in its coverage! [21:34:42.0867] how can someone use `true` to mean `{}`? [21:34:48.0240] i'm pretty confused [21:34:55.0785] > <@ljharb:matrix.org> in what context do they do that? I guess they mean `x.foo` will be the default config (something like that) [21:35:24.0202] i'm not sure why `true` would be a reasonable stand-in for an object literal, unless it's an explicit part of the api [21:35:25.0848] that sounds like weird DOM setters? [21:35:37.0058] it just like `x.fooEnabled` [21:36:55.0323] Rollup has some options that accept either `true` or an object, for example `treeshake: true` or `treeshake: { thatThing: true, theOtherThing: true }` [21:37:03.0223] But it's an explicit API overload [21:37:11.0181] > <@ljharb:matrix.org> i'm not sure why `true` would be a reasonable stand-in for an object literal, unless it's an explicit part of the api because it works today in most apis. So someone might use that pattern. I myself don't use that pattern. [21:37:11.0312] Not accidental [21:38:09.0825] it seems really weird to me to have a config API where an empty object has an effect (i say that while maintaining a project that has that weird api, and i don't like it either) [21:38:38.0998] * it seems really weird to me to have a config API where an empty object has an effect (i say that while maintaining a project that has that weird api, and i don't like it there either) [21:39:20.0430] It may be not intentional, it just works if u don't check boolean and rule out them. [21:39:21.0565] In the rollup case, an empty object is equivalent to not specifying the option I believe (i.e. each sub-option gets its default value) [21:39:51.0240] > <@ljharb:matrix.org> i'm not sure why `true` would be a reasonable stand-in for an object literal, unless it's an explicit part of the api What about passing JSON.parse() output as an "object" parameter? [21:40:17.0934] The code is like `function (config) { if (config) { ... } }` [21:40:35.0349] It seems like the whole point of this presentation is to say "if you're doing a coercion, just please say why" [21:40:36.0279] i'd expect config to be strictly validated ¯\\\_(ツ)_/¯ [21:40:50.0211] so if you think it's convenient to have a boolean coercion, just say why [21:41:10.0070] > <@ljharb:matrix.org> i'd expect config to be strictly validated ¯\\\_(ツ)_/¯ I guess it's a philosophical difference [21:41:41.0982] ok, but that kind of feels like "i've been badly burned, so my philosophy is to not touch fire" [21:41:42.0939] > <@ljharb:matrix.org> i'd expect config to be strictly validated ¯\\\_(ツ)_/¯ But if that, r&b might not work (the motivation is it just work to replace object) [21:42:14.0373] > <@ljharb:matrix.org> i'd expect config to be strictly validated ¯\\\_(ツ)_/¯ * But if that, tuple&record might not work (the motivation is it just work to replace object) [21:44:50.0297] Re: `GetOption` are we talking about an AO in the spec here or a JS API? [21:46:03.0415] an AO [21:46:22.0329] Bradford Smith: it's a 402 AO [21:47:02.0638] the Date constructor is famously evil [21:47:59.0518] the constructor whom'st've must not be named [21:51:56.0558] The upshot of disallowing implicit coercion is that we can more easily replace primitive arguments with options bags in an overloaded API, should we need to add more functionality to an existing API (for any API that "exists" following adoption of this rule). [21:57:40.0184] you'd think "this API needs a string, I'll give it a string" would be... common sense? [21:57:54.0620] can't believe that's not how all people work [21:58:22.0308] But what if you need to pass in a `{ [Symbol.toStringTag](): string }`? [21:58:36.0954] * But what if you might want to pass in a `{ [Symbol.toStringTag](): string }`? [21:58:41.0891] get out [21:58:57.0754] straight to jail [22:01:11.0099] I mean, disagree about coercion functions - they don't coerce *as argument handling*. They take a specified type and, internally, convert it. ^_^ [22:02:10.0681] > <@michaelficarra:matrix.org> can't believe that's not how all people work I wonder if there's a class of programmers who probably think of this, but backwards: only a string can be accepted, so I can pass in whatever (omit the check for whether my value is a string), secure in the knowledge that the implementation will convert my values to a string [22:02:33.0840] i'm sure there is a class but i suspect it's a very tiny one [22:02:45.0858] For a *few* cases in Python that is indeed how I think - particularly string interpolation. [22:03:06.0855] string coercion in template literals is a critical part of the functionality, true [22:03:12.0926] am I the only one who interpolates only strings? [22:03:16.0004] it'd be really annoying to pass in a number and get an exception [22:03:23.0704] * it'd be really annoying to pass in a number and get an exception. so yes, i think you are [22:03:41.0578] but interpoliterals are a special case, most APIs needn't be like that [22:03:47.0529] > <@michaelficarra:matrix.org> am I the only one who interpolates only strings? same [22:03:48.0333] I rarely want to think about what the "default" string representation of the thing is [22:03:51.0929] I want to just choose one [22:04:12.0022] tbf i probably only pass strings *and numbers* [22:04:36.0081] I would be interested in learning more about how sffc's libraries take advantage of the power of coercion. [22:04:36.0526] > <@michaelficarra:matrix.org> am I the only one who interpolates only strings? tagged templates don't even coerce interpolated arguments. That said, I frequently use numbers and things that have a useful `.toString()`, like `URL`. [22:04:44.0719] haha, not only do I interpolate non-strings, I use interpolation to convert things to strings, rather than `""+` [22:04:47.0836] even numbers, you probably want `toFixed`, not `toString` [22:05:11.0039] > <@pchimento:igalia.com> haha, not only do I interpolate non-strings, I use interpolation to convert things to strings, rather than `""+` same; using a template literal to coerce to a string is actually more *correct* than simply concatenating to one [22:05:17.0790] what about decimals? I wouldn't trust the generation of a digit string [22:05:24.0015] > <@pchimento:igalia.com> haha, not only do I interpolate non-strings, I use interpolation to convert things to strings, rather than `""+` * same; using a template literal to coerce to a string is actually more _correct_ than simply concatenating to one, and is undeniable, unlike `String()` [22:05:29.0731] > <@jesse:igalia.com> what about decimals? I wouldn't trust the generation of a digit string huh? why not? [22:05:54.0134] > <@littledan:matrix.org> huh? why not? I would use toFixed to ensure a certain number of digits [22:06:00.0614] exactly [22:06:04.0400] probably reflects a certain kind of paranoia [22:06:07.0841] > <@ljharb:matrix.org> same; using a template literal to coerce to a string is actually more _correct_ than simply concatenating to one, and is undeniable, unlike `String()` True. when we talked about explicit coercion like `+x`, the immediate "explicit coercion to string" mechanism that came to mind was `${x}`. [22:06:17.0879] I have been called paranoid once or twice... [22:06:17.0909] > <@ljharb:matrix.org> same; using a template literal to coerce to a string is actually more _correct_ than simply concatenating to one, and is undeniable, unlike `String()` * True. when we talked about explicit coercion like `+x`, the immediate "explicit coercion to string" mechanism that came to mind was `` `${x}` `` [22:07:01.0919] `${x}` and `""+x` have different behaviour, right? [22:07:18.0915] `${x}` is like `string.concat` [22:10:55.0792] I don't know what you mean there. [22:11:21.0444] Tab, you are unmuted [22:12:00.0123] Tab muted before you sent that [22:13:03.0861] Okay I'm reading the MDN for string.concat and wtf [22:16:21.0082] yep, template literals and string.concat are correct; + to a string is not [22:16:32.0112] babel had the wrong behavior there and switched to using string concat at one point [22:16:32.0395] sffc: https://googleprojectzero.blogspot.com/2015/08/attacking-ecmascript-engines-with.html [22:16:36.0161] search for "Conversion operators" [22:16:40.0233] this has been known to be a problem for a long time [22:17:52.0124] i dunno, writing tests sometimes is more effort than implementation i think :-) [22:18:13.0149] > <@littledan:matrix.org> I would be interested in learning more about how sffc's libraries take advantage of the power of coercion. I'll make a post on GitHub with examples. [22:18:37.0915] It's hard to validate tests without an implementation of *some* kind to verify your assumptions are correct. [22:18:40.0491] btw can someone advance the queue? [22:18:54.0211] ljharb: Try refreshing [22:19:13.0623] i did twice, still says "stop coercing things" [22:19:25.0442] * i did twice, still says "stop coercing things" at the top, with kevin's name [22:19:33.0984] oh right me too [22:19:34.0861] oops [22:19:38.0725] there we go [22:23:11.0728] I updated https://github.com/tc39/how-we-work/pull/136 [22:23:31.0568] sffc: thoughts on my wording here? > Some APIs intentionally round non-integral inputs, for example as an attempt to provide a best-effort behavior, rather than because the API fundamentally only makes sense with integers. This guideline does not apply to those cases. [22:25:38.0971] > <@shuyuguo:matrix.org> sffc: https://googleprojectzero.blogspot.com/2015/08/attacking-ecmascript-engines-with.html The two CVEs on that page under "Conversion Operators" are bugs in engines, both use-after-free. It's not a bug in user code. It seems unconvincing that bugs in engines of the nature that code linting tools can catch (ASAN) should carry a large amount of weight in changing long-standing spec precedent. [22:26:18.0009] definitionally, all bugs due to conversion operators are engine bugs [22:26:26.0418] the point of this precedent is to remove that class of bugs from being possible [22:27:39.0665] indeed, ASAN can catch stuff like this if fuzzers can generate the right case [22:27:52.0396] but this is all part of the broader "economic cost vs gain" tradeoff [22:28:05.0509] pretty sure V8 does run under ASAN and therefore emperically it is not sufficient to catch all bugs of this class [22:28:14.0733] i'd like to see explicit demonstrated value in the ecosystem first, because we know there is economic cost from the complexity [22:28:50.0633] sffc: why do you find the engine bugs to be unconvincing? [22:29:38.0922] > <@shuyuguo:matrix.org> definitionally, all bugs due to conversion operators are engine bugs No, conversion operators can definitely be author-level bugs; that's what I was pointing out with my comment. Being forced to be explicit about coercion makes me realize that an API *wanted a string in the first place*, rather than the object I thought it was asking for, for example. [22:29:53.0018] I was thinking of bugs like "an attacker was able to run malicious code that changed the definition of Symbol.toPrimitive on some object in order to capture m credit card number" [22:30:54.0835] sffc: exploits are always chained, i don't know if i can find you an example end-to-end that results in stealing a credit card. it also seems an overly high bar to set here, when it is known conversion operator paths are used as gadgets in exploit chains [22:31:14.0365] security == simplicity [22:32:18.0033] > it is known conversion operator paths are used as gadgets in exploit chains Can you share examples of such exploit chains? [22:32:24.0284] * > it is known conversion operator paths are used as gadgets in exploit chains Can you share examples of such exploit chains? [22:34:54.0821] > <@shuyuguo:matrix.org> sffc: why do you find the engine bugs to be unconvincing? This is mischaracterizing my position. Potential for engine bugs is absolutely the type of thing that should be weighed in pros and cons. I only said that it's not convincing to me that this particular class of engine bug is a compelling motivation for bakkot's proposal on its own. [22:35:21.0531] "false" --> true --> "true" --> true [22:35:30.0140] should be explotable [22:37:45.0916] It's also the case that linting tools have become much, much more sophisticated in the last 10 years since the cited CVEs were filed. Both ASAN for C++ code and policies to use more Rust in new components. [22:39:26.0062] > <@sffc:mozilla.org> > it is known conversion operator paths are used as gadgets in exploit chains > > Can you share examples of such exploit chains? here is one where `valueOf` is used to trigger an ArrayBuffer detach, which invalidates assumptions, and ends up trigger arbitrary code execution: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7288 [22:39:47.0498] i am happy to put you in touch internally with V8 security folks and Project Zero (natalie) who has long history battling this [22:40:05.0720] * here is one where `valueOf` is used to trigger an ArrayBuffer detach, which invalidates assumptions, and ends up triggering arbitrary code execution: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7288 [22:40:32.0883] I don't think we're anywhere near using Rust to implement major parts of any of the JS engines in the big three browsers [22:41:19.0586] i'm sorry, i strongly disagree with the hypothetical that "some library would like to ship coercible objects" is in the same ballpark as "please staff a team to rewrite production software in a new language" [22:41:38.0685] in terms of funding the two things like 2, 3 orders of magnitude off [22:41:42.0654] at least [22:42:32.0937] sffc: are there any libraries you know of with significant usage that have implicit coercion as a major part of their API? and of those, which would be impacted by *new builtins* no longer implicitly coercing, and why? [22:42:36.0640] > <@sffc:mozilla.org> It's also the case that linting tools have become much, much more sophisticated in the last 10 years since the cited CVEs were filed. Both ASAN for C++ code and policies to use more Rust in new components. you also don't see new bugs in this area because we spent years hardening this area! it'd be nice if we stop adding new APIs so we don't also need to spend years hardening *those* code paths [22:46:22.0947] Stages have a name? [22:46:55.0260] they used to [22:48:03.0090] …What are the stage names? [22:48:04.0063] removed by https://github.com/tc39/process-document/pull/31 [22:48:54.0990] Strawperson → Proposal → Draft → Candidate → Finished [22:49:19.0367] wow [22:49:22.0852] multiple person is speaking simultaneously so note is not going to be correct [22:49:27.0703] I did not realize we retired the names [22:49:38.0295] please correct notes after you've done speaking [22:49:40.0767] * I did not realize we retired the names; I used them in a presentation last year [22:49:47.0209] * multiple persons is speaking simultaneously so note is not going to be correct [22:49:50.0324] * multiple persons are speaking simultaneously so note is not going to be correct [22:49:55.0341] * multiple persons are speaking simultaneously so note are not going to be correct [22:52:41.0889] `Stage e` isn't bad tbh, because it's 2.7 something [22:52:42.0170] the transcription quality has degraded (that's not a slight against our helpers -- the professional transcriptionist quality has deteriorated significantly) [22:52:53.0325] * eemeli's `Stage e` suggestion isn't bad tbh, because it's 2.7 something [22:55:29.0145] Stage e is sounding increasingly good, I agree [22:56:02.0936] it does *sound* a lot like "stage 3" tho, so maybe not for that reason [22:56:16.0634] We're gonna be presenting at some community event and everyone is going to mishear "Stage e" as "Stage 3" [22:56:24.0519] valid [22:56:27.0015] And we're gonna have to say "E as in Echo" constantly [22:56:37.0283] "2.8 final chapter prologue" it is then [22:56:48.0785] How about stage T :) [22:56:50.0055] "stage pre-3" [22:56:53.0630] * "2.8 final chapter prologue" it is then 😉 [22:56:55.0315] (serious suggestion) [22:56:57.0073] "e as in test" [22:57:02.0606] Yeah, pre-3 was my serious suggestion [22:57:10.0040] i don't want anything with "3" in it [22:57:17.0533] post-2, but not pre-3 [22:57:44.0364] e isn't even a digit, definitely suggests something off [22:57:49.0744] 2T? T for tests [22:57:49.0872] Stage t3st [22:59:12.0334] I feel like "pre-3" fairly clearly indicates "not 3" [22:59:19.0911] so ljharb can you say more about why you don't want "3" in the name? [22:59:32.0359] because it still suggests you can use it [22:59:35.0152] 3 and 3 complete? [22:59:41.0686] I agree in that "pre-3" feels different than "3 " [22:59:46.0851] in this new stage it still must not be used [22:59:49.0539] we need to get away from the stage wording. How about something with "phase ..." [22:59:50.0347] * in this new stage it still must not be used/shipped [23:00:04.0528] Stage 2 Act 2 [23:00:27.0696] > <@ljharb:matrix.org> because it still suggests you can use it .... does it? [23:00:27.0859] I like "Stage E" [23:00:42.0278] I feel like it communicates "not yet stage 3" [23:00:52.0524] which specifically means "not ready" [23:03:04.0810] "Stage ℯ" [23:03:16.0710] that's a small e! [23:03:24.0262] yes, like in math [23:03:33.0635] `e` is the math constant. `E` is just `Math.E` which is weird [23:03:34.0673] U+212F [23:04:05.0645] > "Last time I found such a small ℯ, that if divided by 2, it became negative!" [23:04:32.0821] > <@ljharb:matrix.org> because it still suggests you can use it I am still confused about how "pre-3" suggests you can use it [23:04:33.0710] stage 2.62 [23:04:44.0438] also if it does not go in babel's stage 3 preset, which it won't, then... you can't [23:04:50.0812] We very much can teach the community things, it's just sort of a cost/benefit tradeoff. It's cheaper to tie into existing understandings of Stage 3 [23:04:52.0427] eemeli: yes I would object and I can't believe that needs to be explained [23:04:53.0974] * also if it does not go in babel's stage 3 preset, or int typescript, which it won't, then... you can't [23:05:10.0937] * > "Last time I found such a small ε, that if divided by 2, it became negative!" [23:05:20.0575] > <@bakkot:matrix.org> I am still confused about how "pre-3" suggests you can use it i am claiming that people will gloss over the "pre" and see "3" and think "stage 3". because people's reading comprehension is … inconsistent [23:05:21.0413] So it would be Stage ε [23:05:22.0720] stage `2+` [23:05:40.0641] > <@ljharb:matrix.org> i am claiming that people will gloss over the "pre" and see "3" and think "stage 3". because people's reading comprehension is … inconsistent ok but as long as _tool authors_ don't make that mistake we don't have to care [23:05:57.0558] specific polyfill authors not in this room will make it, so we do have to care [23:06:10.0347] i am happy to discuss specifics privately if needed. [23:06:13.0100] we can just ask the core-JS guy to not ship stuff [23:06:15.0678] it's fine [23:06:22.0999] that has been asked and rejected many times. [23:06:27.0209] our choice of naming cannot force him to ship or not ship things [23:06:29.0584] * that has been asked and rejected many times. so no, it's not fine. [23:06:36.0781] nope but it affects the likelihood of it. [23:06:48.0796] > <@bakkot:matrix.org> we can just ask the core-JS guy to not ship stuff sir. you cannot simply.. stop the rock [23:06:48.0836] ok but I think "pre-3" is fine [23:06:58.0914] in terms of likelihood that he will ship a thing [23:07:09.0483] like, if he is willing to ship a thing called "pre-3" he will ship other things [23:07:10.0334] yes, i get that. i don't think it's fine. we have lots of other alternatives [23:07:23.0305] we do not appear to have lots of other alternatives which are actually viable [23:07:37.0437] 2 + (1-epsilon) [23:07:41.0412] so if concerns about whether that one specific person will ship a thing is the only blocker, I think that is the least of the concerns [23:07:48.0552] so like "e" is nerdy and fun but "2.62" is nerdy _and relevant_ [23:07:59.0414] so I actually think I'm serious about 2.62 😅 [23:08:05.0077] > <@littledan:matrix.org> 2 + (1-epsilon) That is pretty close to 3! [23:08:09.0507] > <@littledan:matrix.org> 2 + (1-epsilon) 2.9̅ [23:08:11.0743] I'm disturbed by the claims of the community being unteachable [23:08:24.0794] > <@bakkot:matrix.org> so if concerns about whether that one specific person will ship a thing is the only blocker, I think that is the least of the concerns it's not just that. that's just one example. [23:08:26.0599] it's not so much they are unteachable.. they are more.. unreachable ? [23:08:35.0337] > <@waldemarh:matrix.org> I'm disturbed by the claims of the community being unteachable it's that their teachability is not predictable. [23:08:45.0487] > <@ljharb:matrix.org> it's not just that. that's just one example. what other examples are there? [23:08:49.0416] I thought there are sites like proposal.es that are well known in the JS community (at least, those who track things) [23:08:58.0192] > <@waldemarh:matrix.org> I'm disturbed by the claims of the community being unteachable it's not that anyone is unteachable, it's that it's a give and take, rather than a waterfall model coming from us [23:09:00.0960] if he ships something, but no other tool does, no one is going to be able to use the thing [23:09:08.0452] which is the desired outcome [23:09:59.0460] stage 2.62 is cute [23:11:58.0723] So we agree on a stage between 2 and 3 but we seem to not to be able to agree on a name for it? So how about `Stage `? [23:12:08.0329] ok just don't call it a stage [23:12:12.0213] just say "consensus on the design" [23:12:59.0203] yeah that's fine with me [23:13:02.0034] ship it [23:13:59.0286] see, i told you this is the fun part :-p [23:14:19.0493] but yes it'd be good to move on [23:16:39.0651] here's a list: https://www.proposals.es/stages/stage3 [23:17:05.0078] we have our own list, https://github.com/tc39/proposals :-) [23:17:15.0502] see, this stuff leaks! [23:17:32.0456] I'd agree with waiting a meeting at least. If I'd realized that tests were going to be a requirement for something like `throw` to remain at Stage 3 if it reached it this meeting, I would have written the tests prior to the meeting. [23:17:40.0861] i mean we kind of did explicitly broadcast it by using the terms publicly, tweeting about them, etc [23:17:54.0984] > <@rbuckton:matrix.org> I'd agree with waiting a meeting at least. If I'd realized that tests were going to be a requirement for something like `throw` to remain at Stage 3 if it reached it this meeting, I would have written the tests prior to the meeting. we don't actually have the new stage yet, so everyone has time [23:18:26.0445] and if this topic motivates people to write their tests, then great [23:18:30.0118] "consensus on the normative content"? [23:18:33.0104] * and if this topic motivates people to write their tests (faster/sooner), then great [23:18:37.0368] if that more precisely captures "all of the details" [23:19:20.0063] or even "consensus on the specification" [23:19:31.0853] Was the queue captured at the end of the first part of this? [23:22:14.0001] yes! [23:22:34.0433] it's above but I will repost [23:22:56.0455] does anybody have a clear memory of why the names were removed from the process doc though? [23:23:45.0520] i have no memory of us removing them [23:24:16.0145] > <@bakkot:matrix.org> sffc: thoughts on my wording here? > > > Some APIs intentionally round non-integral inputs, for example as an attempt to provide a best-effort behavior, rather than because the API fundamentally only makes sense with integers. This guideline does not apply to those cases. Can you tag me on the issue and I'll take a closer look soon but not right now? [23:24:29.0463] > <@rkirsling:matrix.org> does anybody have a clear memory of why the names were removed from the process doc though? https://github.com/tc39/notes/blob/main/meetings/2021-07/july-14.md#renaming-strawperson-to-concept-or-something-better [23:25:05.0887] > <@sffc:mozilla.org> Can you tag me on the issue and I'll take a closer look soon but not right now? done [23:25:20.0123] > <@rkirsling:matrix.org> does anybody have a clear memory of why the names were removed from the process doc though? I remember a discussion a couple years back where we decided to remove them because the names suggested interpretations of the stages which were not necessarily correct. [23:25:32.0101] > <@shuyuguo:matrix.org> i have no memory of us removing them > SYG: I want this to be narrowly about removing the name column from the process document, not about how we as delegates in engaging with the community. [23:25:32.0104] reading the notes has me recalling the discussion now [23:25:46.0857] dang [23:25:54.0975] wasn't expecting to be called out like this [23:26:05.0360] sorry! [23:26:29.0681] thanks! [23:28:55.0622] eemeli: do expressions are still potentially a thing but are almost universally felt to be too clunky for this specific case [23:33:47.0948] > SYG: I'm concretely proposing that we say stage 0, stage 1, stage 2, stage 3, stage 4. > JHX: I think most of us are in China only use "stage 1" or 2, 3, just like that. so. 1. this is good! this was an improvement and 2. relevant for us when bikeshedding the new stage name to remember SYG's rationale from this meeting to avoid mnemonics [23:34:32.0617] bakkot: Really? To me, `do { throw x }` feels pretty ergonomic. [23:34:43.0351] ¯\_(ツ)_/¯ [23:35:05.0883] Function expressions where not in the first version?? [23:35:26.0001] * Function expressions were not in the first version?? [23:35:35.0466] no but they were added over 20 years ago and when a much smaller group of people used JS [23:36:02.0165] > <@softwarechris:matrix.org> > SYG: I'm concretely proposing that we say stage 0, stage 1, stage 2, stage 3, stage 4. > > > JHX: I think most of us are in China only use "stage 1" or 2, 3, just like that. > > so. 1. this is good! this was an improvement > > and 2. relevant for us when bikeshedding the new stage name to remember SYG's rationale from this meeting to avoid mnemonics and 3. underscores the importance of not changing the existing number [23:36:05.0155] * and 3. underscores the importance of not changing the existing numbers [23:36:49.0468] I really like IIAGFEs! [23:37:19.0719] > <@eemeli:mozilla.org> bakkot: Really? To me, `do { throw x }` feels pretty ergonomic. In particular when considering cases where something more needs to be done that just `throw x`, do expressions feel like a pretty good potential solution. [23:37:25.0500] What if we made a function like Error.raise instead of adding syntax? [23:37:37.0112] > <@eemeli:mozilla.org> In particular when considering cases where something more needs to be done that just `throw x`, do expressions feel like a pretty good potential solution. yeah but a lot of cases don't need that [23:37:41.0261] a _lot_ of cases [23:37:54.0419] > <@littledan:matrix.org> What if we made a function like Error.raise instead of adding syntax? would that have the right stack frames? [23:37:57.0697] > <@littledan:matrix.org> What if we made a function like Error.raise instead of adding syntax? * would that have the right stack frames and call site? [23:37:59.0804] Sure, and for them the "plain" `do { throw x }` works pretty well. [23:38:46.0489] > <@ljharb:matrix.org> would that have the right stack frames and call site? why not? seems we could specify it to behave just like throw (and hence inherit whatever ehavior `throw` has) [23:39:00.0323] because we don't specify stack frames at all. [23:39:21.0246] * because we don't specify stack frames at all. and we can't specify API to behave like syntax, which is why `import()` isn't a function, it's syntax [23:39:47.0353] right but then new syntax might have any advantage [23:39:59.0794] *might not [23:40:04.0038] Well we can also not specify `throw new Error()` to not add a new random stack frame anyway :P [23:41:15.0881] Michael Ficarra: yes, alternative 2 is safe in that way [23:41:19.0283] that is why I suggested it [23:41:58.0515] bakkot: okay then I would like to express my support for that reason [23:42:14.0570] we can specify Error.raise instead of syntax if we want [23:42:41.0880] Erorr.prototype.throw [23:42:45.0804] As a getter [23:42:55.0141] `new Error().throw` like await in rust [23:43:24.0768] eww [23:43:29.0522] then you can't throw a non-error [23:43:32.0834] * then you can't throw a non-error that way [23:43:36.0755] * then you can't throw a non-error that way, it'd have to be static [23:43:45.0945] import is syntax instead of a function for static analysis, not because we are inherently unable to add functions [23:43:54.0124] you shouldn't throw non-errors [23:43:59.0647] i think it is a mistake that you can [23:44:13.0548] I may have missed it. Did anyone suggest that throw should have approximately the same precedence as `yield`? You would just define the rule so that its production is `ThrowExpression ::= throw ShortCircuitExpression` [23:44:20.0581] > <@devsnek:matrix.org> import is syntax instead of a function for static analysis, not because we are inherently unable to add functions no, it's because the import site needs to know where it's being imported from [23:44:27.0535] > <@devsnek:matrix.org> import is syntax instead of a function for static analysis, not because we are inherently unable to add functions * no, it's because the import site needs to know where it's being imported from. you can do static analysis with globals just fine. [23:44:28.0297] ljharb: `Object.getOwnPropertyDescriptor(Error.prototype, 'throw').get.call(anything)` [23:44:41.0172] it's beautiful! 😍 [23:44:48.0695] > <@ljharb:matrix.org> no, it's because the import site needs to know where it's being imported from. you can do static analysis with globals just fine. it can know where its being imported from if its a function [23:44:55.0106] there's nothing preventing that [23:45:27.0879] > <@michaelficarra:matrix.org> ljharb: `Object.getOwnPropertyDescriptor(Error.prototype, 'throw').get.call(anything)` `Reflect.getIntrinsic('get Error.prototype.throw')::(anything)` is nicer :-p [23:45:28.0122] we even have the machinery in the spec to do that, its very simple [23:45:50.0120] > <@devsnek:matrix.org> it can know where its being imported from if its a function no it can't, because of some principle about how functions can't be have differently based on where you call them. that was a *hard* blocker. [23:45:59.0689] > <@devsnek:matrix.org> it can know where its being imported from if its a function * no it can't, because of some principle about how functions can't behave differently based on where you call them. that was a _hard_ blocker. [23:46:12.0374] > <@ljharb:matrix.org> then you can't throw a non-error that way, it'd have to be static We can put it on `Object.prototype` and it works almost everywhere :) [23:46:18.0179] what does behave differently mean [23:46:21.0907] not on null objects :-p [23:46:27.0994] from my perspective it behaves the same [23:46:30.0271] > <@devsnek:matrix.org> what does behave differently mean it means the function can't know from where it was called [23:46:33.0671] It means "no dynamic scoping" [23:46:45.0973] > <@devsnek:matrix.org> what does behave differently mean * it means the function can't know from where it was called. and dynamic import resolves differently based on where it was called [23:46:53.0830] * The offiacil name is "no dynamic scoping" [23:46:58.0343] * The official name is "no dynamic scoping" [23:47:04.0773] bare specifiers in node can resolve to different things based on position in node_modules; relative URLs based on the current URL, etc [23:47:09.0774] And (continuation) replace the production `ConditionalExpression ::= ShortCircuitexpression` with `ConditionalExpression ::= ThrowExpression` instead [23:48:12.0959] I believe my suggestion prohibits the assignment expressions as is desired [23:48:25.0312] without lookahead [23:48:27.0208] rbuckton: how dare you presume that arbitrary percentages people say in plenary have data to back them up [23:49:39.0434] Imagine the day we'll see a 99.9% percentage backed by data [23:56:31.0387] Rob Palmer: I hope we'll still have time for incubation calls? [23:57:22.0778] we also need to find out about 2024 meeting schedule Rob Palmer [23:57:36.0062] * I believe my suggestion prohibits the assignment expressions as is desired Nevermind - it's been too long since I looked at the grammar carefully. [23:57:46.0456] the first two are on the agenda already [23:57:56.0354] * the first two 2024 meetings are on the agenda already [23:59:04.0341] I only see Jan? [23:59:45.0856] > <@bradfordcsmith:matrix.org> I may have missed it. Did anyone suggest that throw should have approximately the same precedence as `yield`? You would just define the rule so that its production is > `ThrowExpression ::= throw ShortCircuitExpression` `throw` with the precedence of `yield` would require parenthesis in pretty much all cases where it would be used. [23:59:55.0321] oh right sorry, just the first one, my bad [00:00:03.0760] > <@rbuckton:matrix.org> `throw` with the precedence of `yield` would require parenthesis in pretty much all cases where it would be used. With the additional drawback that that would be forever [00:00:10.0828] correct. [00:00:13.0906] > <@ljharb:matrix.org> then you can't throw a non-error that way, it'd have to be static I don't like the getter option but I am ok with saying you can't use this feature to throw a non-error [00:00:25.0896] you can still do that in other ways but we don't have to make it easier for you [00:00:55.0936] the same's true for throw expressions themselves, you can already `(function () { throw e }())` :-p [00:01:20.0764] in hindsight, it seems like a lot of work to go through to avoid a couple extra tokens [00:01:38.0333] > <@ljharb:matrix.org> the same's true for throw expressions themselves, you can already `(function () { throw e }())` :-p the point of throw expressions is to make it easier to throw errors; that it also lets you throw non-errors is incidental [00:01:40.0350] I would place my preference for not requiring parens around `throw` expressions at at least the same level that @bakkot has placed his concern about reader confusion compared to ThrowStatement. [00:01:43.0761] `(() => { throw e })()` is shorter i think [00:02:47.0076] same number of tokens? [00:03:21.0275] `(_ => { throw e })()` [00:03:28.0791] > <@rbuckton:matrix.org> I would place my preference for not requiring parens around `throw` expressions at at least the same level that @bakkot has placed his concern about reader confusion compared to ThrowStatement. my concern about `,` is held fairly strongly but my concern about `0, throw a ? b : c` not throwing `a` is even stronger, to be clear [00:03:32.0956] that just _can't_ throw `a` [00:03:38.0288] it _can't_ [00:04:03.0759] > <@bakkot:matrix.org> that just _can't_ throw `a` (+ only to that specific part :) ) [00:04:27.0572] rbuckton: add me as reviewer for throw expressions, I have some ideas on the specifics for how we accomplish alternative 2 [00:04:38.0462] How does one now get on the list to be invited to an incubator call? [00:04:46.0418] Shu's old repo isn't used anymore, right? [00:05:03.0607] uhh yeah I think that's the place [00:05:11.0710] > <@michaelficarra:matrix.org> rbuckton: add me as reviewer for throw expressions, I have some ideas on the specifics for how we accomplish alternative 2 I'd appreciate it, though I believe alternative 2 is the (almost) worst case. [00:05:22.0992] > <@bradfordcsmith:matrix.org> Shu's old repo isn't used anymore, right? they should be used [00:05:28.0146] > <@bradfordcsmith:matrix.org> Shu's old repo isn't used anymore, right? * it should be used [00:05:33.0725] Bradford Smith: https://github.com/tc39/incubator-agendas [00:05:50.0117] ok, I just thought since shu isn't doing anymore... [00:05:58.0578] > <@rbuckton:matrix.org> I'd appreciate it, though I believe alternative 2 is the (almost) worst case. sounds like the best tractable case though [00:06:02.0525] it would have moved to the tc39 team area [00:06:13.0729] > <@bradfordcsmith:matrix.org> it would have moved to the tc39 team area indeed it is [00:06:38.0108] unless I'm missing something? [00:06:42.0880] I see, the label on my bookmark is wrong [00:10:40.0182] Well, I got my hopes up in July that the trailing infix punctuator ban would be sufficient. I should have tempered my expectations a bit. [00:10:59.0098] I guess I'll have to leave myself a reminder to check back on the incubator-agendas repo next week, once folks have had a chance to add issues representing their calls? [00:11:53.0999] > <@bradfordcsmith:matrix.org> I guess I'll have to leave myself a reminder to check back on the incubator-agendas repo next week, once folks have had a chance to add issues representing their calls? or a reminder to prod the folks to add issues representing their calls 🙂 [00:12:08.0465] > <@michaelficarra:matrix.org> sounds like the best tractable case though Waldemar's comments seemed to indicate otherwise. [00:13:04.0025] But I'd appreciate any suggestions you have. [00:16:03.0499] waldemar did not like that alternative but I was hoping he would be willing to accept it as a compromise position [00:16:16.0223] we ran out of time to discuss it before I got clarity on that though [01:33:15.0652] wrt the negated-in proposal, I see Luca Casonato has gotten prettier updated https://github.com/prettier/prettier/pull/15468 2023-09-29 [22:05:09.0647] I want to do a temperature check: do you think this is a problem worth solving? if the module includes async dependencies, it might miss some startup event in some environments (e.g. onInstall in web extensions, we really hit that problem in the past). Proposal :add a new directive or something, to assert the module has no async dependencies. if assert failed, it will fail the whole graph. Fail-fast can help to find the bug early. "asserts sync"; [22:38:27.0095] so basically, a way to prevent someone adding TLA in one of your deps? i asked for this iirc during TLA at one point, and i love the idea - otherwise you’d need an expensive lint rule to find it. [23:16:08.0575] So this is a pragma that is an early error? [23:46:25.0941] I think the ideal form would be like `with { forbidAwait: true }` or something, in an import [23:46:37.0988] Though I guess it would be annoying to have to put it in all of them [23:47:00.0263] Seems like a problem space worth investigating at least [15:54:26.0336] yes, my first iteration is using import assertions, but now it's no longer an assertion [15:56:06.0854] and when you add it, you do not want to add it to some dependencies and some not, so a new pragma is the best solution I can think so far [15:56:28.0125] but the committee doesn't like the new pragma IMO? [15:56:36.0504] * but the committee doesn't like adding a new pragma IMO?