2025-02-03 [10:33:34.0590] Reading through https://news.ycombinator.com/item?id=42876840, it seems like the most wanted proposals are Records&Tuples and pattern matching [10:59:20.0837] Let's do both of them! [15:53:29.0839] It looks like we will get a **Community Event in Seattle** on the evening of **Thursday 20th February.** Please can folk who are attending volunteer some talks! - [**Call For Speakers**](https://github.com/tc39/Reflector/issues/550) SeattleJS are asking us to provide all the content for the evening, so I hope we can deliver lots of exciting talks. 2025-02-05 [17:17:59.0577] Does anyone know why we decided not to look for private fields on the prototype chain of any object? This somewhat came up in 2 different proposal discussions lately: https://github.com/tc39/proposal-class-access-expressions/issues/26 and https://github.com/ljharb/proposal-error-stack-accessor/issues/3 (the latter is for a internal slot but same idea) [17:21:16.0610] It would likely break a ton of "brand checks" use cases, but really there isn't an easy way to even create a helper to search the prototype chain as one cannot get a "ref" for the private field. [17:22:14.0304] * It would likely break a ton of "brand checks" use cases, but the problem is that there isn't any way to even create a helper to search the prototype chain as one cannot get a "ref" for the private field. [00:11:46.0608] the helper would need to take a callback: `(o) => #p in o` [06:26:14.0849] It's hard/impossible to truly preserve privacy while also working with prototype chains, especially if you want to stick strictly to object-like semantics and not invent on a new thing. Also, the SES crowd insisted on WeakMap analogy semantics in particular, which has no prototype chain walk. [08:47:27.0208] also if it used the prototype chain then they wouldn’t be private fields, they’d be public ones, because anything can extend anything else at any time [08:47:38.0688] * also if it used the prototype chain then they wouldn’t be _private_ fields, they’d be public ones, because anything can extend anything else at any time [08:54:50.0475] well, the space of possibilities is large, but yeah we had trouble finding a mechanism that would preserve privacy, have inheritance *and* have a number of other properties that people were interested in [12:39:40.0329] > <@ljharb:matrix.org> also if it used the prototype chain then they wouldn’t be _private_ fields, they’d be public ones, because anything can extend anything else at any time And wouldn't have been able to minify them with so much confidence. Local lexical lookup is great for AOT transforms 2025-02-06 [19:00:39.0895] Realising this wasn't about matching other private fields with the same, so the name of the field would all still be local and still minifiable. it's more that the lookup would have fewer guarantees. Because proxies, walking the proto chain could have side effects and give different answers. so couldn't assume AOT things like `#p in v === #p in v` [02:02:06.0779] Yeah the fact that looking up a private field cannot trigger any user code is a nice property. Combined with the fact you wouldn't know which object the value came from is probably sufficient reason for this to have been the right choice. 2025-02-07 [07:49:25.0188] This is super early, however — a few of us will be taking the train to go to the A Coruña meeting in May (mostly from NL and UK). If anybody traveling from somewhere in western Europe wants to join us please write me a message by the end of February :) [09:55:25.0724] - **Reminder:** The Feb 2025 Plenary deadline for Stage Advancement is in 24 hours! 2025-02-11 [17:14:45.0064] do i read RegExp.escape correctly that it doesn't care about lone surrogates? it'll just escape them? [17:28:11.0708] yeah [17:28:43.0991] I don't know if that means "doesn't care" since it does explicitly handle them [17:29:09.0286] but it handles them by escaping them [19:27:13.0806] fair. by "doesn't care" i mean it doesn't error out if input is malformed [19:27:24.0205] malformed by having lone surrogates [21:25:13.0507] to me yesthat sounds right [21:25:18.0614] * that sounds right to me yes 2025-02-12 [10:06:37.0764] Given that lone surrogates are valid values in JS strings, that seems like the right behavior, rather than erroring. [13:51:30.0616] Reminder: The [TG5 Workshop](https://github.com/tc39/tg5/blob/main/workshops/2025/106.md) will be held on Friday 21st of February, the day after the plenary meeting. It'll be hosted by F5 (same venue as the plenary). Among other items on the agenda, we'll have a visitor from UCSD to talk about [the MessageFormat study](https://github.com/tc39/tg5/issues/3) and identify other proposals that might benefit from user studies. Registration link: https://forms.gle/jBn3XguosNwJsScy6 _What is TG5?_ TG5 is a task group of TC39 that: - conducts scientific studies on proposals, either "commissioned" by TC39 (e.g., MessageFormat study - to be presented at the upcoming workshop in Seattle), or out of self-driven interest with a clear potential to applicability to TC39 - develops methods, approaches, tools to aid understanding / designing / specifying the language (e.g., executable spec, spec formalisms, navigation within the spec, Proposal Management Tool, etc.) - considers TC39 within the larger ecosystem of programming language design, specification and standardization (e.g., cross-standards research, language drift, decision-making) 2025-02-13 [18:12:46.0535] Reminder: Please register for SeattleJS on Thursday evening 20th Feb if you wish to attend! https://lu.ma/s97y24jd [23:20:35.0923] ah, thanks for the reminder! 2025-02-14 [07:55:40.0456] if anyone would like to join an A/V test call for next week's meeting at 10:00A Pacific (about 2 hours from now), send me a DM [08:03:30.0517] ^^^one volunteer requested! [08:06:39.0601] DM sent 2025-02-16 [19:38:53.0854] In case anyone has not received or accepted the invite, we have a Seattle Matrix channel for in-person logistics. Please say if you would like an invite. 2025-02-17 [14:36:00.0502] 📣 the draft schedule is available on the meeting issue in Reflector: https://github.com/tc39/Reflector/issues/547 2025-02-18 [17:09:34.0583] in case we forget to mention it tomorrow, please do not ever use the `I'm done speaking` button in TCQ. thank you! [17:50:52.0350] TC39 rule: never stop speaking [17:53:36.0804] can we remove the button? [18:07:55.0392] https://github.com/bterlson/tcq/pull/68 [22:57:15.0252] whatever happened to the rewrite? [02:02:03.0156] Looks like Christian Ulbrich and Tom Kopp were working on it here at least up until last June: https://github.com/zalari/tcq/pull/7 [08:11:12.0311] Sign in form with video link will be posted around 9am PT. [09:09:54.0431] Is there an ETA for the video link? I still don't see one in the reflector. [09:20:26.0115] Not quite. Michael is still setting up AV. [09:20:31.0334] Oh I forgot these start at 10 not 9 lol [09:21:25.0553] correct - there is 38 minutes until go time [09:46:51.0824] The video link will be posted on the Reflector very soon [09:51:13.0229] The video link is now posted via [the Sign-in form on the Reflector!](https://github.com/tc39/Reflector/issues/547) [10:03:48.0475] maybe we should add an actual persistent temperature check to tcq [10:05:02.0268] fwiw its PST (-8) not PDT [10:05:23.0244] * fwiw its PST (-8) not PDT (-7) [10:13:55.0630] SUMMARIES ARE GOOD [10:13:57.0322] YAY SUMMARIES [10:24:42.0596] If anyone would like to be the TC39 Liaison to IETF please let the Chairs know or reach out to Samina directly. [10:25:12.0932] * maybe we should add an actual persistent temperature check to tcq (like, physical room temperature) [10:26:49.0908] we already liason with the W3C i18n WG for TG2 [10:27:04.0603] and some WGs from Unicode for that matter [10:27:25.0697] * we already keep track of the W3C i18n WG for TG2 [10:27:41.0170] Only technically, mind. I've a recurring conflict with their call, and Ben has not been able to attend many of their meetings. [10:29:02.0854] please share resources for where folks should go to get involved in TC55 (matrix room, meeting info, etc) [10:29:18.0637] https://wintertc.org [10:29:48.0229] * https://wintertc.org + https://github.com/wintercg/admin [10:31:23.0385] matrix room: #wintertc:matrix.org [10:32:15.0900] rock and roll [10:32:54.0572] Thanks a lot Aki again for all the help with making sure that our technical work follows what Ecma needs [10:33:25.0987] thank you all ECMA folks 🙇 [10:36:45.0996] You’re audible, Aki [10:36:58.0039] oh reminder, there should not be notes during this period [10:37:09.0406] so please remove them and/or tell the transcriptionist to pause [10:37:13.0970] * so please remove them and tell the transcriptionist to pause [10:37:15.0134] it has been paused [10:37:40.0921] Don't worry, we manage also with you out of the call! [10:37:43.0068] and don't discuss here 🙂 [10:37:53.0777] * Don't worry, we do things right also with you out of the call! [10:38:04.0238] of this, I have no doubt 🙂 [10:38:32.0863] You can come back [10:41:12.0539] can we make sure the transcription bot, and transcription human, have resumed? [10:41:35.0032] The human is back and apparently the bot was not running in the first place [10:42:09.0404] Now that Google Docs has "export as markdown", is it time to update the agenda item template? [10:45:28.0593] say more [10:47:15.0668] Allows us to use the standard document styles and get markdown as a result https://snaps.akiro.se/2502_ji3bx.png [10:49:43.0277] the only reason the notes items are they way they are, afaik, is for ease of markdown conversion, so it seems fine to change them? [10:50:20.0533] suggest validating the quality of the export first [10:52:19.0640] Maybe we could try on Thursday, when the agenda is light. To reduce 'risk' if the formatting needs manual fix up [10:53:17.0422] I've used the export for notes for other committees [10:53:20.0055] I'm very happy with it [10:58:02.0640] nicolo-ribaudo: re: linking other web specs, I bet we could figure out how to automatically generate ecmarkup-compatible biblios from web specs if we really want to [10:58:08.0664] the ecmarkup biblios are very simple [10:58:29.0584] gotta snipe tab into supporting it in bikeshed [10:58:58.0974] Right now we just need to link to URL and fetch so doing it manually is probably less effort than making it work automatically, but if we'll need to link to more stuff I'll look into it [10:59:16.0474] Currently we also rely on Infra, but as part of the rewrite we are just going to rely on ECMA-262 built-ins instead [11:11:01.0538] One thing we sometimes do is wrap parts of the transcription in backticks, e.g. when someone references `Object.is`. Do you know if these would carry-through, or would we need to do this by changing the font? [11:12:06.0283] it escapes them, but that's a very easy search & replace [11:12:27.0986] y'all have no idea how many regex search & replaces I do on every meeting's notes [11:13:14.0152] have you considered just asking an LLM to "make it good" :D [11:13:28.0899] 🤮 [11:13:37.0454] can't wait to find out what lovecraftian horrors end up being stage 4 due to that [11:17:40.0453] somehow I feel much more comfortable trusting the speech-to-text than I do a text transform, and I can't explain why [11:18:28.0549] Probably speach-to-text worst case writes nonsense, rather than plausible-looking wrong stuff [11:18:47.0844] the trick with text transforms is to have it generate a diff, which you can then easily review for correctness [11:19:15.0634] also no, modern speech-to-text definitely writes plausible-looking wrong stuff a lot [11:19:31.0417] Eggma showed up a lot in the last TC55 meeting [11:20:01.0761] https://docs.google.com/presentation/d/1LjsJhdTIP3wgo1odtVa-qbfyGU5M1W9YMm0AtKnJJKk/edit#slide=id.p [11:20:21.0239] https://github.com/bakkot/transcribe-to-gdocs/blob/fb863c5a314d078f2a0c60d26cf8774f08dd068a/replacements.js#L35-L46 [11:20:57.0092] eggma is a new one lol [11:21:28.0735] (though this list was when using google's old speech-to-text; whisper is much better and I hear gemini is better still although I have not yet gotten around to hooking it up) [11:24:43.0741] eggman [11:25:35.0267] if Whisper wasn't already better than a human transcriptionist (it probably is), Gemini certainly is [11:26:12.0574] coo coo ca choo [11:27:39.0811] Oh, I missed this in my constraints. I need to be present for the Decorators discussion, so if it can remain after the lunch break I would appreciate it. I will add this to the agenda as a late breaking constraint [11:29:40.0942] except for 100%, right? [11:37:40.0576] 🤓 as someone who has tried/done "professional" transcriptions a while ago, I think Whisper is good at speech-to-text but has terrible/no formatting last I looked [11:39:13.0606] 50% of the human transcriptionists we've hired have actively harmful formatting (double spaces between sentences, linebreaks every few words, etc), so "no formatting" is still superior [11:41:53.0931] yeah agree with that [11:46:37.0493] Not sure if still true today, but in the past the human transcriptionists seem to handle people talking over each other better. Giving each their own `>>` lines [11:47:39.0509] Could someone record a conclusion on the chair election in the notes? [11:48:01.0783] (I'm happy to share the doc link in a DM if anyone needs) [11:49:02.0892] we already have it i believe [11:51:07.0192] Nope, this is it: ### Speaker's Summary of Key Points * List * of * things ### Conclusion * List * of * things [11:51:08.0712] please edit the notes and add a summary and conclusion section, saying who was elected. It is currently missing. [11:51:22.0601] I mean, I just pasted that in [11:51:33.0451] I'm not sure if someone people believe that the earlier text implies the summary/conclusion [11:51:41.0987] but... I just can't make sense of it [11:51:45.0756] oh I read conclusion as conclusion of opinion oops nvm [11:51:57.0384] * we already have it i believe [11:51:59.0731] we just don't have a list in the notes of who was elected [11:52:13.0995] i'll do in break if no one else does [11:52:28.0129] (this is normal -- almost nobody writes their own summary and conclusion without prompting, but I didn't know who to prompt for this topic) [11:53:01.0177] Done [11:57:57.0245] presenters! please note, the topics in the overhead bins have shifted during flight: https://hackmd.io/dp19kCC5QBeG1W37oESrfQ?view [13:20:15.0193] `@babel/plugin-proposal-decorators` is the most downloaded Babel plugin on npm for a proposal. It has (looking at some plugins for proposals that have been around for a while and are among the most downloaded ones): - 100x the downloads of `@babel/plugin-proposal-explicit-resource-management` - 40x the downloads of `@babel/plugin-proposal-throw-expressions` - 80x the downloads of `@babel/plugin-proposal-pipeline-operator` [13:21:29.0987] What is the burden with shipping first? Is it that you are the one that's going to find compatibility bugs? [13:22:40.0489] littledan: Did you really mean Stage 3, or should that have been 2.7? [13:23:31.0360] 3 is when it's time to implement and ship, so while ideally things would be blocked at 2.7 if there's no desire to implement, 3 would be fine too [13:23:44.0619] but it's definitely subpar to have something be stage 3 that nobody's prioritizing [13:23:47.0888] re the isSafeNumeric item later, Number toString technically allows implementations a choice of outputs in some cases https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-tostring [13:23:51.0503] does anyone actually... do that [13:25:40.0604] I will say that it's rather frustrating as someone tracking the decorators spec work for some time... what I heard is that implementers don't want to prioritize it because they don't want to be the first to ship, but that they don't want to be the first to ship because the work is not prioritized..... what I'm not hearing at all is do the implementers just not want to implement decorators at all? Is this just a delay tactic to ultimately kill the proposal? [13:29:21.0623] For many syntax features, developers are often comfortable with using a build tool to transform new syntax under the expectation that that transformation step can be removed once evergreen browsers have been updated to support the feature, but that requires those browsers to continue to make progress on shipping those features. Many syntax transformations are fairly cheap, though that's not always the case. Async functions and generators required fairly significant transformations and helper libraries to support, which adds overhead to bundles. The transformed emit for stage 3 decorators can also be quite large, which has a negative impact on bundle size and initial load time. [13:30:00.0734] Even if feature availability is lopsided across browsers, developers can use server-side UA sniffing (or even client side with `import()`) to ship a leaner bundle with native decorators on browsers that support them, and a transformed bundle on browsers that don't. [13:31:46.0518] possible in principle and I wish people did it more, but in practice I have ~never seen server-side UA sniffing for serving scripts with downleveled features to browsers which don't support something [13:32:44.0614] i think facebook might do it, but i've never actually seen it [13:32:47.0359] > <@bakkot:matrix.org> possible in principle and I wish people did it more, but in practice I have ~never seen server-side UA sniffing for serving scripts with downleveled features to browsers which don't support something Isn't this essentially what anyone participating in an Origin Trial would need to do? [13:33:03.0365] > <@bakkot:matrix.org> possible in principle and I wish people did it more, but in practice I have ~never seen server-side UA sniffing for serving scripts with downleveled features to browsers which don't support something we literally do that [13:33:22.0427] one of the npm-to-web cdns does it, idr the name [13:33:35.0361] origin trials are most often APIs which you can just make conditional within a script instead of UA sniffing [13:34:26.0540] we do a lot of weird things! but that's a one-off for a particular feature we needed, not a general mechanism for arbitrary features [13:36:47.0385] `polyfill.io` did for APIs but that's a slightly different thing than syntax [13:37:16.0353] I don't think many places are using npm-to-web CDNs in prod [13:37:21.0200] well, presumably lots of hobbyist stuff [13:37:41.0296] > <@bakkot:matrix.org> possible in principle and I wish people did it more, but in practice I have ~never seen server-side UA sniffing for serving scripts with downleveled features to browsers which don't support something Large scale applications definitely have used both server-side UA sniffing and client-side feature detection to dynamically load content in different engines for performance tweaks. [13:38:14.0175] I agree some people do it; we do it. But it's very very rare in my experience, looking at random retailers and hotels and so on. [13:42:35.0748] syg: What we are doing with import defer, is that deferred namespace objects guarantee that they will never have a .then property. This doesn't actually change the promises machinery, but makes sure that deferred namesapces are inhert to it [13:42:38.0360] If decorator downlevel emit size is a significant concern, it might be worth that kind of temporary split to produce a leaner bundle when possible. Web performance optimization is a major area of focus for large scale applications. [13:42:54.0410] * syg: What we are doing with import defer, is that deferred namespace objects guarantee that they will never have a .then property. This doesn't actually change the promises machinery, but makes sure that deferred namesapces are inert to it. And we can do it because they are already very exotic objects [13:43:15.0112] thanks. still says to me there's a datapoint that we consider "then" a special evil worth special casing [13:46:01.0179] We did already make Object.prototype be exotic (to have a frozen __proto__) but I agree that exotic with respect to then is an extra form of weirdness [13:49:42.0084] Mathieu Hofman: for the Promise.resolve constructor lookup, see https://github.com/tc39/proposal-faster-promise-adoption/issues/1 [13:49:53.0256] For the notes: every time someone says "object dot proto", they mean Object.prototype, right? Not Object.__proto__ [13:50:01.0518] currently the check is `IsPromise(p) && p.constructor === C`; I think it should be `IsPromise(p) && GetPrototypeOf(p) === C.prototype` [13:50:07.0052] * For the notes: every time someone says "object dot proto", they mean `Object.prototype`, right? Not `Object.__proto__` [13:50:30.0595] GetPrototypeOf usually triggers user code, but can't trigger user code once you pass the IsPromise test [13:53:13.0977] Yes this is when the "SafePromiseResolve" issue came up last time [13:54:16.0549] Are firefox use counters public, with a list of example websites, like Chrome's? [13:55:04.0843] I basically want to make this check into a "SafePromiseResolve" that fast path promises that do not re-enter, and delay by one tick the ones that may. Then anyone can use that operation, possibly even `await`. [13:55:51.0309] That's not sufficient if someone overrides `%PromisePrototype%` properties [13:56:01.0662] isn't it? [13:56:03.0529] * That's not sufficient if someone overrides `%PromisePrototype%` `then` and `constructor` properties [13:56:14.0226] Promise.resolve does not do a lookup of `.then` on things which pass that check [13:56:39.0235] It does for `constructor` if I recall. [13:56:54.0383] Right, it does `IsPromise(p) && p.constructor === Promise` [13:57:21.0737] but if we make it `IsPromise(p) && GetPrototypeOf(p) === C.prototype` then it would not do anything user-observable (on real promises) [13:57:29.0433] and I bet we can get away with that [13:57:50.0359] this also applies to `await` since it uses the same machinery [13:58:22.0574] and `await` also does not do an actual `.then` lookup at all, it just does a PromiseResolve and then uses the built-in PerformPromiseThen [13:58:28.0766] `defineProperty(`Promise.prototype`, 'constructor', {get() {} }})` [13:58:38.0140] * `defineProperty(Promise.prototype, 'constructor', {get() {} }})` [13:58:45.0710] * `defineProperty(Promise.prototype, 'constructor', {get() {} })` [13:58:55.0400] I don't know what that's intended to be a response to [13:59:08.0031] I am proposing to change the machinery so nothing ever looks at `.constructor` [13:59:23.0394] what constitutes a brand check [13:59:32.0831] like what granularity [13:59:36.0838] there are so many ways to organize objects [13:59:49.0756] A sync side-effect-free way to tell wether an object has a particular internal slot or not [13:59:51.0093] Oh, if you think that's web compatible [14:00:01.0075] * A sync side-effect-free way to tell wether an object has a particular internal slot or not, for any slot [14:00:11.0227] for *every* internal slot? [14:00:16.0045] I give it reasonable odds [14:00:35.0163] since the only thing that happens if something starts failing the check is that they get another microtask tick [14:00:42.0247] Well, a brand check is for _one_ internal slot, and Jordan would like every internal slot to have a brand check [14:00:57.0788] yeah i mean my question is what the consensus applied to [14:01:10.0425] because there are a lot of internal slots, how does one decide which ones are relevant in this case [14:01:39.0436] Frank is ill, and I will now be presenting his slides on Intl Locale Info. Rob Palmer Chris de Almeida ryzokuken [14:01:55.0301] Yeah I just need to think through the different cases of "subclassing" that the constructor check is meant to handle. [14:02:08.0825] hope he recovers soon, thanks for the heads up [14:02:20.0617] every internal slot that has observably different behavior, i suppose [14:02:35.0818] Anyway, I'd be happy with anything that allows anyone (spec or user code) to stop triggering sync code during Promise.resolve [14:02:47.0438] and luca's comment seems somewhat related, in that it relates to the overarching goal throughout ES6 of making DOM objects JS-implementable [14:02:55.0190] * and luca's comment seems somewhat related, in that it relates to the overarching committee goal throughout ES6 of making DOM objects JS-implementable [14:03:17.0614] I am very firmly convinced that the goal of making host things 100% doable in userland was a mistake [14:03:27.0154] that gave us Symbol.concatSpreadable and etc [14:04:09.0117] _mostly_ doable in userland is good but I think it's probably OK if you can't polyfill this particular behavior? [14:04:27.0582] i'm not personally invested in implementable in userland, fwiw [14:04:27.0707] like, people probably aren't going to start relying on being able to stick `.then` on your polyfilled webIDL thing [14:04:39.0733] are there no webIDL thenables? [14:04:49.0190] don't think so [14:04:50.0423] because being able to implement one of those seems important for engines implemented in JS? [14:04:52.0670] * because being able to implement one of those seems important for engines implemented in JS, if so [14:04:53.0008] if it's not doable in JS then there are a ton of web platform APIs that node.js, deno, etc would have a difficult time implementing this for [14:05:31.0721] though engines implemented in js have their own object graph, so its kind of a moot point [14:05:33.0287] I think for node etc you could just have a built-in thing to mark objects as special in this way, and then mark them? [14:05:46.0049] as long as V8 exposes this as a bit you can set on an arbitrary object [14:05:50.0234] Such built-in things become rather expensive from a perf cost [14:06:11.0596] hm, ok [14:06:15.0143] anything that requires calling down into C++ becomes rather expensive in aggregate [14:06:56.0408] it could take a list of objects and just do a single call, if the concern is the number of times you cross the language barrier [14:06:59.0176] ones 100% implemented in JS yes, but not in eg node where they use JS to augment (and sometimes polyfill) standard features not implemented in JS [14:07:06.0555] do you need to mark objects often? [14:07:06.0785] > <@jasnell:matrix.org> anything that requires calling down into C++ becomes rather expensive in aggregate there's no reason V8 couldn't have a built-in that gives access to an object containing a lot of internal APIs that can be called from JS [14:07:10.0049] is it like, per instance? [14:07:51.0182] ...why... would we do this? [14:07:58.0526] fyi chairs I'm good to present math.clamp from now for scheduling [14:08:03.0593] well, it's not *just* node.js itself. Also thinking about user-land provided polyfills of standardized apis [14:09:20.0407] at the very least, it seems we have consensus that there's a problem to address here. I think there's likely multiple ways to address it but I want to make sure we do not prematurely take JS polyfillability off the table [14:10:00.0308] is it fine to do the login form twice or if not could someone dm the meeting link? [14:10:31.0904] how important do you think it is to be able to polyfill this specific weird behavior? because it feels not that important to me [14:10:36.0615] yes, it's fine to do it multiple times [14:10:57.0415] i mean hermes still needs to polyfill `Promise.resolve` for react native [14:10:59.0804] * i mean hermes still needs to polyfill `Promise.resolve` for react native, using JS [14:11:18.0090] having experienced this issue before *with* a userland polyfilled implementation, I'd personally say it's important [14:11:52.0607] * i mean hermes still needs to polyfill `Promise.resolve` for react native, using JS, so they'd need it [14:12:18.0242] technically this does exist, there's a kitchen sink object called the "extras binding" [14:12:33.0992] oh god, please don't expose this to users [14:12:53.0505] snek: for me it's like, can you, with a straight face, say a thing is intended to be a thenable? if not, it'd be nice if we disallowed it to be a thenable at a language level [14:12:54.0785] it triggers an emotion to see "how important to be spec compliant" in a tc39 channel [14:13:22.0074] well like I don't think people should be trying to polyfill `document.all` [14:13:25.0898] the language has a lot of weird corners [14:13:35.0622] well with a straight face i would say that modules aren't intended to be thenable. but idk how many people agree with me on this [14:13:37.0225] (+1 that subclassing builtins was a mistake) [14:14:04.0123] I definitely agree but that ship has sailed [14:14:08.0269] we can't now make them not-thenable [14:14:11.0590] * well with a straight face i would say that modules aren't intended to be thenable. but idk how many people agree with me on this (well if anything, based on my original proposal being rejected, i know people don't agree with me) [14:14:19.0329] `.constructor.name.match(/promise|defer/i)` [14:14:19.0530] but we did for deferred namespace objects at least [14:15:17.0239] i'd love it if we used null proto more aggressively for new spec-created objects; it seems like it'd avoid a whole class of problems [14:15:33.0105] time to merge the `extends null` spec pr? [14:16:10.0839] FYI on terminology, a "thenable" is any object with a `then` method, regardless as to whether it is a promise or matches the Promise/A+ specification. i.e., if `typeof x.then === "function"` it's a "thenable". Being a "thenable" doesn't make it Promise-like. [14:16:40.0902] i'm aware [14:16:44.0003] I want this but weren't there still unresolved questions? [14:17:50.0722] yeah, the PR didn't work at all [14:18:32.0019] the pr /works/, people just don't agree on the behavior [14:19:02.0497] I only mention it because I've been running afoul of developers making the wrong assumption, or assuming the meaning of "thenable" has changed over the years. I'm mostly making the point so it's on the record in the chat log. [14:19:11.0379] like we have a set of test cases (which you can read in the proposal), which delegates don't agree on the output of, or at least didn't last time it was brought up [14:19:15.0325] * like we have a set of test cases (which you can read in the pr), which delegates don't agree on the output of, or at least didn't last time it was brought up [14:21:27.0706] as i recall, the options atm are either: 1. `class extends null` not necessarily statically, but `super` is an error in what is syntactically a derived class 2. `class extends null` not necessarily statically, and `super` is a noop (and i think also either option, but "only statically") and i think both options had a number of folks whom received an "ick" from it [14:22:05.0689] * as i recall (disclaimer: i haven't read the PR in years), the options atm are either: 1. `class extends null` not necessarily statically, but `super` is an error in what is syntactically a derived class 2. `class extends null` not necessarily statically, and `super` is a noop (and i think also either option, but "only statically") and i think both options had a number of folks whom received an "ick" from it [14:22:25.0970] * as i recall (disclaimer: i haven't read the PR in years), the options atm are either: 1. `class extends null` not necessarily statically, but `super` is an error in what is syntactically a derived class 2. `class extends null` not necessarily statically, and `super` is a noop (and i think also either option, but "only statically") and i think each option had a number of folks whom received an "ick" from it [14:23:02.0636] Wow reading through that PR I really dislikes what some comments are proposing [14:23:21.0844] We're skipping the break? [14:23:41.0528] * Wow reading through that PR I really dislike what some comments are proposing [14:24:01.0468] the break is delayed [14:24:11.0076] we'll break for 30 at the end of this presentation [14:24:18.0998] Charis can you update the agenda item on tcq? [14:24:35.0576] done, thanks [14:24:40.0299] https://github.com/tc39/ecma262/pull/1321 is the `class extends null` PR [14:24:46.0660] in case anyone else wants to have opinions [14:24:55.0419] or clean it up and bring it back :D [14:25:49.0474] i'm happy to bring it back if people agree on something [14:25:54.0496] (Personal opinion) Just going back to the Decorators browser stalemate of "willing-to-ship-but-not-be-first", it makes me worry a tiny bit about the quality of signal Stage 3 is sending to non-browsers. If it gets unblocked, there's no worry. If it remains blocked or gets demoted, we will have unfortunately transferred risk to TypeScript that has followed our process and shipped the proposal - which has been a major churn for users of the older version of TS Stage 1 Decorators. [14:25:55.0769] can't solve a paradox [14:25:56.0766] Maybe we could report on developer usage experience from Decorators TS to help inform/motivate browsers to begin shipping. [14:26:47.0044] well until they are open about why they're not shipping it, its kind of unclear what report they need, if any [14:28:45.0090] This feature does not need to be a speedup to be useful, IMO. (Good to avoid false claims here though) [14:29:24.0911] I can't believe css shipped clamp in a different order than every other language [14:29:32.0382] that is such a bizarre developer-hostile decision [14:30:02.0000] i didn't know people put min after max [14:30:06.0773] is TabAtkins here, can we complain to him [14:30:09.0445] * is TabAtkins here, can we complain to them [14:30:32.0186] CSS should have meeting minutes where they discussed this at some point... [14:31:41.0942] apparently a fairly common complaint https://github.com/w3c/csswg-drafts/issues/11427 [14:35:44.0320] The minutes are at https://github.com/w3c/csswg-drafts/issues/2519#issuecomment-387803089. It seems like it was for alignment with a CSS function that ended up not actually existing (minmax with 3 arguments) [14:35:57.0296] uuuuuuuuuuuugh [14:36:01.0133] nice [14:36:13.0651] What up [14:36:41.0817] `clamp` has the wrong argument order, it is different from every other language, this probably means we can't have `Math.clamp` [14:36:51.0104] * css `clamp` has the wrong argument order, it is different from every other language, this probably means we can't have `Math.clamp` [14:37:08.0516] The question would be "does JS align with CSS, or with all the other non-web languages" [14:37:09.0050] the prior art used in this is painful [14:37:14.0940] As the issue says, there's both precedents [14:37:34.0961] i thought dbaron had adopted gen z slang but i see that `fr` is a unit :( [14:38:56.0416] `new Math.Clamper(min, max).clamp(value)` [14:39:27.0462] With hindsight, I agree the weight of precedent goes with val first [14:39:37.0702] `fr` fr [14:39:50.0361] `(new (new Math.ClamperFactory(min))(max)).clamp(val)` [14:40:02.0541] `NumberConstrainmentBuilder` [14:40:12.0477] problem solved [14:40:20.0496] don't forget the MathFactory [14:40:32.0175] `BigMath` [14:40:40.0899] please take shitposting to tdz [14:41:32.0299] I just don't think it's so useful to overthink this kind of thing [14:41:41.0665] * I just don't think it's so useful to overthink this kind of thing (re sffc's comment) [14:42:15.0682] hindsight? you just shipped this just now! [14:42:29.0587] (anyway we've been there before) [14:42:49.0817] We resolved on it six years ago [14:42:57.0987] clamp is pretty old at this point https://developer.mozilla.org/en-US/docs/Web/CSS/clamp [14:43:02.0479] unfortunately... [14:43:13.0820] Anyway do the obvious thing in JS [14:43:32.0806] Css round() looks nothing like Math.round either [14:44:21.0722] fair point! [14:44:39.0387] Really it's only on the simplest of cases (single argument, or all arguments semantically identical) that we match [14:45:01.0690] eemeli: only the ones that start with "to" :-p this one wouldn't [14:45:31.0855] It would still be a very radical change. [14:45:50.0879] Css even fixed JS's dumb mistake with mod() (but still shipped the bad behavior as rem()) [14:46:34.0834] if we end up shipping rem with the other behavior that would be very funny [14:46:47.0410] i'm not sure it'd be "radical" - does anybody have the expectation that "all methods on a thing always return the same kind of thing"? [14:46:48.0827] I mean JS doesn't name either of them [14:46:55.0288] So that would be a self own [14:47:09.0316] i'd expect people call one method, and don't know or care about the ones they aren't calling [14:47:35.0664] And I *did* do significant name research to settle on mod/rem as the name pair [14:49:01.0132] someone used to push regularly for us to add those [14:49:06.0247] ... possibly Brendan actually? [14:50:31.0465] We still should! [14:51:11.0431] Symbol.clamp [14:51:15.0358] * System.clamp [14:51:33.0010] sffc: being aligned on the motivation is for stage 1. are you objecting to that? [14:51:33.0112] Given that we already have `Math.min` and `Math.max`, I don't see how anything other than `Math.clamp` would be better. [14:51:57.0936] the main reason i see is that it'd also allow `BigInt.prototype.clamp` [14:52:08.0942] * the main reason i see is that it'd also allow `BigInt.prototype.clamp` (and i guess that it resolves the argument ordering question) [14:52:11.0314] Yeah please do Math.clamp(v, min, max), y'all [14:52:30.0793] what would the bigint clamp be then? [14:52:39.0391] `BigInt.clamp` [14:52:43.0590] The reason I like a proposal for this is that there is a 50% chance to forget "when doing max(min(...), ...), I need to pass the min to max and the max to min". A built-in function for this is motivated if it makes it easier to pass the right number in the right place [14:52:50.0634] then y no `Number.clamp`? [14:52:58.0768] because Math is the namespace for the number stuff [14:53:04.0216] Oh, I'm not in the meeting at I didn't see the context. But yeah sure, BigInt.clamp() [14:53:11.0262] Math.clamp(number|bigint) pls [14:53:13.0977] And yeah, Math has precedent [14:53:21.0697] I think the question about clamping bigints needs to be answered simlutaneously with min() and max() for bigints. [14:53:36.0922] those also go on BigInt [14:53:51.0581] Or the "three bigint arguments" on Math. +1 to eemeli: [14:54:07.0348] and in a world where we also have decimal, suddenly all the Math stuff "should" really be on Number, and Math is just weird legacy baggage? [14:54:26.0381] I think Number will always be privileged relative to any other numeric types [14:54:27.0839] are bigints not math [14:54:29.0868] so it is ok that it gets two namespaces [14:54:38.0942] BigInts are not math [14:54:45.0130] re: `Math.max(bigint)`, https://github.com/tc39/proposal-bigint-math/issues/23#issuecomment-1275893064 [14:54:49.0548] I think this is very compelling [14:54:51.0322] ah, but `3n + 4n` works [14:55:00.0740] > `1n + Math.max(...list)` will throw a TypeError if `list === []` [14:55:46.0204] 1 + Math.max(...list) is -Infinity, is that more helpful in practice [14:56:11.0321] * 1 + Math.max(...list) is -Infinity, is that more helpful in practice (not that it isn't the correct thing to return) [14:56:31.0321] it's not necessarily more helpful but it is what your code is already designed for [14:56:42.0098] and unexpectedly getting a TypeError is pretty weird [14:56:49.0264] I don't like the return types of functions to depend on the types of their inputs [14:56:57.0945] * also, seperately, I don't like the return types of functions to depend on the types of their inputs [14:57:01.0580] * also, separately, I don't like the return types of functions to depend on the types of their inputs [14:57:09.0138] I did not mention it because throw-away objects are probably bad, but `Math.max(value, { min, max })` would also be a reasonable option [14:57:12.0961] * I did not mention it because throw-away objects are probably bad, but `Math.clamp(value, { min, max })` would also be a reasonable option [14:57:23.0096] but i think at a very high level if we want to continue to separate things out, prototype methods is a probably my preferred solution. cuz then `(a, b) => a.min(b)` works for any numeric types [14:58:27.0948] > <@nicolo-ribaudo:matrix.org> I did not mention it because throw-away objects are probably bad, but `Math.clamp(value, { min, max })` would also be a reasonable option Note that the css clamp accepts "none" for its min/max arguments, so that would be a more consistent functionality [14:59:01.0495] this makes me wish again that js had named arguments, separate from option bags [14:59:10.0095] Allows you to optionally clamp either side without having to either branch your function name or supply infinity [14:59:58.0147] `Math.BigInt.{ min, max, clamp, ...}` is always an option. It's a bit odd to have `Number`-related methods on `Math` but `BigInt` related methods on `BigInt`. [15:00:00.0421] Have we actually considered named arguments and dismissed them at some point? [15:00:25.0589] Yes, sorta [15:00:34.0905] It's fallen on syntax grounds [15:01:08.0160] In the same vein, `Math.Decimal.{ min, max, clamp, ... }`... [15:08:42.0087] Specifically, the two obvious syntaxes are `foo(arg1: v)` and `foo(arg1=v)`, and both are problematic. [15:09:47.0617] moar punctuation: `foo(arg1:: v)` [15:09:47.0906] I thought it had fallen on "we already have `{ arg1: v }`" grounds [15:10:56.0754] `foo(arg1=v)` definitely is, but why is `foo(arg1: v)` problematic? Something like `foo(arg1:= v)` would work too [15:11:21.0048] Though in some languages, `:=` means "bind and initialize" [15:11:25.0807] while I was typing it i could recall what was bad about `arg:val`, actually [15:11:30.0836] * while I was typing it i couldn't recall what was bad about `arg:val`, actually [15:11:43.0622] i suspect it is just that object bags take the air out of the room [15:13:03.0544] Except that they're extremely inefficient. [15:13:13.0325] oh yeah they're bad, i agree [15:13:55.0008] maybe `arg:val` was just becuas eof its nearness to the trinary operator being potentially confusing [15:14:55.0785] C# has both `foo(arg1: x)` and `?:`, it's not especially confusing, IMO. [15:15:09.0320] URL fragment directives use `:~:`; we can't do worse than that [15:15:11.0689] Especially since arg binding can only happen at the start of an argument. [15:16:56.0731] Named arguments was an issue that partial application ran up against. Partial application only wants to bind Argument positions, and `foo(x, { y: ? })` is not a valid Argument position, while `foo(x, y: ?)` would be. [15:18:29.0188] a little similar with parameter decorators, they don't work in the same vein for object-bag-as-named-argument-pattern [15:20:47.0480] I would find named arguments like `foo(arg: value)` to correspond rather well with the way we can already use `foo({ arg: value })`. [15:21:46.0734] yeah, it probably is the most natural syntax for js [15:24:14.0563] I think the biggest issue with named arguments is that parameter names aren't preserved in the face of `.bind` and method replacement via decorators. [15:25:07.0983] i mean, they could be. it's unobservable right now. [15:25:22.0213] (source visibility doesn't contradict this) [15:25:58.0099] `.bind` could. Decorators could not, not without additional reflection over the method being decorated and some way to dynamically define named arguments. [15:27:18.0988] tho Python gets by without having either of those preserve names, because it has *args and **kwargs [15:27:49.0462] named parameters working automatically (without opt-in from the callee) would break all minifiers which would be kind of a shame [15:27:49.0577] so a decorator can just take and pass `(*args, **kwargs)` and preserve the arg name beahvior [15:28:12.0302] I want to repeat my request to the meeting organizers that we enable recording and publishing as a pattern for any presentation [15:28:14.0549] `arguments.named` [15:28:32.0270] it is a very good practice, for transparency and inclusion [15:28:43.0806] thank you Mark for bringing it in here [15:29:05.0203] fwiw I strongly dislike having any public recordings of my voice (though there is at least one now) [15:29:15.0792] but would feel somewhat awkward about personally opting out of recording my presentations every single time [15:29:48.0483] for example: ```js function ignore() {} function dec(t, c) { return ignore } class C { @dec a(x) {} @dec b(y) {} } ``` `a` and `b` both end up with the same function for the method. [15:29:56.0222] I guess we could have some practice of automatically overdubbing but that would be a lot more process [15:29:59.0722] opt-in to record sgtm [15:30:19.0814] opt-out to not-record sbtm [15:30:33.0193] So yeah, named arguments would need to be passed along somehow. [15:31:28.0641] fwiw i am concerned about ephemeral spirited in-group discussion, or attempted whimsy in a slide deck, becoming like a conference talk that people can critique forever even as cultural standards shift [15:31:40.0190] * fwiw i am concerned about ephemeral spirited in-group discussion, or attempted whimsy spoken aloud, becoming like a conference talk that people can critique forever even as cultural standards shift [15:31:50.0235] * fwiw i am concerned about ephemeral spirited in-group discussion, or attempted whimsy spoken aloud, becoming like a conference talk that people can critique forever even as cultural standards shift. opt-in only covers that tho. [15:32:30.0024] * fwiw i am concerned about ephemeral spirited in-group discussion, or attempted whimsy spoken aloud, becoming like a conference talk that people can critique forever even as cultural standards shift. opt-in-only covers that tho. [15:32:34.0603] I don't think anyone was proposing recording the discussion, just the presentations [15:32:44.0303] yes, this would be opt-in. (but generally I think the things which look bad in retrospect were already bad at the time.) [15:33:53.0243] otoh, apologizing to forty people is tractable in a way that apologizing to everyone is not [15:35:12.0410] Yeah, that does make it sound like it'd break the web. [15:35:29.0782] well, not as we usually use the term [15:36:09.0696] but it would be pretty annoying for developers and also probably make all websites much larger eventually once the minifiers updated to preserve parameter names [15:36:18.0027] * but it would be pretty annoying for developers and also probably make all websites some amount larger eventually once the minifiers updated to preserve parameter names [15:36:54.0925] there are a lot of identifiers they have to preserve anyway [15:37:10.0359] there are? [15:37:15.0830] just `eval` [15:37:17.0528] what else? [15:37:23.0331] property names [15:37:30.0676] and options bag names [15:37:34.0098] those aren't identifiers, get out of here [15:38:00.0774] 🤨 https://gc.gy/d5e67b97-d268-455e-8e3c-9d99b62e7208.png [15:38:13.0641] * 🤨 https://gc.gy/20c632fb-3230-4795-babd-ed57b11c0b22.png [15:38:35.0092] IdentifierName is, to be fair, technically not Identifier [15:39:50.0016] imports from packages not bundled, exports exposed to end users, globals [15:53:40.0713] FWIW I wouldn't mind normative text, requiring that hosts respect the immutability of immutability array buffers (but the assert reading makes sense too) [15:58:14.0667] I would probably do something like > NOTE: Because canonical numeric index properties of a TypedArray backed by an immutable ArrayBuffer are nonconfigurable and nonwritable, the [essential object invariants](link goes here) mean that hosts are prohibited from modifying the values in an immutable ArrayBuffer by any means. [15:58:36.0973] If an assert failure makes the spec normatively incorrect, then an assert cannot be informative. Informative text cannot make a spec inconsistent. [15:59:05.0961] Why not? [15:59:13.0391] but, it's text that implies no normative requirements on implementations 2025-02-19 [16:00:07.0645] I just stated the reason. The definition of "informative" is any text that can be removed without affecting the normative parts of the spec. [16:00:34.0032] An assert doesn't fall into that category if it can make a spec normatively inconsistent. [16:00:34.0749] Informative text being incorrect seems like it definitionally means the spec is inconsistent. [16:00:52.0713] and assert failure does not make the spec normatively incorrect, it makes it incoherent. incorrect/correct as a category doesn't even arise because it's malformed [16:01:14.0868] this was very fast advancement for such a significant proposal [16:01:25.0136] An Assertion is a statement that the asserted condition is the only possible state based on how the algorithm is used elsewhere in the specification. It is essentially informative because its absence would have no impact on the spec itself, so long as the spec is coherent. [16:01:27.0226] (I think that's a good thing -- we're able to act efficiently when it's a good idea) [16:01:34.0438] Incorrect = malformed in my comment above. [16:01:48.0598] i see, well, its removal still doesn't affect the malformedness [16:01:58.0280] the spec remains malformed if the only removal is the assert [16:02:17.0078] Yes, it does, because the spec might become well-formed with removal of asserts. [16:02:57.0475] interestingly, the C++ standards committee is currently working through a similar epistemological debate, but at the level of assertions in source code -- should they execute? I heard they decided that the mode is determined by compiler flags (...a very different language philosophy from ours) [16:03:09.0689] * interestingly, the C++ standards committee is currently working through a similar epistemological debate, but at the level of contracts in source code -- should they execute? I heard they decided that the mode is determined by compiler flags (...a very different language philosophy from ours) [16:03:32.0467] excited to see immutable arraybuffers advancing. There are definitely a number of web API specs that will need to be updated to account for them. I mentioned Web Crypto crypto.randomValues() but BYOB ReadableStream is the other big one. That will need to be updated to reject immutable buffers on reader.read(buf). [16:03:45.0689] I plan to use compiler flags for whether to include spec asserts or not (I have none currently) [16:04:21.0912] TextEncode encodeInto is another [16:05:01.0699] i guess the nuance here is the assert tells a story about the intended property of the spec. if it doesn't hold, we say the spec is malformed in the sense that the intention doesn't hold. it could be brought back into well-formedness by changing the intent (which is necessarily not reflectable within the text, only tacit). more often, we don't change the intention doesn't change, and it turns out the there is a bug in the spec [16:05:19.0318] * i guess the nuance here is the assert tells a story about the intended property of the spec. if it doesn't hold, we say the spec is malformed in the sense that the intention doesn't hold. it could be brought back into well-formedness by changing the intent (which is necessarily not reflectable within the text, only tacit). more often, we don't change the intention, and it turns out the there is a bug in the spec [16:05:26.0834] * i guess the nuance here is the assert tells a story about the intended property of the spec. if it doesn't hold, we say the spec is malformed in the sense that the intention doesn't hold. it could be brought back into well-formedness by changing the intent (which is necessarily not reflectable within the text, only tacit). more often, we don't change the intention, and it turns out there is a bug in the spec [16:06:11.0200] those fall out to SetValueInBuffer, so probably the fix is to update WebIDL to do something else? or make SetValueInBuffer fallible, though that would be a shame [16:06:17.0622] https://webidl.spec.whatwg.org/#arraybuffer-write is the relevant thing I think [16:06:29.0249] but we definitely need tests as well [16:06:53.0979] I hope web integration can look into where immutable arraybuffers can be a benefit in some cases, e.g., by avoiding certain cloning when used. [16:07:03.0513] yes, WebIDL is good to call out to see how they want to go [16:07:13.0279] maybe they want an attribute to require buffer sources to be immutable [16:07:39.0586] also there are places which take a buffer as an argument and they do a defensive copy [16:07:42.0969] and should be updated to not do that [16:08:16.0689] though that's... mostly fine [16:08:20.0609] you can just as-if that away [16:08:23.0590] if an immutable arraybuffer can't be detached, copying it can just be not-copying it [16:08:28.0785] * if an immutable arraybuffer can't be detached, copying it can just be implemented as not-copying it [16:08:38.0855] Like I said, Python gets by without this happening explicitly, because it has *args and **kwargs, and it's common practice for decorators to make the wrapper function they return take `(*args, **kwargs)` and then call the inner function with the same. That preserves passed function names, without needing the runtime to actually track function names across decorator boundaries. We'd need to add the same to JS, I think, to do named args. [16:09:10.0211] yes, I think this is important. Even if it's formally just an editorial change, calling out in various specs where they can avoid work in the case of immutable ArrayBuffers makes it more likely that browsers will implement the optimization. [16:09:28.0948] I think probably this consists of finding the places which refer to https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy and updating them [16:09:31.0115] Python also has explicit syntax in the parameter list to denote named vs positional arguments [16:09:34.0681] also agreed there. the amount of as-if optimizations happening on the web spec side is surprisingly little, compared to JS algorithms [16:09:58.0386] right, people are more likely to implement line-by-line there [16:10:02.0691] only recently (by default, all args are passable by both index and name), and that doesn't affect the pattern I mentioned anyway [16:10:33.0961] (but I do think we could apply Python's lessons and go ahead and add "index only" and "name only" arglist section, like they do) [16:10:48.0682] As much as I love this feature of Python when writing Python, I think I would prefer to maintain JavaScript’s rustic aesthetic, rather than rewalk the path to realizing Python needed a delimiter between positional arguments and positional arguments that are eligible to be interpreted as kwargs. [16:11:59.0174] sure, JS having *just* index-only and name-only is a potential future I think woudl be okay, and means there would be a syntax opt-in for named args so minifiers wouldn't need to change by default [16:12:20.0619] (you'd have to write `function foo(posarg, **, kwarg1, kwarg2)`) [16:12:24.0568] or similar [16:13:56.0974] I find it clearer to continue `function foo(posarg, {kwarg1, kwarg2} = {})`. [16:14:19.0192] Given the degree of difference in practice. [16:14:48.0333] and that's the exact argument that's blocked it in the past ^_^ [16:16:20.0359] it's kind of annoying that keyword arguments have to take place at a particular indexed position... makes it harder to add positional arguments over time, but maybe that's OK. [16:16:42.0420] but I'm not sure whether it'd be worth it to introduce a whole other named argument system [16:17:00.0473] just seems like a lot of work [16:17:08.0918] `function foo(posarg1 ;{kwarg1, kwarg2} = {} ;posarg2)` [16:17:47.0037] as has been stated, the lack of named arguments is a minor blocker in a number of dimensions, but it's only a very minor improvement in the base case, so it's harder to argue for since the extra stuff can be dismissed more easily. [16:19:56.0891] This is a conspiracy by Big ESLint to add more rules to ESLint [16:20:16.0324] hey who told you about big eslint [16:21:03.0657] for fans only: look again at those semicolons [16:21:32.0731] fun fact `for` is a valid function name [16:21:58.0087] `function for(x; y=y+1; z) {}` [16:22:11.0408] Which JavaScript are you talking about [16:22:42.0528] jesse's thing above [16:22:53.0485] the `function foo(posarg1 ;{kwarg1, kwarg2} = {} ;posarg2)` one [16:23:00.0368] `const f = { for() {} }['for'];` :-P but `function for() {}` is a syntax error [16:23:30.0620] wrong javascript [16:23:33.0522] ugh [16:23:44.0073] yeah it needs to be a method not a declaration [16:23:46.0820] ``` for(of of of); ``` [16:23:47.0315] I always get that wrong [16:24:35.0049] this is one thing that really bothers me about rust, let me name fields `if` and `return` and such [16:24:43.0754] ``` class X { for(x; y=y+1; z) {} } ``` [16:24:55.0427] not being able to have a field named `type` is enormously annoying. everyone uses `typ` or `r#type` [16:25:27.0949] I think that sailed once `await` became an operator which is indistinguishable from property access [16:25:44.0507] i love it and i hate it [16:26:02.0206] feedback welcome: https://github.com/tc39/proposal-immutable-arraybuffer/pull/44 [16:26:04.0078] it's grown on me [16:32:36.0750] waldemar re: "ToString is not unique" the spec does allow the last digit to vary, but I'm not sure if any implementations actually differ [16:32:49.0225] I think we might be able to fully specify it and thereby resolve that specific issue [16:33:28.0170] is the goal here round-tripping a string representation? and the thing that's stopping people from relying on that because we have some leeway technically? [16:33:36.0534] * is the goal here round-tripping a string representation? and the thing that's stopping people from relying on that is because we have some leeway technically? [16:34:13.0943] it sounds like the goal is "can this string be represented as a number" but semantic misunderstanding or disagreement about what "can be represented" means [16:34:51.0032] The problem here is that it's impossible to define a Number-to-String conversion such that the resulting string satisfies isSafeNumeric [16:34:54.0293] yeah, if the "can this be represented" means mathematical value that is... not useful [16:35:36.0712] oh I remember what I wanted to say: it seems inconsistent to say that larger integral values are not "safe" for this purpose [16:35:45.0678] doesn't make any sense [16:36:37.0063] these sound like reasons to iterate on the definition (significantly) and maybe add a number-to-string-safe operation, but it feels like the stated motivations hold [16:36:44.0629] Is it? I think if our ToString fully specified the last digit it would work. The spec previously had a bad definition of isSafeNumeric but under the `MV(string) = MV(ToString(ToNumber(string))` I think it's coherent? Or at least the obvious examples like 0.1 don't fail. [16:37:28.0946] > <@devsnek:matrix.org> it sounds like the goal is "can this string be represented as a number" but semantic misunderstanding or disagreement about what "can be represented" means yeah I think a lot of lay-people think "can be represented" means "the float represents this number only", which... just isn't the case [16:37:32.0686] It is very specific to our specific ToString but afaict that's what they're asking for [16:37:53.0497] oh! yes, that didn't occur to me [16:38:04.0692] The definition of MAX_SAFE_INTEGER is that it's the largest Number x such that x+1 is representable exactly. But Number("0.00000000000000000000000000000025") + 1 is 1, while "0.00000000000000000000000000000025" is considered "safe" by this. [16:38:11.0109] > <@littledan:matrix.org> these sound like reasons to iterate on the definition (significantly) and maybe add a number-to-string-safe operation, but it feels like the stated motivations hold I think the motivations are so confused, it's hard to say whether they hold or not [16:38:51.0752] well, I wonder what we should do about the problem space (floats are confusing with respect to value-preserving conversion to/from string) [16:39:22.0075] I would want this problem to be solved with a bank of functions that apply to specific number domains, e.g., `String.representsSafeInteger`, `String.representsSafeNumber`, `String.representsSafeBigInt`, which is less forgiving that the corresponding constructor or parse functions. [16:39:33.0095] > <@littledan:matrix.org> well, I wonder what we should do about the problem space (floats are confusing with respect to value-preserving conversion to/from string) there's probably interesting things to think about here, but I don't yet see a specific problem being identified [16:39:36.0160] oh, yes, I think that conflating this with MAX_SAFE_INTEGER is just incoherent and that part of the proposal should be removed [16:39:46.0346] An example that fails: 10000000000000000 cannot be converted to any string for which isSafeNumeric, as defined in the presentation, returns true. [16:39:48.0588] programmers definitely don't tend to think about floats as a range of underlying reals, even if that's the most sensible way to understand them. The MV tends to correspond more closely to the intuition, I think [16:39:49.0464] at least as I understand the proposal it is strictly about round-tripping values, not about doing arithmetic on them [16:40:49.0586] `+String(10000000000000000) === 10000000000000000` is true, am i missing some zeroes? [16:41:08.0636] i 100% agree that most programmers think about numerical syntax as if they're mathematical values [16:41:10.0051] `string === ToString(ToNumber(string))` isn't the same as `MV(string) === MV(ToString(ToNumber(string)))` given that `MV("1.0")` and `MV("1.00")` are the same mathematical values but different strings? [16:41:16.0295] `10000000000000000 > Number.MAX_SAFE_INTEGER` [16:41:37.0759] aha, that's a fair point, decimal/trailing zero normalization, as well as leading zeroes, would be different [16:41:48.0839] is that the problem statement here, dealing with those kinds of things? [16:41:53.0022] I think the `MV` is to handle that normalization. [16:42:02.0210] this is likely why they reached for MV, but MV is not exactly that [16:43:34.0236] I assume the goal of `isSafeNumeric` is to validate that the input string can be accurately represented as a `Number` without loss? It can probably be specified more directly. [16:43:49.0185] I feel like this is missing a problem statement that differentiates it from https://xkcd.com/927/ [16:43:52.0436] we're debating what the champion considers "without loss" [16:43:57.0738] When printing a Number into a string that satisfies isSafeNumeric you also have the issue of what to print for things like 1e40 or 1e-30, since this thing rejects exponential notation. [16:44:12.0146] because as strictly read, 0.1 fails (as do 0.2, 0.3 etc) [16:44:25.0124] no longer true [16:44:27.0552] I wonder if the use cases for this proposal are basically covered by decimal, in that one would just use decimals rather than numbers, but guarded (possibly many times) with `Number.isSafeNumeric` [16:44:28.0121] that was true but they fixed it [16:44:33.0409] oh how did they fix it? [16:44:41.0133] it's the thing on the screen [16:44:43.0373] see the current slide [16:44:50.0499] `MV(string) = MV(ToString(ToNumber(string))` [16:44:51.0670] ah [16:44:55.0148] that passes for the string `"0.1"` [16:45:13.0438] yeah then i'm back to jordan's question [16:45:18.0815] I just don't see what passing that is *useful* for [16:45:19.0716] why not do the string roundtripping...? [16:46:26.0145] well, consider the input string ".00000000000000000000001" [16:46:46.0809] import attributes has been merged into the spec 🎉 (https://github.com/tc39/ecma262/pull/3057) [16:47:13.0971] its really hard to propose any particular behavior without understanding the intention more [16:47:35.0646] true, if you accept inconsistently formatted strings as input, then doing the normalization yourself is hard [16:47:36.0401] ".00000000000000000000001" toStrings to `1e-23` so it does not satisfy `string === ToString(ToNumber(string)` [16:48:07.0014] * ~true, if you accept inconsistently formatted strings as input, then doing the normalization yourself is hard~ oh you weren't talking about the leading zero, nvm [16:48:07.0479] i see, thanks [16:49:07.0133] that said if you reject `"1e-23"` as input I'm not sure how you're supposed to produce values which are accepted by this [16:49:10.0250] I guess `toFixed`? [16:49:47.0810] > <@canadahonk:matrix.org> import attributes has been merged into the spec 🎉 (https://github.com/tc39/ecma262/pull/3057) JSON modules incoming [16:49:53.0183] though it's hard to know how many digits to use [16:49:58.0522] so the thing i heard was an app would choose to represent input as a double, or to use a userland library. that seems kinda wild to me [16:50:26.0989] to choose representation at runtime like that, given floating point arithmetic [16:53:28.0111] i... don't know how to disentangle that problem statement from "i wish we didn't have floats" [16:53:35.0483] Michael Ficarra: Not when validating input [16:54:18.0790] did Michael Ficarra press the forbidden button? [16:54:51.0274] He jumped ahead, is that what the forbidden button does? [16:55:18.0191] `I'm done speaking` is the forbidden button. otherwise I don't know how the queue jumped [16:55:20.0733] I think he means as if you did the maths on reals [16:56:37.0280] Chris de Almeida: Note that I don’t have the forbidden button on my TCQ page. [16:56:44.0007] possible tg5 topic: understanding how ieee754 works [16:56:52.0240] you do if you're currently the one on the queue [16:57:13.0763] meaning 'Speaking` [16:57:18.0368] * meaning `Speaking\` [16:57:24.0269] * meaning `Speaking` [16:57:36.0376] > <@softwarechris:matrix.org> you do if you're currently the one on the queue Should I press it 😏 [16:57:51.0875] Why is the button forbidden? [16:57:57.0014] Slide 4 seems like the clearest example to me. `0.1234567890123456789` cannot be accurately represented in `Number` as it truncates to `0.123456789012345678`. Similarly, `9007199254740993` cannot be represented. [16:57:58.0026] I'm about to adblock the button [16:58:19.0423] rbuckton: suppose you can accurately represent something. what do you do with that number then? [16:58:19.0580] assuming Chrome still permits me to do that [16:58:30.0091] or i suppose, what do you do with that string [16:58:47.0623] There is a race condition between you pressing it and the chairs pressing it for you. If the speed at which the chair's signal to stop pressing travels from their eyes to their brain is slower than the hand movement, they are going to press it for the person after [16:58:48.0505] > <@rbuckton:matrix.org> Slide 4 seems like the clearest example to me. `0.1234567890123456789` cannot be accurately represented in `Number` as it truncates to `0.123456789012345678`. Similarly, `9007199254740993` cannot be represented. see snek's comment above about what "can be represented" means [16:58:57.0673] For me, if it can be accurately represented, the function returns true. If it can't you inform the user (hence the use case for input validation) [16:59:10.0995] * There is a race condition between you pressing it and the chairs pressing it for you. If the speed at which the chair's neurons signal to stop pressing travels from their eyes to their brain is slower than the hand movement, they are going to press it for the person after [16:59:37.0175] if it returns true, what do you do with the input? [17:00:08.0276] A better approach, were we to keep the button, would be to just notify the chair that the user is finished. [17:00:19.0030] Should we do breakout sessions at the end of the meeting? https://github.com/tc39/Reflector/issues/552 [17:00:50.0604] would it be possible to have AV support for each breakout session for remote attendees? [17:00:58.0827] You use it? Beyond validating the input, its up to the developer to determine if it can then be safely used with other mathematical operations. [17:01:06.0963] Yeah, we should be able to do that [17:01:18.0817] i am highly skeptical of that claim [17:01:21.0444] but we'd probably keep note-taking informal [17:03:24.0609] It can be used for relational comparison at the least, and serialized via JSON. [17:03:49.0207] I think the challenge is that you're stuck in the binary64 world; stuck in that world, things are safe and if you say things aren't safe, you have no recourse to a safe alternative [17:04:15.0181] please everyone take a look at the transcription if you have time [17:04:33.0655] at some points I was the only one helping with the notes, and I definitely missed a lot of stuff at various points [17:06:03.0235] thanks Andreu Botella ! [17:07:47.0418] thank you for your help! if you ever find that we are not keeping up with the notes properly, please raise a `Point of Order`, so we can pause to rectify 🙏 [17:21:43.0029] many thanks to our note takers today 👏👏👏👏👏👏 Andreu Botella Daniel Ehrenberg Jesse Alama Linus Groh Oliver Medhurst Shane Carr [22:17:13.0018] littledan or whoever else is interested: here's my doc for avoiding allocations in engines for the iterator protocol https://docs.google.com/document/d/1M5S-u3N3vQkVBGFCoaYt_ABPGl0EW16QQrvDBaY2FiE/edit?tab=t.0 [00:55:46.0169] I missed the isSafeNumeric discussion due to being asleep at the time. If it gets a continuation, it'd be nice if it was earlier rather than later, but that's of course unlikely (mini-rant: For the last few years 4/6 TC39 meetings have been on North American timezones, with 2/6 on Pacific Time. This is not friendly to remote-participation from Europe. It'd be a little bit friendlier if at least the remote PDT meeting was moved to EDT or even further East). So posting the comments here that I'd have mentioned out loud had I been there: - I'm generally positive on enabling a developer to verify that WYSIWYG applies to their numeric string. - I'm not sure that "safe" is the right word here, though we do already have `Number.isSafeInteger`. I was thinking that "precise" or "canonical" could be more apt. The attachment point could also be different, as all of the pre-existing `Number.is*` functions require their input to be a number. - This seems to correlate very highly with the goals of Decimal, which, if accepted, would also expand the set of strings for which JS can provide a "safe" numerical representation. That proposal is specifically looking to improve the representation of values coming from the real world or elsewhere, which seems like the same domain as this. [01:04:49.0138] interesting. if it's not good for Europe then it'd literally only work for the Americas [01:07:27.0976] * interesting. if it's not good for Europe then it'd literally only work for the Americas (...though I think you just mean that the last couple hours don't work, which is much better than the entire meeting not working) [01:44:44.0742] I'm on Eastern European Time, and this week's meetings start at 20:00 and end at 03:00 for me. I'm used to having plenty of calls with folks on Pacific Time, but those are all scheduled for the morning there; TC39 calls take up the whole day. Comparatively, a meeting on US Eastern Time ends at my midnight, which is still bad but not as horrible. I do understand the benefits of running the meetings at different times, and the ones in Europe or Asia are about as much fun for North American participants, but it's the regularity of having all of the virtual meetings on North American timezones _and_ having one of them on Pacific Time that seems a bit extra. [07:08:47.0086] (Sorry for late reply just finally getting through backchannel) Sadly, no. In principle I wish they were, but public front end for this has yet to be resourced. We do have -much- public telemetry data (https://glam.telemetry.mozilla.org), but Use Counters specifically don't have a public front end (and I currently have to make my own dashboard for every use counter probe). [08:39:13.0834] you know, one way we might be able to resolve the "safe numeric string" proposal is for the champion to give us a large list of sample strings and whether they are "safe" and we work backwards from there to try to figure out what they mean [08:42:46.0540] ZiJian Liu: ☝️ [09:59:32.0439] Please nominate breakout session topics here: https://github.com/tc39/Reflector/issues/552 [10:06:00.0795] it feels somewhat odd to use decimal numbers with imperial units [10:06:24.0763] no one says "1.375 inches", it's always "1 3/8 inches" [10:07:18.0783] Are those fractions always with a power of 2 as the denominator? [10:07:58.0203] no, they switch to thousandths [10:08:15.0922] and sometimes they are thirds! [10:09:02.0561] i'm a huge fan of unit apis. durations and sizes especially in computers. [10:09:10.0541] usually powers of 2 though [10:09:16.0507] thousandths are mostly only used by machinists [10:09:37.0282] *machinidths [10:09:37.0441] i've seen thirds for volumes, but usually for lengths i think i only really see powers of 2?= [10:09:37.0955] a thousandth of an inch is pronounced a "thou" and is arguably its own unit [10:09:38.0665] * i've seen thirds for volumes, but usually for lengths i think i only really see powers of 2 [10:09:48.0704] i mean no one uses 128ths of inches [10:10:07.0487] * i've seen thirds for volumes (like ⅓ cup, etc), but usually for lengths i think i only really see powers of 2 [10:14:41.0091] whoever else is doing notes y'all are killing it [10:14:43.0080] > <@bakkot:matrix.org> thousandths are mostly only used by machinists not just used by machinists but also those who employ them, writing specs and tolerances for parts/materials [10:14:59.0620] * whoever else is doing notes y'all are killing it ❤️ [10:15:37.0394] yeah the captioners this meeting are amazing [10:15:42.0357] I have woodworking tools that are capable of 1/128” adjustments. [10:16:36.0687] And I have used that precision. [10:17:32.0660] For folk wanting to attend the SeattleJS Community event in-person on Thursday evening, please respond to [this poll about the NDA requirement.](https://github.com/tc39/Reflector/issues/547#issuecomment-2669412895) ❄️ I need to provide the count and names of delegates by midday today in order to stand a chance of getting an exemption. [10:19:05.0779] For some specialties, they’d say 20 thousandths. [10:21:12.0091] Measure seems more appropriate for 402 [10:21:51.0295] I wouldn't be opposed to this, but worth considering why Temporal should be in 262 and Measure in 402 [10:23:44.0877] ...i thought temporal was in 402 [10:23:54.0410] what are the applications and developers who want to use measure? [10:24:09.0219] > <@devsnek:matrix.org> ...i thought temporal was in 402 Temporal is in a proposal [10:24:23.0758] yeah i mean a proposal for 402 [10:24:34.0861] it's been proposed for addition to 262. The editors should say something if they want it to land in 402 instead... [10:24:38.0844] i thought it was split between basically what needs/doesn't need CLDR [10:24:40.0694] Think I’ll need to catch up on this committee meeting tomorrow via the notes. Trying to attend remotely in a different time zone is just too tiring after a full day of work. [10:24:42.0379] it's kinda split, some data-dependent stuff _are_ in 402. bulk of it is in 262 [10:25:13.0230] at least with test262 there is a load of tests not in 402 [10:25:35.0575] idk if this matches with what the presenters want but personally i'd love stuff like `Measure("hours", 2).into("milliseconds")` for passing to timers, or `Measure("megabytes", 3).into("bytes")` for allocating buffers. stuff like that [10:25:56.0580] why do you think that should be in the language? [10:25:57.0813] * idk if this matches with what the presenters want but personally i'd love stuff like `Measure("hours", 2).into("milliseconds")` for passing to timers, or `Measure("megabytes", 3).into("bytes")` for allocating buffers. stuff like that, pretty much always as program constants. [10:26:15.0084] time and bytes come up a lot [10:26:19.0945] meters rather less so [10:26:23.0248] > <@shuyuguo:matrix.org> why do you think that should be in the language? it's a common need [10:26:45.0194] (also Temporal durations already do the time part of this) [10:26:53.0882] having constant number of bytes is a common need, having a general measure isn't is my hunch [10:27:50.0921] yeah i mean i'd be fine with Duration and Size classes rather than a generalized Measure thing. i'm not against Measure though, especially if there's some sort of cldr-ish data to feed in it i think its generally nice. [10:28:17.0165] would Measure be significantly more complex to spec or implement than Duration + Size? [10:28:19.0068] whether 'generally nice' meets everyone bar for new apis is 🤷 [10:28:29.0347] * whether 'generally nice' meets everyone's bar for new apis is 🤷 [10:28:31.0157] yeah unifying it is a nice way to organise things to allow for further expansion [10:29:00.0725] and what about units that JS apps are more likely to want to manipulate that are not physical units? [10:29:41.0193] I believe wether Measure supports custom units or not is an open question, so the answer to "what about that" is "well we could support it" [10:29:55.0408] I think rates are another common one: bytes/time or count/time [10:30:36.0331] what i mean is, those seem to be more useful units for the domain than grams and inches [10:30:43.0192] shu I feel like these would be reasonable things to put on the queue [10:30:57.0650] #tc39-decimal:matrix.org [10:36:05.0656] gentle reminder to please not use the `I'm done speaking` button in TCQ [10:40:42.0838] Chris de Almeida Could you push my queue item to the bottom? Ideally to 5 mins before the end [10:41:19.0689] https://github.com/unicode-org/cldr/blob/54e3b840473a9fd9abc747de485355338e4618e0/common/supplemental/units.xml#L149-L392 [10:42:27.0021] * cf. https://github.com/unicode-org/cldr/blob/54e3b840473a9fd9abc747de485355338e4618e0/common/supplemental/units.xml#L149-L392 and https://github.com/unicode-org/cldr/blob/54e3b840473a9fd9abc747de485355338e4618e0/common/supplemental/units.xml#L149-L392 [10:43:04.0209] * cf. CLDR [`unitConstants`](https://github.com/unicode-org/cldr/blob/54e3b840473a9fd9abc747de485355338e4618e0/common/supplemental/units.xml#L149-L392) and [`convertUnits`](https://github.com/unicode-org/cldr/blob/54e3b840473a9fd9abc747de485355338e4618e0/common/supplemental/units.xml#L149-L392) [10:43:48.0054] `` [10:44:07.0795] What operations precedence to they use there [10:48:01.0891] The Measure/Amount presentation zooms out far enough that I can imagine that `new Amount("1/3", "cup")` is in the picture, assuming Amount is a generically typed tuple of magnitude, unit, and precision, where Amount does not imply any arithmetic, unit conversion, currency conversion, or even interpretation of the type. [10:48:16.0597] not point of order but could someone else help with notes please :) [10:48:22.0779] * The Measure/Amount presentation zooms out far enough that I can imagine that `new Amount("1/3", "cup")` is in the picture, assuming Amount is a generically typed tuple of magnitude, unit, and precision, where Amount does not imply any arithmetic, unit conversion, currency conversion, propagation of precision, or even interpretation of the type. [10:48:44.0552] i can help [10:48:49.0655] * The Measure/Amount presentation zooms out far enough that I can imagine that `new Amount("1/3", "cup")` is in the picture, assuming Amount is a generically typed tuple of magnitude, unit, and precision, where Amount does not imply any arithmetic, unit conversion, currency conversion, propagation of precision, or even interpretation of the composite types. [10:49:54.0915] (fine now, thanks all) [10:55:00.0609] snek Remember that for Duration we have temporal, we would probably not support time units in Measure [10:56:00.0550] That suggests Measure would not support Currency if there were Currency. [10:56:14.0383] And I think that’d be sensible. [10:56:31.0157] yeah i guess. it could also just be defined in terms of temporal.duration for duration units. [10:57:04.0409] i don't feel super strongly about it other than just having these things exist in some form [10:57:05.0844] That is “Conversion” doesn’t mean the same thing for Measures (including Duration) and Currencies. [10:57:21.0987] yeah we can't do currencies [10:57:30.0089] err, currency conversions [10:57:59.0857] I am struggling to think of times when you actually need units other than time and bytes in JS applications [10:58:10.0886] except obviously in specific applications like a recipe site or a house planner [10:58:32.0583] which, those feel like they are adequately met by a library [10:58:38.0620] the girl scout cookie inventory system site has "cases" and "packages", but that's specific, as you said [10:58:51.0242] yeah time & bytes are the only two things i use [10:59:06.0178] Has there been a proposal for something like `Currency`? [10:59:15.0899] right, to complete my thought: if the answer to my question of "what about these other common units that JS apps actually use, like bytes and px and whatever" is "userland code, custom units", my response to that is "then use a userland library"? [10:59:29.0278] what does `Currency` do? does it have more stuff than just being a decimal type? [10:59:49.0664] ties a currency to a number [10:59:50.0857] I think a lot of the time, the units are just kept implicit, people use bare numbers, and there are bugs when units are accidentally confused/mixed. But I'm not sure what would lead to a design of Measure that would ensure actual uptake to avoid those bugs. [10:59:53.0271] there is something to be said for having a standard object type that can hold a value and an arbitrary unit, so those libraries can interop more cleanly [11:00:20.0919] i understand that in the abstract, which is why i want to see what people do today [11:00:40.0249] in some way, this is analogous to how the most popular representation of decimal is strings, not any of the decimal libraries. [11:00:56.0618] i think at the very least ones like time, bytes, pixels have some motivation from being units that js/dom have standard library features using [11:01:34.0182] i agree, which is why if we have a concept of built-in units, i'd care more about those being present than grams and inches [11:01:57.0396] but it seemed like the champions weren't so interested in that [11:02:01.0641] well, the idea is, units are arbitrary, un-interpreted strings; unit conversions may be better as a separate thing, as Eemeli proposed [11:02:02.0291] if I am correct that people mostly only need these when building a specific application like a recipe site, then I don't think you are likely to need interop between libraries [11:02:02.0567] yeah i think i can agree with that [11:02:15.0960] * yeah i think i can agree with that (to shu) [11:02:52.0806] well, I think this discussion is motivation for limiting the unit that are baked into the language and *possibly* motivating a mechanism for allowing users to specify their own unit definitions. [11:03:33.0354] ``` const myUnit = new Unit({ ...}); const measure = new Measure(1.234, { unit: myUnit }); ``` [11:04:57.0937] shu: The Amount type for currencies at Agoric is a tuple of a “brand” for the currency and a value that can be a bigint, or even an array of serial numbers. We pair Amounts with a corresponding AmountMath. Amounts are very domain-specific. [11:07:44.0206] Those that mentioned weaker parts of the space carrying other parts (e.g. Michael Ficarra, but also others with similar words), what do you mean by "weak part" and "strong part"? The answer doesn't seem to be consistent across delegates [11:07:48.0979] * Those that mentioned weaker parts of the space carrying other parts (e.g. Michael Ficarra, but also others with similar words), what do you mean by "weak part" and "strong part"? The answer doesn't seem to be consistent across the committee [11:08:04.0469] cf.format(1e12) is '1M'? [11:09:44.0035] fyi taking break from notes but I think others are already helping \o/ [11:10:04.0444] > <@nicolo-ribaudo:matrix.org> Those that mentioned weaker parts of the space carrying other parts (e.g. Michael Ficarra, but also others with similar words), what do you mean by "weak part" and "strong part"? The answer doesn't seem to be consistent across the committee like which parts do I feel are weak vs strong, or what do those words mean? [11:10:11.0140] Yeah [11:10:29.0888] uhh that was an either-or question @nicolo-ribaudo:matrix.org [11:11:05.0592] Ohh I thought you were asking what else would _my_ words mean 😛 Which parts are weak and which are strong [11:11:59.0846] I don't have an opinion on which parts are weak and which are strong, just that I don't want the strong one carrying the weak one [11:15:39.0648] FYI, for duration, the format used in `Temporal.Duration.p.toString` is the same format proposed by eemeli 's stable formatting proposal. This is probably assumed by everyone, but wasn't mentioned in the presentation so figured I'd note it here. [11:16:05.0227] why are we not stopping the meeting for the PoO? [11:16:07.0262] Chris de Almeida I'll help with notes [11:19:28.0894] I'd encourage people to yell out such points of order for help with notes [11:22:26.0343] why would it use "null" instead of "zxx" if its called "zxx" elsewhere [11:22:36.0227] (i ask this not knowing much about these apis in general) [11:23:04.0049] add to tcq? seems fair to me but also don't know much [11:23:15.0015] Justin added it to TCQ [11:29:06.0178] > <@littledan:matrix.org> in some way, this is analogous to how the most popular representation of decimal is strings, not any of the decimal libraries. I think there's a strong argument to be made that this is due to strings being built in and those libraries not being. When math is needed on this decimal strings, the most popular behavior is also to just do a float parse and perform the bath with ordinary Number, which is terrible, but it's there and the library isn't. [11:29:36.0272] Using "null" feels just slightly off given the prevalence of `null` returns in web apis. I'd generally prefer the use of `zxx` [11:29:37.0192] And both of these work reasonably well *often enough* that the pressure to use a library is light [11:29:50.0917] exactly. For the same reason, having Measure will encourage more usage of it. (But it's true, Decimal libraries seem to be more popular already than Measure ones) [11:30:12.0409] did someone clarify the reasoning for this [11:30:46.0791] I imagine this might be because it's sort of a layering violation for us to define something in the locale space [11:31:20.0149] my other guess is maybe webcompat where `zxx` already behaves some way but `null` previously threw? [11:31:37.0819] > zxx - non linguistic content, such as onomatopoeia (animal sounds) [11:31:42.0461] i guess zxx is overloaded [11:32:35.0782] I can just imagine some weird intesectional edge case where someone accidentally ends up passing `null` because that's what another api returned and that's coerced into `'null'` when that was not the intention. Not a blocking case but a possible quirk of the approach [11:34:43.0757] that's a very funny description -- spelled-out animal sounds are clearly localized :) [11:36:06.0252] > <@littledan:matrix.org> that's a very funny description -- spelled-out animal sounds are clearly localized :) I bet a lot of people without much exposure to other cultures believe this though [11:36:41.0217] that is until they visit france and the dogs start saying ouaf ouaf! [11:36:49.0996] in the same way lot of people think "there's exactly X continents" is a universal truth [11:41:01.0504] Waldemar already asked, but is it correct that cf.format(1e12) returns 1M? [11:42:59.0694] > <@nicolo-ribaudo:matrix.org> Waldemar already asked, but is it correct that cf.format(1e12) returns 1M? eemeli: no, it returns 1T [11:43:02.0099] hmm, I get "1,000,000,000,000" [11:43:46.0614] Richard Gibson: fyi, your mic volume is very low [11:44:52.0338] (oops, forgot the `"compact"` bit sorry) [12:03:47.0718] Yeah, sorry, that was a typo. [13:13:08.0647] so who makes the benchmarks? [13:13:17.0206] * so who makes the benchmarks, or decides which ones matter? [13:13:42.0200] https://github.com/WebKit/Speedometer/blob/main/Governance.md [13:14:26.0576] Is the main point of contention here whether this needs to be a getter/data prop? [13:15:12.0595] Or is it because anything was added to a TC39 owned class? [13:15:37.0353] Isn't this the same as one of the browsers adding a new API? [13:16:14.0024] adding a new API outside a standards process, yes [13:16:28.0625] in all such cases it's helpful to get broader input as early in the process as possible [13:17:12.0829] But they add new APIs to the global all the time. [13:17:20.0842] new non-standard ones, all the time? [13:17:35.0150] Not standardized here. [13:17:36.0557] if so, i would think that's something that should concern both tc39 and whatwg [13:17:44.0338] right, standardized *somewhere* tho [13:17:57.0950] It's common for browsers to ship APIs at the same time as creating the equivalent of a stage 1 proposal in w3c/whatwg [13:18:17.0876] there is a qualitative difference between something developed with multiple stakeholders, and something one private company's team unilaterally decides to do [13:19:09.0330] Or at least, for one of the browsers [13:21:59.0417] i recommend people who care about this follow intents emails on Chromium and Mozilla's email lists, and read STP notes for Safari [13:22:18.0491] * i recommend people who care about keeping abreast of all things that ship to follow intents emails on Chromium and Mozilla's email lists, and read STP notes for Safari [13:22:24.0315] > <@nicolo-ribaudo:matrix.org> It's common for browsers to ship APIs at the same time as creating the equivalent of a stage 1 proposal in w3c/whatwg this sounds like a really problematic process [13:22:25.0394] i definitely try to do that, but that is a large firehose of information [13:22:43.0496] * i definitely try to do that, but that is a large firehose of information, and much of it is not relevant to javascript [13:22:44.0395] https://x.com/intenttoship [13:23:07.0183] https://x.com/search?q=from%3Aintenttoship%20capturestacktrace&src=recent_search_click [13:23:16.0209] (or https://bsky.app/profile/intenttoship.dev) [13:23:23.0237] whatwg standards don't follow the same model as tc39. tc39 honestly has something very special in terms of how much weight non-implementors have in the process. [13:23:25.0696] (you do have to read the notes for Safari since they're not split out) [13:23:36.0821] yeah there's soooo much CSS and other stuff I just don't want to hear about coming through the intents [13:26:23.0344] i'm glad it's rare. rare makes it notable and worth mentioning. [13:27:47.0522] `Function.prototype.caller` :D [13:27:54.0726] there's still a few non-standard things out there [13:27:56.0428] (v8 changing how captureStackTrace works a few years back was also notable) [13:30:15.0865] 🫠 https://github.com/nodejs/node/blob/f6ce48636b08292baac4fd443399ab9972e1a69b/lib/internal/errors.js#L148 [13:32:16.0712] oh fun, another use of `SetterThatIgnoresPrototypeProperties` [13:32:24.0076] I was hoping to forget that AO existed [13:33:32.0069] `SetNoOverrideMistake` [13:33:59.0403] that's this afternoon's topic [13:36:05.0211] speaking of non-standard features, https://github.com/tc39/proposal-regexp-legacy-features has been stage 3 for ~8 years [13:36:15.0823] I don't know if actually matches what browsers do [13:36:21.0286] or if there's tests [13:36:35.0256] > This does not reflect what the implementations do, but what the editor thinks to be the least bad thing they ought to do in order to maintain web compatibility. [13:36:51.0858] bakkot: I was thinking about that proposal during the prior discussion. [13:36:52.0593] ah [13:41:39.0028] ljharb It'd be great to have a note in the spec text saying that the reason those accessors are so weird is web compat, like the one at https://tc39.es/ecma262/#sec-set-iterator.prototype.constructor [13:41:57.0225] bakkot: fwiw DOMException is a true Error now in the web, thanks to Error.isError, if that answers your question [13:42:08.0975] sgtm, a PR would be appreciated :-D [13:42:39.0454] Damn I hate when asking other people to do more work backfires [13:44:27.0626] it's slightly different [13:44:33.0778] I think there are [13:45:44.0063] browsers have said that they find that proposal to be very low priority, but at least Mozilla said they'd review a patch for them. I hope we can eventually make a collective decision about the proposal's future, though people didn't seem to like that idea when I brought it up in a proposal sweep [13:48:27.0370] `(new DOMException).stack // undefined` [13:48:33.0008] is the intention to change this? [13:48:42.0493] (Firefox actually has a stack here) [13:48:44.0880] waldemar: ``` > Object.getOwnPropertyDescriptor(e, 'stack').get === Object.getOwnPropertyDescriptor(e2, 'stack').get true > Object.getOwnPropertyDescriptor(e, 'stack').get.x = 1 1 > Object.getOwnPropertyDescriptor(e2, 'stack').get.x 1 > ``` [13:48:50.0608] * waldemar: \`\`\` > Object.getOwnPropertyDescriptor(e, 'stack').get === Object.getOwnPropertyDescriptor(e2, 'stack').get > true > Object.getOwnPropertyDescriptor(e, 'stack').get.x = 1 > 1 > Object.getOwnPropertyDescriptor(e2, 'stack').get.x > 1 ``` [13:48:59.0020] * waldemar: ``` > Object.getOwnPropertyDescriptor(e, 'stack').get === Object.getOwnPropertyDescriptor(e2, 'stack').get > true > Object.getOwnPropertyDescriptor(e, 'stack').get.x = 1 > 1 > Object.getOwnPropertyDescriptor(e2, 'stack').get.x > 1 ``` [13:49:22.0242] it's implementation-defined, so while i'd expect them to have a stack, it's up to the browser what's in it [13:49:31.0693] well it's actually undefined in Chrome [13:49:34.0204] not a string [13:49:47.0389] it'd have to become an empty string, i think, yes, as currently specified [13:50:02.0366] sgtm but that will need WPT tests [13:50:15.0894] sounds good, i can probably write those [13:52:13.0166] * waldemar: ``` > const e = new Error(), e2 = new Error(); > Error.captureStackTrace(e); > Error.captureStackTrace(e2); > Object.getOwnPropertyDescriptor(e, 'stack').get === Object.getOwnPropertyDescriptor(e2, 'stack').get > true > Object.getOwnPropertyDescriptor(e, 'stack').get.x = 1 > 1 > Object.getOwnPropertyDescriptor(e2, 'stack').get.x > 1 ``` [13:56:45.0068] bakkot: it's weirder [13:56:46.0548] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.cc;l=61;drc=8b7ec5d99ad2d76762011a50ed1c14d754e3ff5f [13:56:50.0302] like, it depends on how it's thrown [13:57:27.0411] nice. [13:58:00.0042] witchcraft! [13:58:47.0969] This would be a WebIDL PR, not HTML [13:59:19.0456] I'm not sure it's actually a change to any of the specs [13:59:26.0921] it would need WPT changes [13:59:36.0906] but stacks for DOMExceptions aren't spec'd anywhere afaik [13:59:51.0483] and this would apply to DOMExceptions as written automatically [14:00:08.0333] that's more headwinds really [14:00:27.0255] unclear how much appetite there is if it requires significant blink/Gecko/non-JSC webkit-side work [14:00:37.0601] > <@bakkot:matrix.org> but stacks for DOMExceptions aren't spec'd anywhere afaik WebIDL says that if any implementations have a stack property on errors, they must have it in DOMException: https://webidl.spec.whatwg.org/#js-exceptions [14:00:50.0054] the stack is also structured clone [14:00:53.0273] * the stack is also structured cloned [14:00:56.0095] ah [14:00:57.0305] well [14:01:01.0231] browsers are not doing that already [14:01:09.0204] * browsers are not (always) doing that already [14:01:21.0753] oh, and structured clone would definitely need changes [14:01:28.0402] * oh, and structured clone would definitely need changes, if it's cloning stacks [14:01:51.0774] yeah [14:03:16.0622] > User agents should attach a serialized representation of any interesting accompanying data which are not yet specified, notably the stack property, to serialized. [14:03:22.0817] ... sure [14:05:09.0876] what are week numbers [14:05:28.0135] sometimes I think ecma262 is too informal, and then I see some of the other web specs [14:06:18.0301] https://en.wikipedia.org/wiki/Week#Numbering [14:06:33.0414] wild [14:06:39.0010] "first thursday of the year" just wild [14:06:49.0433] > <@devsnek:matrix.org> what are week numbers spend a bit of time in continental Europe and you'll know [14:06:56.0398] scandanavian countries use them colloquially apparently [14:07:21.0619] timeshares in the US use them [14:07:31.0592] i guess amsterdam isn't european enough for this [14:07:41.0995] Can confirm ubiquitous in Sweden [14:07:55.0643] Screenshot from our secret Igalia documents [14:07:59.0590] That's a week number [14:08:02.0592] We use it all the time [14:08:53.0145] > <@nicolo-ribaudo:matrix.org> Screenshot from our secret Igalia documents hmm, what could this "...mpilers team" at Igalia be? 🤔 [14:08:53.0649] a... weekref, if you will [14:08:57.0358] Also fun fuct we call out big company-wide meetings like TV series [14:08:58.0420] whoops, not TDZ [14:09:05.0298] The next one is S25E02 [14:10:00.0887] decompilers team [14:10:40.0593] I suspect I am not alone in having absolutely no opinions about minutia of week numbering [14:19:11.0933] https://chromestatus.com/metrics/feature/timeline/popularity/5209 [14:19:15.0858] i can't believe it's not zero [14:19:25.0022] i want to find these sites and i want to talk to them [14:19:48.0058] it's looooow [14:19:55.0126] 0.000007 [14:20:14.0559] %? [14:20:21.0741] * %? yeah [14:20:30.0182] yeah so 2 more `e`s [14:20:58.0372] shu Why is it not showing sample websites? [14:21:18.0151] i have no idea [14:21:19.0130] I know at least some people are (or were) using stamping to attach data to arbitrary objects [14:21:22.0933] probably sample is too small [14:21:23.0002] because of weakmaps being slow [14:21:27.0060] so it's probably that [14:21:35.0201] i think it only shows sample websites by correlating the use counters with crawling of HTTP archive [14:21:42.0233] the return override thing is simply the design of ES6 classes. I get annoyed ever time I hear it referred to as a "mistake". [14:21:46.0734] Are we also going to ban non-extensible objects from being weakmap keys to preserve the original equivalence of private fields and weakmaps? [14:21:47.0846] if there are no sites in HTTP archive that has the counter, i don't think we record other data [14:22:11.0352] my understanding is no, mark is giving up on that equivalence [14:22:17.0560] oh but we're talking about the set thing [14:22:18.0425] I believe the reason Mark is now confident with proposing this is that we already lost that equivalence due to the window proxy [14:22:19.0490] sounds like an argument for decimal: being able to reliably compute extremely unpopular features in tracking dashboards [14:22:20.0673] can you install private fields on symbol instances [14:22:31.0521] the deciding factor here is in-line vs out-of-line storage [14:22:37.0700] on boxed ones sure [14:22:50.0669] they don't need to be boxed to be weakmap keys [14:22:56.0822] the code that broke with the inherited Set thing is an old version of lodash. It was unclear how to fix it. [14:23:16.0973] Allen Wirfs-Brock apparently put in the inherited Set behavior on purpose, FWIW [14:23:22.0978] hm, "symbols as weakmap keys" did not consider that weakable was supposed to imply field-stampable [14:23:36.0124] (none of the rest of us were able to understand his explanation for why it was a good idea, though) [14:23:38.0445] can't return primitives from constructor right [14:24:57.0603] it's independent of classes, though... [14:25:31.0419] Right, this Set inherited non-writable thing is separate, sorry for my confusion [14:25:37.0415] wasn't it a custom elements thing? [14:25:43.0817] for the upgrade [14:26:09.0447] well, CE was an argument for it, but it was also just an instance of keeping things kinda similar to ES5 classes [14:26:53.0082] I guess my annoyance comes from people coming across it first in the context of fields, but it's really not because of fields [14:30:12.0273] permanent inheritance is referred to as "immutable prototype exotic object" in the spec FWIW [14:31:47.0696] I would kind of like "rationalizing the behavior of" some weird web thing to generally not be a motivation [14:31:57.0322] it's kind of nice if we get that because of some other thing that we want [14:32:09.0072] but should not really be a goal in itself [14:32:38.0255] we did consider this unbundling when immutable prototype was introduced, but concluded the same at the time, that it's not worth it to unbundle [14:33:18.0539] How are we going to investigate whether the carveout works? [14:33:28.0055] When / in which proposal was immutable prototype introduced? [14:33:30.0849] I love seeing proposal that end up being "actually, it can be reduced by 80%" [14:33:51.0487] This was a PR to fix a Proxy security risk which delayed its shipping [14:35:04.0612] https://github.com/tc39/ecma262/pull/308 [14:35:51.0803] tyvm [14:37:16.0888] huh, TIL it was not always immutable [14:37:38.0894] I refuse to believe that is new information to you [14:38:31.0413] I barely have room to remember the horrors we currently have in the language; no way I'm remembering the few we've actually fixed [14:40:23.0671] I'm pretty sure you were there. IIRC this was literally the first thing I got into the language. [14:40:46.0231] I think it might predate Kevin by a couple meetings [14:41:17.0394] still, that's no excuse 😛 [14:44:59.0972] sorry, did someone get dropped off TCQ? nicolo-ribaudo maybe? [14:45:06.0135] I am going to drop from the call at the break, mgaudet will be representing SpiderMonkey (at least until he has to drop as well) [14:45:13.0606] Yes but Dan asked the same question [14:45:18.0684] ok [14:45:50.0819] Isn't it only a throwing behavior in strict mode? [14:46:04.0436] oh hmm [14:46:13.0769] does it go from silent no-op to different behavior? that's scarier [14:46:58.0267] Could we just "fix the override mistake" in strict mode? [14:47:06.0613] * Could we just "fix the override mistake" only in strict mode? [14:47:34.0241] IIRC the lodash thing was in strict mode [14:47:55.0910] like that's why it caused the throw that it depended on [14:48:08.0397] I mean that we do Justin's change, but also keep setting an inherited non-writable property as a no-op in sloppy mode, to avoid going to "silent noop to different behavior" [14:48:12.0366] Re Shu's message [14:48:24.0210] that would give up a lot [14:48:24.0692] i'm confused now. can we hope to fix it for sloppy mode at all? sounds like no [14:48:43.0975] I dunno if we found any compat issue in sloppy mode [14:48:52.0269] maybe we *will* find one, though [14:49:33.0889] node (and a lot of things) would like to have frozen intrinsics and probably cannot do so if the override mistake is only fixed in sloppy mode [14:49:38.0028] * node (and a lot of things) would like to have frozen intrinsics and probably cannot do so if the override mistake is only fixed in strict mode [14:50:26.0915] 📣 **Announcement** I added a "Stage 2.7 reviewers" column at https://github.com/tc39/proposals?tab=readme-ov-file#stage-2, go there and add reviewers for your proposals or proposals you are a reviewer of [14:50:48.0292] Hmm. Sloppy mode seems to actually not have the override mistake? [14:51:11.0084] `object.constructor` would change to be the new function [14:51:27.0248] yeah that screenshot shows sloppy mode doing a silent no-op [14:51:33.0178] so we'd be changing one non-throwing behavior to another non-throwing behavior [14:51:42.0519] so there are two web compat questions: sloppy mode + toString [14:52:36.0883] Ah, yes. it's showing `Object.constructor`. [15:04:04.0322] shu For the use counter, I believe after step 16 of https://tc39.es/ecma262/#sec-object.prototype.tostring you'd need to add: ``` 1. If O has a [[ViewedArrayBuffer]] internal slot and _tag_ is not "DataView", trigger the counter. 1. Else, if O has a [[SetData]] internal slot and _tag_ is not "Set", trigger the counter. 1. Else, ... (for all the types listed in that issue) ``` [15:04:25.0306] I don't get it; what evidence do we have that we can't apply this in sloppy mode? I thought the only evidence we had was, we can't fix the mistake in strict mode [15:04:55.0486] we have no specific evidence either way, but a strong general intuition that making errors into non-errors is more likely to be web compat than changing behavior of non-error paths [15:05:46.0334] The issue is that sloppy mode doesn't error, so other use cases aside from lodash may not be as obviously broken. [15:05:56.0744] it's just really hard to figure out [15:05:59.0483] we have no idea what breakage means [15:06:28.0101] similarly, fixed leaves private fields mutable, right? [15:06:56.0774] it could be something non-local eventually throws, it could mean it behaves differently and you get a load of bug reports that are just like "site broke" "video doesn't play" "button doesn't work" [15:07:48.0469] yes, e.g. `Object.fix(new Map()).set("foo", "bar").size === 1` [15:07:50.0971] thanks, will think on that [15:08:27.0397] anyway i am not sure if there's consensus that we should fix override mistake in strict mode only [15:11:08.0736] Are we sold on calling this "fix"? I think a name more aligned with what it's actually doing might make more sense. "Fix" seems too general of a term, especially if the "fixed" behavior we were previously discussing gets rolled into "extensible". [15:22:22.0894] i would prefer a name other than fix, yes [15:24:05.0408] is mark in this channel, i can't find him via autocomplete [15:28:54.0996] MarkM doesn’t patrol Matrix, no. [15:29:06.0636] For that, he has minions. [15:30:01.0371] I liked Stable [15:32:26.0449] > <@kriskowal:aelf.land> For that, he has minions. MarkMinions? [15:33:18.0405] kriskowal: okay, i'll post to issue in the github [15:36:35.0780] some possibilities raised at various points: Object.{crystallize,fix,lock,petrify,stabilize} [15:37:06.0914] I could also imagine an extra option to `Object.freeze` [15:37:07.0541] > <@gibson042:matrix.org> some possibilities raised at various points: Object.{crystallize,fix,lock,petrify,stabilize} okay maybe fix isn't so bad [15:37:15.0260] `Object.freeze(x, { nontrapping: true })` [15:37:21.0200] i like that [15:37:27.0798] the options bag [15:37:42.0925] So many allocations [15:37:58.0010] do you not re-use your options bags? :) [15:37:59.0373] don't freeze where performance matters, ez [15:38:27.0693] it's `erights` ftr [15:38:42.0976] What I don't like much about fix is that even if I know it's "fixed as in it cannot move" I keep thinking that objects are then either fixed or broken [15:39:15.0666] `Object.isBroken` [15:39:25.0977] always returns true [15:45:02.0639] TCQ empty -> time to ask for Stage 3 for R&T [15:48:58.0166] I still don't understand why? In principle, shouldn't freeze allow more optimization ? [15:49:27.0694] who is going to put in the work to write those optimizations instead of more heavily optimizing the common case? [15:50:13.0967] I am not totally clear if this vision is still keeping `${} === ${}` [15:51:03.0490] I am guessing no? [15:51:21.0214] i was told yes [15:51:23.0967] was that explained and I just missed it? [15:51:25.0997] hm [15:51:27.0075] I will ask [15:51:34.0255] I think it cannot, I don't think we've gotten there yet [15:51:53.0528] Let's continue the presentation; it answers bakkot's question [15:51:54.0229] it'd have to memoize the contents and keep the resulting object somewhere, so i'm not sure how it'd be practical [15:51:59.0596] ah, slides have an `Object.equalRecords` [15:52:29.0897] I did go through the slides and did not immediately see an answer to my question but I think the existence of `equalRecords` implies no [15:52:31.0528] I think that may have been the next section before we broke for the queue? The slide mentioned composite keys [15:52:41.0655] composite keys don't have to be `===` [15:52:48.0804] if you make the collections special case them [15:53:53.0770] there are some questions about backwards compat if that happens by default [15:54:12.0318] (again we're jumping ahead of the presentation) [15:54:24.0902] I don't see how there can be back compat questions about new syntax? [15:54:28.0592] Not really backwards compat, as these things don't exist yet [15:54:35.0077] More "mixing old and new code" [15:54:39.0108] * More "mixing old and new code" might not work [15:54:43.0376] right sorry [15:54:56.0027] i don't quite understand that, excited to see the slides ig [15:55:12.0708] libraries using a Map assuming that putting 2 different object cannot result in the same entry in the map [15:55:32.0070] I *really* want this composite key feature built-in [15:55:34.0393] code often breaks when we add new concepts to the language [15:55:45.0870] this doesn't break that assumption, unless you mean specifically due to this having typeof "object" [15:55:46.0877] * code often breaks when we add new concepts to the language and you try to use them with old code [15:56:44.0201] Isn't this already broken by `typeof null === 'object'` ? [15:56:53.0719] also: can you put one of these in a WeakMap? [15:56:58.0084] 😠 SameValueZero [15:57:09.0148] I guess maybe only if it contains at least one thing which can be put in a WeakMap? [15:57:17.0090] The TC39 rule is "when somebody says `typeof x === "object"`, pretend they said `Object(x) === x`" [15:57:19.0566] type doesn't matter. reality is that today if a !== b, then set.add(a) is distinct from set.add(b) [15:57:48.0598] NaN enters the room [15:57:49.0898] r&t should override === imo [15:58:00.0209] just really annoying otherwise [15:58:06.0779] no [15:58:08.0542] no no no [15:58:16.0815] please do not add attractive nuisances to the language [15:58:17.0291] counterpoint: yes? [15:58:53.0678] we don't want to overload ===? [15:58:55.0518] That was the feedback from implementors: no can't do [15:59:08.0216] well [15:59:11.0313] it is not totally clear [15:59:14.0648] I think this vision is, no [15:59:18.0610] though some people would like to [15:59:22.0140] or just give me a System.goodEqual function which i can transpile every `===` into [15:59:24.0037] the only way it makes sense to have it, and not overload `===`, is if "same" objects are actually the same object [15:59:33.0116] ``` > const s = new Set() undefined > s.add(NaN) Set(1) { NaN } > s.add(NaN) Set(1) { NaN } ``` [15:59:56.0293] but `NaN !== NaN` 2025-02-20 [16:00:06.0506] and yes I expected to be called out for that one [16:00:07.0017] counterpoint: i really want composite keys [16:00:08.0676] doesn't matter, we do the right thing [16:00:25.0900] i also want them, but i'm not sure why the two are linked [16:00:34.0486] Manually building tries is a pain [16:00:38.0230] this proposal is just composite keys [16:00:44.0518] that is the whole proposal [16:00:47.0514] if I understand correctly [16:00:47.0689] oh [16:01:14.0631] right, but can't it just, like, do the nested weakmap + a finalization-registered weakref, in the spec? [16:01:18.0547] A goal of the presentation is for delegates to say "yeah let's just do composite keys", or "let's do R&T" [16:01:19.0743] I can't bother my pretty head with `NaN` and `-0` [16:01:29.0392] then a composite key of the same object will never observably be a different object [16:01:32.0122] then you can't do a composite key of only primtiives [16:01:40.0318] which is bad and dumb [16:01:42.0966] have a parallel Map for that? [16:01:48.0725] then you leak [16:01:50.0656] which is bad and dumb [16:01:55.0282] only primitives go in the Map [16:02:03.0499] yeah that leaks [16:02:06.0068] oh [16:02:14.0443] hm [16:02:16.0370] this space is well-expored in userland [16:02:21.0929] you can't ever collect those entries because they're forgable [16:02:27.0118] then i guess we need `===` overloaded [16:02:30.0609] the links from the slides have a few different approaches [16:02:47.0472] * this space is well-explored in userland [16:03:14.0874] if you do the finalizationregistry thing, it does not leak if a composite key of only primitives become unreachable, even with a map, no? [16:04:12.0545] is the implementor worry that it will slow down *all* `===` occurances [16:04:23.0561] It has to, because the components of the composite key would always be forgeable, the composite of them is forgeable [16:04:33.0774] Yeah, I defined a bunch of collections before Map was added to the language, where you brought your own contentEquals contentCompare, which I suppose is analogous to species. [16:04:33.0791] > <@devsnek:matrix.org> is the implementor worry that it will slow down *all* `===` occurances I think that's the claim (in the past) [16:04:42.0717] * It has to leak, because the components of the composite key would always be forgeable, the composite of them is forgeable [16:04:53.0727] I guess we could in principle say that a composite key of only primitives cannot be held weakly [16:04:56.0105] what is this a response to? [16:04:56.0933] and maybe that solves the problem? [16:05:16.0829] oh right yes obviously [16:05:17.0925] that seems perfectly reasonable [16:05:26.0889] but what if it's an object ? [16:05:32.0992] (it makes an even stronger case for a built-in "isWeakable" predicate, ofc) [16:05:39.0324] I was expecting you to say "this breaks the predicate to check when I can put something in a weakmap) [16:05:44.0949] Oh there it is :) [16:05:45.0839] I do not understand the question [16:05:53.0430] * I was expecting you to say "this breaks the predicate to check when I can put something in a weakmap" [16:06:17.0153] having a non-weakable object is def weird too [16:06:46.0294] See above discussion. An object is currently expected to be usable as a weak map key [16:07:08.0410] > <@ljharb:matrix.org> having a non-weakable object is def weird too no weirder than registered symbols [16:07:51.0311] they're both differently weird. which is weirder in aggregate [16:08:19.0633] (this would also require the thing from the previous presentation where non-extensible objects could not get stamped with private fields, incidentally) [16:09:45.0628] ooooo composite keys would obviate `Array.prototype.uniqBy` 😮 [16:09:58.0208] god I need this [16:10:17.0665] ... would they? [16:10:22.0283] I feel like they'd make it better tbh [16:11:24.0322] well that was entirely coincidental [16:11:49.0304] whats the 4th form of equality? [16:12:06.0118] `===`, `==`, `Object.is`, `SameValueZero` [16:12:16.0198] ohh SameValueZero [16:12:18.0691] I was imagining that this would replace SameValueZero [16:12:35.0573] Also in `[].includes`? [16:12:54.0126] I mean, yeah, if we're modifying existing APIs [16:14:44.0056] shu: is it still held that `===` for r&t is too expensive? [16:14:52.0391] yes [16:15:04.0695] 😔 [16:15:51.0545] also reminder of the old https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey [16:16:24.0628] these were `===` via interning (and requiring at least one weak component) instead of modifying collections [16:16:28.0430] but same goal [16:21:40.0197] also, phrasing these as "composite keys" makes it clear that you shouldn't be using these all over the place [16:21:55.0927] e.g. a new Object.entries-like API would not return these [16:23:19.0444] if they are actually composite keys and composite keys only, is the recursive part of it needed? [16:24:51.0576] I would want it to, so I wouldn't have to manually flatten the results of my `.toKey` methods everywhere [16:26:02.0651] fair enough [16:26:39.0658] (and it's not like it's any slower to do it recursively vs me manually flattening. faster, probably, since you can have a fast path if I was using actually the same object) [16:26:51.0257] * (and it's not like it's any slower to do it recursively vs me manually flattening. faster, probably, since you can have a fast path if I was using actually the same inner object) [16:28:40.0363] libraries are allowed to have expectations and we're definitely allowed to break those expectations [16:28:47.0382] we added new `typeof`s! [16:30:54.0047] that was *not good* for some minifiers [16:31:10.0008] but that was ok [16:31:33.0924] only because I fixed them promptly [16:32:12.0000] I expect this would be less brutal than new typeof [16:32:13.0791] p sure the forever goodness of new primitives outweighs one person's minifier fixing effort tho [16:33:06.0458] Ashley Claymore: is there a repo for your r&t work? Is it just https://github.com/tc39/proposal-record-tuple? [16:33:08.0003] so, would composite keys this new vision of records normalize `-0` to `0` when using them in a map? [16:33:13.0462] presumably yes? [16:33:15.0122] could we have more help from notetakers? [16:33:21.0765] I can help [16:33:26.0321] kind of annoying; that could be expensive. but I guess just don't have `-0` [16:34:02.0103] why would it? it'd just normalize during calculation of the hashcode itself, and then do comparison SameValueZero-wise [16:34:04.0374] do we need a PoO? [16:34:14.0577] no [16:34:41.0710] oh, yeah... because that's what maps do with scalars... [16:35:09.0649] maybe we should just skip it here, though, since it'd be weird if the identity didn't actually match the first one that put it in [16:35:40.0239] Iiiiiiiii guess that would be ok? [16:35:58.0710] but in that case it would be better if we didn't normalize `-0` [16:36:02.0313] too late for that though [16:36:21.0159] PSA: The notes today are missing lots of summaries and conclusions. Please, speakers, make sure you record those while they're still fresh in your head. Take 5 minutes to save Samina & me thirty. [16:36:47.0511] I was exploring a slightly different design here: https://github.com/acutmore/proposal-keyby what I presented today needs a home (maybe the existing R&T repo?) [16:50:27.0278] Is this James Snell speaking? [16:50:42.0231] yes [16:53:08.0096] is implementation slowness the only thing holding back r&t `===` (and other operator overloads like decimal addition?) [16:53:47.0446] the feedback also included the risk of changing existing JIT code [16:54:08.0065] i.e. the one line spec change does not map to a one line c++ change [16:54:18.0276] usual complexity concerns if it incentivizes ever-more-complex interning schemes [16:54:29.0870] harder and harder to tune [21:04:58.0575] (please nobody be concerned that the notes doc is no longer accessible; turns out hackmds are all fully indexed by google) [23:44:05.0371] I trust that the notes doc will be made accessible again at some point? [00:08:56.0500] Hi, thank you for everyone's feedback, this is the problem-statement document of the proposal Number.isSafeNumeric. If there are any questions or suggestions, feel free to comment in the Github Issue. Link: https://github.com/Lxxyx/proposal-number-is-safe-numeric/issues/4 Chris de Almeida [05:48:25.0997] what is the concrete implementation of `MV(str) is MV(F(MV(str)))`? Do you just have to check every possible "worthy"(?) serialization (e.g. scientific notation, `0.N` vs `.N`, etc...) of the floating point value? [05:52:06.0489] * what is the concrete implementation of `MV(str) is MV(F(MV(str)))`? Do you just have to check every possible "worthy"(?) serialization (e.g. unnormalized scientific notation, `0.N` vs `.N`, etc...) of the floating point value? [06:14:08.0606] 1. MV(str) means mathematical value (aka the real number value) of the str, there is no specific implementation yet, just a conceptual statement, proving that the real number may change during string-number conversion. 2. When a string is converted to a number, the Runtime can obtain the exact number value, and perhaps a comparison could be made at this point (this is my speculation and has not been verified). If there are better solutions, please let me know. [06:16:45.0852] yeah I mean my point is that computers can't literally do MV(str) is MV(other str). (otherwise doubles wouldn't exist and we could all go home lol), so I imagine the only reasonable implementation to be a routine that switches through comparing different serializations depending on the format of the input. [06:17:25.0361] * yeah I mean my point is that computers can't literally do MV(str) is MV(other str) (otherwise floats wouldn't exist and we could all go home lol), so I imagine the only reasonable implementation to be a routine that switches through comparing different serializations depending on the format of the input. [06:18:41.0041] Thank you for the reply, yes, so this is pseudocode, not an actual implementation (just a convenient way to understand the problem, sorry for the confusion, I might need to make a special note about this formula) [06:19:44.0737] no it's fine to discuss abstractly, I'm just asking the room how they would approach concrete implementation [06:23:21.0293] * yeah I mean my point is that computers can't literally do MV(a) is MV(b) (otherwise floats wouldn't exist and we could all go home lol), so I imagine the only reasonable implementation to be a routine that switches through comparing different serializations depending on the format of the input. [06:30:36.0554] I might have an internal representation of digit strings that would allow me to at least do an equality check [06:31:45.0547] so you'd first attempt to canonicalize the input I guess? [06:58:30.0491] What happened to yesterday's notes document? I get Access Denied trying to review it. [07:08:03.0284] > <@devsnek:matrix.org> so you'd first attempt to canonicalize the input I guess? yeah that would be my approach. That's essentially what the decimal proposal polyfill does when giving a string as input [07:13:06.0441] > <@waldemarh:matrix.org> What happened to yesterday's notes document? I get Access Denied trying to review it. https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$KG586ubrdr9PCC6MsiQdItP_oPRxUWtGb2X-Kl40pow?via=matrix.org&via=mozilla.org&via=igalia.com [07:42:22.0434] The top secret notes document link (and TCQ link) were leaked, presumably by being present in the hackmd schedule, which gets indexed by search engines. We will share a new notes doc link on the reflector issue for the meeting. Also perhaps a new TCQ link. [07:43:27.0999] How do search engines find the hackmd document in the first place? Was it linked somewhere? [07:45:45.0419] not sure, but one way is that the hackmd links are sometimes shared in these public matrix channels, which get logged and those pages get indexed [07:46:58.0601] the hackmd pages themselves are not really a problem to be accessible (except maybe that anyone can edit them) -- but the fact the notes doc and tcq links appeared on them is the bigger issue [09:03:21.0100] new notes doc link is up on the reflector issue: https://github.com/tc39/Reflector/issues/547 [09:16:50.0220] new TCQ link is up on the reflector issue as well [09:48:57.0504] as the prophecy foretold [10:01:10.0293] many thanks to our note-takers from yesterday! 👏👏👏👏👏👏👏 - Ben Lickly - Chengzhong Wu - Luis Fernando Pardo Sixtos - Linus Groh - Nicolò Ribaudo - Oliver Medhurst - Philip Chimento [10:01:43.0601] - Daniel Ehrenberg [10:02:25.0134] * many thanks to our note-takers from yesterday! 👏👏👏👏👏👏👏 - Ben Lickly - Chengzhong Wu - Daniel Ehrenberg - Luis Fernando Pardo Sixtos - Linus Groh - Nicolò Ribaudo - Oliver Medhurst - Philip Chimento [10:03:35.0848] ooohh I actually didn't know we had the right to a minority report [10:03:39.0657] I appreciate that [10:06:45.0888] 📣📣📣 **The new TCQ link is in the Reflector** [10:09:18.0321] I don't think single blocker is the issue, the issue is "unequal authority". [10:10:44.0391] Is there any example of minority report in our history?? [10:11:47.0185] @haxjs:matrix.org I don't think it was common knowledge that we had that ability [10:11:52.0616] so I'm not aware of any [10:15:28.0455] 📣 don't forget to request more breakout session topics for this afternoon! https://github.com/tc39/Reflector/issues/552 [10:22:31.0187] I like the canPlayAudio API! [10:22:39.0465] I believe it's empty string actually [10:22:46.0658] which is close-enough to false [10:23:21.0166] ah thanks, it was off the top of my head [10:23:28.0816] an equally non-committal kind of false [10:32:33.0034] ok but SABs are actually good [10:32:42.0541] people should pick examples which are unambiguously bad if they want to make this point [10:32:46.0643] if we had blocked SharedArrayBuffer in TC39, it wouldn't've blocked it from shipping, just reduced TC39's scope as it was standardized somewhere else [10:33:16.0057] right, invoking Crockford and ES4 is also fraught here... [10:33:36.0968] the counterfactuals that mark invokes would not be a better outcome [10:33:46.0237] * the counterfactuals that mark invoke would not be a better outcome [10:34:42.0326] we simply don't have agreed upon goals for the language [10:35:06.0645] a veto in TC39 does not change those goals, and they will be realized in another way [10:35:10.0192] my understanding is, historically, Mark, Waldemar, Crockford, Dave Herman and Allen W-B innovated/invented the block during the ES4 process; it is not a historical constant in this committee [10:35:30.0103] however, sometimes that realization is not "good faith" participation. [10:35:32.0735] sometimes, but yeah [10:35:37.0647] definitely in the SAB case [10:35:55.0377] if base64 had taken a single additional meeting I was going to do it in whatwg [10:36:00.0207] I was very close already [10:36:00.0474] iow sometimes if an entity hacks around an objection in TC39, it's not actually a good faith action. [10:36:04.0551] is your end goal to make sure everyone participates in tc39 in good faith? [10:36:14.0372] or is your goal to evolve the language? [10:36:14.0466] hopefully we're already there. [10:36:28.0435] the whole enterprise of standardization at all is a means to an end [10:36:30.0296] "evolve the language" implies good change. all change is not good change. [10:36:32.0621] it is not the end [10:36:42.0033] I don't think "good faith" is a very useful lens. The committee has already advanced a lot in that we're not constantly referring to "good faith", which I think is a sign of... good faith [10:37:34.0884] But I agree with Mark that _generally_, the dissent isn't to solving the problem overall [10:37:36.0108] > <@littledan:matrix.org> I don't think "good faith" is a very useful lens. The committee has already advanced a lot in that we're not constantly referring to "good faith", which I think is a sign of... good faith yes, this used to come up much more often [10:37:49.0643] one person's hacking around an objection in one standards body is another person's making progress in a less sclerotic organization [10:38:02.0759] i don't think good or bad faith matters [10:38:15.0071] all progress is also not always good process. [10:38:25.0655] who's saying that? [10:38:35.0013] maybe nobody, just making sure it's explicit [10:38:54.0399] should we interrupt for the POO [10:39:02.0162] well, there are clearly hypothetical things people could do that are bad faith, like behaving anticompetitively with respect to the standard under discussion, which is prohibited by Ecma rules (as it is in all standards bodies). But I don't think that ever happens here. [10:39:16.0565] (I also agree with Michael Saboff—it _has_ happened. It's just not usual) [10:39:30.0973] agreed, good clarification. that is a much dire form of bad faith that we basically never see here [10:39:54.0793] tc39 is the only standards committee i've interacted with where it feels like non-megacorps can drive any form of change. i don't think blocks are the only component of that but i think giving large equal power is definitely an important part of it. everything will have good faith and bad faith, and all you can do is strive for processes to be as non-destructive as possible. [10:40:35.0007] Michael Saboff: if you'd like, I'm volunteering to collaborate on a concrete proposal for how the block process can be improved [10:41:21.0266] equality is an important value of TC39; I don't think Michael's proposal questions that. [10:41:32.0954] ngl i was onboard with this but this (great) view has completely changed my mind [10:41:36.0582] but it does lessen it, even if unintentionally [10:41:44.0729] * ngl i was onboard with the proposal but this (great) view has completely changed my mind [10:41:53.0018] i don't understand mark's point [10:42:11.0469] for the most part only big companies/browsers have more than 1 delegate [10:42:19.0664] mark thinks it is important that browser vendors not have more power than everyone else [10:42:20.0601] if you believe browsers have de facto veto, _no_ change to process (which is de jure) can change that [10:42:37.0288] since browser vendors necessarily have a veto, the only solution to keep parity is for everyone to have a veto [10:42:39.0450] * for the most part only big companies/browsers have more than 1 delegate so they could block themselves but smaller companies could not [10:43:00.0666] ah, but, tc39 rules do not bound anybody to ship anything [10:43:06.0157] thus the disparity between de facto and de jure [10:43:10.0466] right, exactly [10:43:24.0295] oh of course i don't think it intentionally does. i would consider it more to be an emergent check against the power of implementors technically having their own "lone veto" anyway. not that i am accusing them of taking advantage of that at all. [10:43:26.0743] but the good faith part is that if browser makers provide consensus for stage 3, then they have committed to shipping it [10:43:46.0864] if they weren't going to ship it, or decide later not to, it's incumbent to block stage 3 or propose demotion [10:43:54.0298] I think this shoulnd't be a breakout topic [10:44:14.0095] strong +1, this is a topic for the whole committee [10:44:33.0608] * but the good faith part is that if browser makers provide consensus for stage 3, then they have in fact committed to shipping it [10:44:37.0743] i can copy the queue into notes if people would like [10:44:39.0401] the current process actively is at odds with this mode IMO [10:44:41.0035] * if they weren't going to (or aren't able to commit to) ship it, or decide later not to, it's incumbent to block stage 3 or propose demotion [10:44:47.0139] i'll speak to it later on the queue if we get to it [10:45:46.0906] ah we're tabling this? [10:45:59.0702] we are continuing this afternoon [10:46:30.0805] we will have an overflow topic, at least to go through the queue [10:47:03.0775] ljharb: in short, my view is that the veto culture in TC39 in practice works out to that stage advancement can mean "can we live with this proposal", not necessarily "are we actively supporting this proposal" [10:47:24.0126] oh i agree. but "live with" imo includes "will ship" whether you support it or not [10:47:31.0088] I didn't add myself to the queue because it was clear that we weren't going to get there, but I did have a topic to add re: often there is only ~two active voices of support for a proposal so requiring (in some cases) >2 active voices to veto seems silly [10:47:37.0212] and if we can merely live with something but do not actively support something, the committment to shipping it ASAP is not there [10:48:00.0414] i guess i really don't understand why a browser wouldn't block it in that case [10:48:14.0024] the expectation is that basically everyone will ship it in stage 3 [10:48:16.0420] there are many cases where we play catch up to reduce interop risk [10:48:32.0401] i will take merely live with over active support. like, the success rate seems pretty high? [10:48:35.0166] "will ship" on whose timeline? [10:48:36.0503] ok, so you're saying where you're gambling that others will ship it first, so that you're forced to play catchup? [10:48:54.0472] no [10:48:55.0478] I wouldn't be opposed to increasing the support threshold. (But I also see the point about not making the veto threshold too high) [10:49:02.0534] i think it would be perfectly fine for a browser to say "consensus, but we won't ship first" - that way if every browser says that, we all know we have a problem [10:49:11.0144] I wanted to push back on Mark's final statement that definitively stated "the rule we have is the only one that can work." We should be open to suggestions for process improvement. And it sounds like James Snell has ideas. And there are some the chair group has considerd too. So I'd like to be open minded and not assume it's a problem we cannot solve. [10:49:26.0781] that's fair, if you want that to be more explicit, that's a concrete change to the process we can talk about [10:49:34.0826] but priorities change, product strategies change [10:49:38.0186] oh sure [10:49:39.0896] yeah, my preferred solution would be to require significantly more active support for a proposal to advance, and then also raise the threshold for a veto. [10:49:46.0155] you want us to be locked in to some direction, you want promises. there will be no promises [10:49:48.0567] the change to require at least 2 active supporters was good [10:49:59.0714] ultimately, if all browsers don't want to ship something, we should figure out how to coordinate on what the language is and not leave things indefinitely ambiguous. It's OK if you change your mind and decide against something. [10:50:07.0139] and a change doesn't imply bad faith at all, but i think it's incumbent on a browser to notify the committee if the "will ship" status changes [10:50:12.0569] > <@shuyuguo:matrix.org> but priorities change, product strategies change "will implement" doesn't mean "will ship" [10:50:16.0955] but 2 active supporters and no active dissenters is _such_ a low bar for changes to the language, we should have a higher bar [10:50:22.0064] someone else can implement the proposal [10:50:38.0402] huh? [10:50:49.0819] The point that I wanted to make last night is that for me, stage three is not intent to ship, it is we should start implementing. This is based on other priorities. [10:50:58.0623] maybe the reverse? "will ship" doesn't imply "will implement"? [10:51:03.0411] 2 supporters from different representations? [10:51:10.0754] Has anything failed to make it from stage 3 to 4 due to lack of browser implementations? [10:51:16.0545] right, my position has been stage 3 is an option to ship [10:51:20.0528] Decorators [10:51:21.0373] we reserve the right but are not obligated [10:51:32.0285] well, https://github.com/tc39/proposal-regexp-legacy-features is 8 years old [10:51:36.0651] I don't know about "failed" [10:51:41.0287] we can't obligate anyone. but the *intention* should be to ship imo [10:51:44.0194] because at any time people could implement it [10:51:50.0482] > <@shuyuguo:matrix.org> huh? In decorators, V8 is blocking the proposal even though there's a complete implementation. Committing to ship isn't committing to implementing, and in the presence of implementers external to the company whose browser is the product, committing to ship is the thing that matters more. [10:52:18.0478] V8's position is we don't want to be the first to ship [10:52:26.0464] strictly speaking I don't think we said they had to be from different organizations but I don't think the question has actually arisen [10:52:33.0251] i take issue with that characterization [10:52:38.0440] that is fine but i think this is the first time that's been stated, and it's been stage 3 for a long time [10:53:02.0295] I mean, it's every browser's position. None of the browser is individually responsible, but it means that the proposal will not go to stage 4 unless somebody changes their mind [10:53:04.0979] > <@rekmarks:matrix.org> Has anything failed to make it from stage 3 to 4 due to lack of browser implementations? in addition to Decorators, we've had a Stage 3 withdrawal [10:53:07.0536] that's fine, but a major function of the standards committee is to coordinate expectations and plans; we can't force anyone to do anything, but I hope we can eventually understand each others' plans so we can help others in the JS ecosystem. [10:53:15.0008] namely SIMD [10:53:51.0743] technically stage 4 doesn't require browser implementations [10:54:13.0701] what stage 4 requires is intentionally vague because nobody agrees on it, happy to provide more context later [10:54:15.0880] my question is then why can no individual browser be convinced to be the first to ship? [10:54:24.0688] we have different leadership, different priorities too [10:54:27.0889] the actual concern is not the nominal stage, it's whether it goes in browsers [10:54:35.0394] Also polymorphic covers `new Amount.from({value: "1/2", unit: "cup", precision: "1/16"})` [10:54:36.0270] something actually being stage 4 is pretty irrelevant [10:54:51.0786] that's fine, so, eventually we should be able to digest all of that and figure out, OK so should we cancel the proposal [10:54:55.0150] > <@littledan:matrix.org> namely SIMD I was thinking about Object.observe, but also taht [10:55:01.0393] * I was thinking about Object.observe, but also that [10:55:08.0816] that was stage 2 [10:55:11.0994] Stage 4 implies (requires?) browser implementations, though? [10:55:21.0654] yeah this was a prominent block of Stage 3, by Yehuda [10:55:24.0490] the exact text is "implementations" not "browsers" [10:55:26.0687] (and it was the right call!) [10:55:40.0901] > <@shuyuguo:matrix.org> we have different leadership, different priorities too in a situation where we have a fairly complete implementation, how much is priorization the thing that matters when deciding not to ship? [10:55:48.0175] But doesn't that always mean browsers in practice? [10:55:51.0415] its purposely vague, and in practice if the 3 largest js implementations don't ship something its problematic to call it "standardized" [10:55:58.0058] i'm not sure i understand the question [10:56:05.0475] > <@rekmarks:matrix.org> Stage 4 implies (requires?) browser implementations, though? https://tc39.es/process-document/ [10:56:06.0489] per process doc "Two compatible implementations which pass the Test262 acceptance tests... Significant in-the-field experience with shipping implementations, such as that provided by two independent VMs" [10:56:09.0478] only two are required [10:56:10.0482] having an implementation is a very small part of the decision to ship something [10:56:13.0392] but in practice browsers yes [10:56:29.0350] nobody will make something stage 4 if it has zero browser implementations, no matter what the process doc says [10:56:48.0465] we have always required at least one browser but IIRC we've allowed some trivial things to go forward with only one browser actually finished implementing, if there was an implementation in babel or something [10:57:12.0676] Seems sensible 👍️ [10:57:18.0207] for anything nontrivial we're going to need two browsers though yes [10:58:01.0377] these are not my words, but reflects on browser dynamics in W3C and WHATWG: https://ln.hixie.ch/?start=1721260117&count=1 [10:58:33.0713] huh, I didn't realize hixie was still writing on web stuff [10:58:44.0985] the footnote made it seem like he was goaded into it :) [10:59:22.0663] @jesse:igalia.com Decimal as presented is normalised? [10:59:30.0106] > The users chose browsers i'm not sure that's really true anymore tho :-/ [10:59:33.0430] Yes [11:02:18.0480] it is definitely true that a user of Firefox will choose to use Chrome or Safari if web pages don't work in Firefox [11:02:30.0108] not clear that there are choices beyond that [11:02:35.0774] (which is very sad) [11:03:02.0984] right [11:03:24.0097] whatwg/ietf (for example) continue to exist because they are effectively just implementors and no one else. tc39 continues to exist because it only attempts to steer implementations, it doesn't throw random stuff in and just expect it to then be implemented. anything further than tc39 doesn't exist anymore because its irrelevant to our shared reality. finding a good place within this spectrum is difficult, and i think some perhaps underdiscussed component of these arguments is where people think tc39 should land on this. [11:03:47.0938] I'm not sure if that describes IETF... [11:04:50.0465] IETF WGs vary rather widely to make that sort of a generalization [11:05:22.0901] This basically describes the power dynamics that exist between standards and implementors in cryptocurrency / blockchain as well (opportunity to coin the name of a Law here, folks) [11:05:30.0412] do we have a link to the slides for this presentation? [11:05:53.0827] https://docs.google.com/presentation/d/1050DHlNOzcN-8LqJQ_6z8j-LryXgEqOcLfcVzkhJyEk/edit#slide=id.p, from the agenda [11:06:38.0934] It's past tense 😉 [11:07:50.0462] Perhaps it would be “Hixie’s Law”, but I suspect that Hixie has made many other statements that one could enshrine as “laws”. Or maybe Hixie would say someone else came up with it first and told him. [11:08:58.0978] Rarely do the coiners get to choose the law they lend their name to [11:09:07.0716] * Rarely do the coiners get to choose the law they lend their names to [11:09:46.0297] That smells like a new law to me… [11:11:02.0584] Stigler's Law of Eponymy, arguably [11:11:20.0920] /me retires from note editing, could another person please aid [11:13:11.0170] > Stigler attributed the discovery of Stigler's law to sociologist Robert K. Merton, from whom Stigler stole credit so that it would be an example of the law. The same observation had previously also been made by many others. Oh, thank goodness, I was hoping that it would be autological. [11:13:31.0811] Fyi, there is a proposed breakout session for Decimal/Measure/Amount [11:13:44.0556] Still need another notetaker [11:13:51.0191] i think [11:14:04.0125] will pause for volunteers after this topic [11:14:11.0474] I’ll do it, I’ll get in a minute. [11:15:38.0276] littledan: Regarding champion groups, I agree, but in this case the sole champion is not available. [11:15:59.0590] Agree, I think it's good going through the committee this time [11:17:35.0463] Could someone link the file with the speaker abbreviations? [11:17:37.0218] sure, fine to discuss in committee if people want. I can see how in some cases it might be ambiguous whether a coworker in the same company is an appropriate choice. [11:17:50.0383] https://github.com/tc39/notes/blob/main/delegates.txt [11:17:50.0637] https://github.com/tc39/notes/blob/main/delegates.txt [11:19:34.0343] Does anyone have slides for this new presentation? [11:19:38.0294] re: current topic, is the string "1234.5678000000000338332029059529304504394531251" supposed to be allowed? [11:19:43.0015] I'm assuming they're not on the agenda. [11:19:43.0123] i have a hard time finding "most people are not aware of ieee754" compelling. it permeates to too much of the language beyond just storing values [11:19:44.0206] * re: current topic, is the string "1234.567800000000033833202905952930450439453125" supposed to be allowed? [11:19:57.0261] they're on the hackmd (via the reflector) [11:20:10.0057] it's the previous one [11:20:17.0376] not the one is presenting? [11:20:42.0552] if it's just about u64, it should be parsed by `BigInt()`, not `Number()` [11:20:49.0920] oh [11:21:14.0695] > <@bakkot:matrix.org> re: current topic, is the string "1234.567800000000033833202905952930450439453125" supposed to be allowed? it *has* to be, right? [11:21:25.0086] ("1234.567800000000033833202905952930450439453125" is notable because it is the exact decimal representation of the float denominated by 1234.5678 in JS) [11:21:31.0410] well, as currently written it would not be [11:21:46.0856] don't pay attention to what is written, try to understand what they're going for [11:22:01.0209] this spreadsheet use case is very weird to me [11:22:02.0874] what is written has been wrong a dozen times in the last week [11:22:06.0586] I am unclear on what they're going for [11:22:06.0992] yes I think so? [11:22:31.0986] if your _initial_ input happens to be representable "exactly" as float64, then you opt into ieee754 _arithmetic_ on the sheet? [11:22:42.0496] if your initial input isn't, then you opt into big decimal arithmetic? [11:22:53.0413] "1234.567800000000033833202905952930450439453125" does arguably lose precision, in the sense that when you display the corresponding number to users it is going to be different than the input [11:22:55.0147] yeah that's weird [11:23:03.0451] Last I checked, Uber’s JS API gateway is in this same exact world of pain. [11:23:15.0926] so if this is about losing precision _when displaying values_ not just when parsing them, that string should be rejected [11:23:37.0765] so i woke up at 3am and spent like two hours interrogating the examples and motivation and came to the conclusion that they want "MV(str) is MV(F(str))" (assuming that MV(str) is defined to exist). [11:24:26.0591] secondarily, i find the motivation... not motivating enough [11:24:38.0698] I expect a solution to this problem to look more like “can this string be captured in a bigint” (rejecting strings with decimals) and “can this tring be captured in a float64” (rejecting apparent integers with more digits than fit in a mantissa) [11:24:51.0181] > <@devsnek:matrix.org> so i woke up at 3am and spent like two hours interrogating the examples and motivation and came to the conclusion that they want "MV(str) is MV(F(str))" (assuming that MV(str) is defined to exist). not entirely tru if Kevin is correct above [11:25:11.0164] Or maybe even specifically “can this string be captured in an int64” because that’s what’s going to be important to Java, Go, &c [11:25:17.0595] isn't that what they said in the last presentation [11:25:28.0106] > <@bakkot:matrix.org> isn't that what they said in the last presentation no, read carefully [11:25:29.0049] and does that mean "1234.567800000000033833202905952930450439453125" is rejected? [11:25:59.0647] well, I guess last presentation also included Number.MAX_SAFE_INTEGER [11:26:01.0463] but other than that [11:26:40.0420] i believe that to be equiv [11:26:57.0949] * i believe that to be equiv (but more confusing cuz of the extra tostring decimal representation in the middle) [11:27:07.0943] can one currently implement `MV()` in JS in a practical sense? [11:27:09.0525] actually, wait, snek did you meant to write `MV(F(str))` or `MV(ToString(F(str))` [11:27:11.0817] I don't think so, because of the way we tostring [11:27:12.0533] on the RHS [11:27:57.0755] those are equiv if `Number(ToString(n)) is n` holds, no? [11:28:01.0318] ok so does this mean that the use case would be solved with _either_ "give me the MV string of this string" _or_ with a function that implements the screenshotted comparison? [11:28:28.0978] "give me the mv string of this string" is not... a thing [11:28:34.0489] > <@devsnek:matrix.org> those are equiv if `Number(ToString(n)) is n` holds, no? no [11:28:40.0455] The slide link on the HackMD page’s Day 3 section seem to be to the old slides, unless I’m missing something. [11:29:03.0765] right, i'm asking if, should we provide such an API, would that suffice (not that i'm proposing that) [11:29:09.0118] ryzokuken: Advance the queue [11:29:15.0010] no i mean we can't provide such an api [11:29:23.0911] mv isn't a concrete thing, its the abstract idea of numbers [11:29:29.0228] chairs, please advance the queue [11:30:54.0429] I think we're getting at the key part here: this proposal is *both* about representing a float and presenting a float to the user [11:31:11.0033] we can absolutely provide it if we want to [11:31:25.0539] i assumed we could just provide a string representing it [11:31:35.0253] you mean just as the substring of the source code for that value? [11:31:39.0858] My suggestion for the exact condition to determine if a number is safe: https://github.com/Lxxyx/proposal-number-is-safe-numeric/issues/3 [11:31:42.0471] and then you can literally type `MV(str) === MV(String(+str))` in your code [11:32:08.0023] oh I meant we could provide "give me the string which is the exact decimal representation of this double" [11:32:23.0673] oh, i don't think that's what ljharb means [11:32:25.0261] or if we had decimal we could have it give you the decimal [11:32:40.0193] every double has a (very) finite decimal representation so it's feasible [11:33:25.0474] We have that, right? `.toFixed(n)` with the highest n that doesn't throw (34?) [11:34:32.0665] exact decimal representations don't have trailing zeros but you could trim those off I guess [11:34:38.0834] also you need more than 34 [11:34:53.0776] I think it's bounded at 100 [11:35:18.0215] maybe better would be toPrecision(34) [11:35:23.0972] you might need 1076 [11:35:26.0334] so [11:35:31.0421] bounded at 100 is not going to do it [11:35:43.0693] (ES2018 bumped it up to 100) [11:35:50.0477] * (ES2018 bumped it up to 100, iirc) [11:35:58.0298] ``` > 1234.5678.toFixed(101) Uncaught RangeError: toFixed() digits argument must be between 0 and 100 at Number.toFixed () ``` [11:36:13.0460] i'm fine with raising the limits of toFixed to any arbitrary amount. i find this proposal unconvincing though. [11:36:16.0685] looks like an implementation restriction [11:36:20.0820] (2.22507385850720187716e-308 is the smallest double and its representation has 1074 digits after the `0.`) [11:36:36.0321] But that's not a solution to this proposal, that check would return false for `0.1` [11:36:36.0927] * (2.22507385850720187716e-308 is the smallest normal double and its representation has 1074 digits after the `0.`) [11:36:46.0752] yes that's why i mentioned it separately [11:39:41.0106] we don't need a proposal to see if a string remains unchanged after round-tripping through floats, you can just do `String(+s) === s` [11:40:01.0897] That doesn't work with notations like `.1` and `1e4` [11:40:21.0541] `String(parseFloat(s)) === s` [11:40:23.0496] it also doesn't work for `0,1`, which this proposal doesn't solve [11:40:45.0603] you don't want "string remains unchanged", you want "MV of the string remains unchanged" [11:40:49.0639] which is harder! [11:40:51.0536] `String(parseFloat("1e1") === "10"` [11:40:53.0930] yeah i'm also not convinced the serialization use case can't be done with existing APIs [11:41:08.0333] > <@bakkot:matrix.org> you don't want "string remains unchanged", you want "MV of the string remains unchanged" not for Kris's serialisation use case as I understand it [11:42:17.0592] > <@nicolo-ribaudo:matrix.org> `String(parseFloat("1e1") === "10"` that's expected, right? [11:42:28.0490] I guess I did not understand that use case [11:42:37.0079] I would expect the solution to this proposal to return there in that case [11:42:41.0840] * I would expect the solution to this proposal to return true in that case [11:46:15.0805] also I keep mentioning this but in fact the spec allows freedom in some cases for what the ToString of a number even is, so this would not be the same on all platforms [11:46:20.0452] man, the word "represent" is really causing us some problems this meeting [11:46:27.0508] we keep using it in different ways [11:46:40.0281] "represent" often means "stands in for" (even if different) [11:46:50.0417] people keep using it to mean "is 1-1 with" [11:46:53.0524] we should stop having decimal be the default serialization of numbers in js [11:46:57.0406] "exact representation" [11:46:59.0413] just show the 64 bits [11:47:46.0172] > <@devsnek:matrix.org> just show the 64 bits better yet, show the range of exact decimal values [11:47:51.0675] we should always have had the default serialization be the full exact value [11:47:57.0878] y'all making me cry [11:48:07.0655] that would also solve the `0.1 + 0.2` problem [11:48:08.0269] I agree with shu that using isSafeNumeric to decide whether it’s safe to capture a stringy number in either a number or decimal is unsound. [11:48:18.0271] because you'd write `0.1` in the console and it would print as something else [11:48:31.0198] as an f64, can you not use Float64Array to do that? [11:48:40.0555] you can use a Float64 array to read the bits, yes [11:48:50.0679] %a baby [11:48:52.0230] you can't use it to read the exact decimal representation [11:48:53.0874] that's harder [11:48:58.0566] no i mean, put the number in, pull it out, and compare the result? [11:49:05.0349] nnnnno [11:49:07.0537] but it's not pretty enough! [11:49:08.0079] oh but you mean producing an f64 string is harder, gotcha [11:49:14.0518] putting a number into a Float64Array doesn't do... anything [11:49:19.0958] would be funny to have some kind of range semantics: you typed "x", but the best I can do is *this range of things here, pick one* [11:49:36.0420] oh [11:49:46.0157] The alternate problem statement I proposed is much more consistent an int32 to Number parser that rejects integers in the int64 upper range, or an float64 to Number parser that rejects strings that express numbers that can only be faithfully captured in decimal [11:49:47.0639] it's already a Float64 [11:50:10.0236] kriskowal: can you state your problem statement again? [11:50:11.0714] right [11:50:16.0745] i say this without judgment: i think nicolo's idea to get people to understand IEEE754 is the most actionable next step. i get the feeling people are ascribing utility to the proposal based on misunderstanding of how floats work [11:50:32.0455] utility at best, soundness at worst [11:50:41.0559] http://www.2ality.com/2012/04/number-encoding.html is a great read on the topic, i believe [11:50:58.0529] I see that the person who I would like to volunteer reacted with 👍️! [11:51:35.0112] that is a good article but does not sufficiently emphasize that the actual value represented by the JS number `0.1` is in fact a different mathematical number [11:51:46.0156] Maybe I'll give the presentation if nobody else wants to, but not at the next meeting [11:52:01.0239] and that float represents many different mathematical numbers [11:52:07.0903] * and that JS number represents many different mathematical numbers [11:52:35.0677] i just want a presentation full of words like "recurring decimal in base 2" [11:53:04.0854] this is somewhat good but still misses out on some of the big aha moments i think https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html [11:53:09.0847] For purposes of interoperating with other languages that are obliged to represent their native int64 and decimal types as strings for transmission through JSON, JavaScript would benefit from methods for parsing int32 to number and parsing float64 to number, rejecting strings that are out of the range that can be safely captured by those types. [11:53:28.0186] process point: if multiple people have expressed that they are uncomfortable with stage advancement, I would like chairs to not ask for stage advancement or ask if anyone is "withholding consensus" [11:53:35.0214] if multiple people have expressed that they are uncomfortable with stage advancement it is clear we do not have consensus [11:53:36.0963] > <@nicolo-ribaudo:matrix.org> I see that the person who I would like to volunteer reacted with 👍️! furiously trying to recall whether I reacted with :+1: before this [11:53:43.0131] making people actually say "I personally am stopping this" is bad [11:53:45.0326] * furiously trying to recall whether I reacted with 👍️ before this [11:54:56.0132] what does "out of the range that can be safely captured by those types" mean [11:55:01.0249] does that include `"0.1"` or not [11:55:15.0482] even this seems ill-defined... would such a function accept or reject `0.3`? What about `0.30000000000000004`? [11:55:38.0044] * even this seems ill-defined... would such a function accept or reject `"0.3"`? What about `"0.30000000000000004"`? [11:56:54.0558] I reject the problem of discriminating a safe subset of decimal or int64 for representation in float64. If the sender is using a string, a JavaScript program that manipulates it needs to use the corresponding native representation, albeit bigint for int64. I accept that a function for serializing bigint to stringy representations of int64 is useful if it handles overflow either with throw or wrap. [11:57:38.0012] what's interesting about this is that there's such a concrete developer pain here but so hard to pin down what the problem is [11:57:39.0866] And I also reject that it’s okay to capture decimal in a number for purposes of presenting the same precision to the user. For that, the original string should always suffice. [11:58:40.0489] Please nominate breakout session topics at https://github.com/tc39/Reflector/issues/552 [11:58:42.0575] my reluctance is that developer pain feels awfully close to the blanket "ieee754 is counterintuitive and a pain", which isn't a problem we can solve with a helper function [11:59:06.0899] I agree, the problem of truncating int64 is much more interesting than mishandling string representations of decimal. Whether another language is providing a decimal or float64 is very clearly discriminated by whether it’s captured in a JSON string or number [12:01:41.0406] That is, if you receive an integer as a string, the sender either represented that as int64 or decimal. The API proxy should be in a position to know which is which and parse it accordingly. [12:02:36.0433] Yeah, I am resigned that even my generous interpretation suggests an underlying misunderstanding of the architecture problem. [12:03:07.0238] Which is definitely common, but can’t be solved with more methods. [12:05:35.0907] And I’m almost absolutely certain that every company using JavaScript as an API proxy for terminating HTTP JSON and forwarding or fanning out to Java and Go is also truncating enums that weren’t in the IDL whenever the API proxy was last deployed. [12:09:19.0701] at what time is the meeting resuming? [12:14:24.0346] Presumably top of the hour [12:14:49.0980] Thank you all for the feedback on Number.isSafeNumeric, this has been a rare experience and journey for me, I will continue to improve the proposal, thank you all for your guidance 😆 [12:24:02.0165] Know that Alibaba is not alone. JavaScript’s mismatched number type tower with most languages is a headache felt everywhere. [12:25:59.0114] appreciate this feedback. we need to be clear though. it is common that people express reservations or dissent but do not intend to outright block advancement. we also saw that some folks had modified their stances. it is also common when someone is blocking to ask them to clearly state their reasons FTR. someone may say they are, e.g. "unconvinced" and sometimes this implies a block, and sometimes it does not. we need to err on the side of being clear and unambiguous [12:28:41.0492] Yes, I have to deal with similar issues every day, which gives me a headache. Thank you for your feedback, it made me realize that I need to improve my perspective on the problem. Perhaps looking at the issue from the perspective of the entire JavaScript system would be a more suitable problem-statement. [12:29:28.0623] however, it's also better to err on the side of non-advancement - an easily fixable problem if there's consensus for it - rather than advancement, which is much harder to "fix" if there's not. [12:31:15.0160] sure. in that case, you are referring to committee decision, correct? (in any case, the stakes are much lower at stage 1, but I don't disagree) [12:43:29.0243] 📣 ~15 mins left to suggest breakout sessions https://github.com/tc39/Reflector/issues/552 [13:00:55.0316] I don't think we ought to think of this in terms of "is there a block or not": that equates "consensus" with "no explicit blocking". I disagree with that. We say that "explicit blocking" implies "not consensus" but I don't think that this means "no explicit blocking" implies "consensus". And I think if at least two people have publicly stated they are not convinced (and there is not a huge upswell of support from everyone else), then this is clearly not consensus. [13:01:48.0367] Specifically, it can be the case that there is clearly not consensus _even if no one has explicitly stated that they are blocking_. [13:01:57.0453] And I don't think we ought to ask people if they are "blocking" in that case. [13:02:36.0966] A delegate can insist, of course, but it should not be the default. [13:02:50.0301] * A delegate can insist, but it should not be the default. [13:03:04.0653] there were several people who supported advancement, and there were some folks who changed from negative to positive positions. in the end, the chairs are not comfortable making the decision for the committee, and we were not clear on what the result was [13:05:20.0496] That's fair, but even in such cases I would like to phrase this as asking the committee whether we have consensus, rather than asking specific people if they're blocking. [13:06:06.0412] I personally at least am much more comfortable saying "I don't think we have consensus" (even in cases when I support a proposal!), on the basis of people's expressed discomfort, than I am saying "I am blocking" [13:06:10.0090] what do you see as the material difference between those two things? [13:06:51.0906] "whether the committee has consensus" is something one can have an opinion on without necessarily having an opinion on the whole proposal [13:06:56.0804] I hear you. but this is exactly the issue -- we sometimes get a response like "I don't think we have consensus". that is not a definite conclusion [13:06:58.0270] * "whether the committee has consensus" is something one can have an opinion on without necessarily having an opinion on the proposal itself [13:07:11.0805] It is a definite conclusion unless someone disagrees with it [13:07:40.0828] so then we are getting a meta-consensus on whether we agree that we don't have consensus? [13:08:41.0623] if it comes to that, sure [13:09:16.0505] I don't think it is usually going to be the case that there is wide disagreement about whether we have consensus unless there was only one person who objected to something [13:09:53.0235] or if someone says "I think we have consensus" and other people say "no, actually I didn't like that and didn't speak up" or something [13:09:56.0418] which can happen! [13:10:15.0173] but that's a discovery of new information rather than a disagreement _per se_ [13:10:26.0857] how do the "syntax bar is very high" folks feel about this possible statement on syntax [13:10:51.0571] well [13:11:03.0247] I would drop the "where desugarging is not possible" part [13:33:23.0993] what's the value of actually getting "consensus" here instead of just understanding this point? [13:34:05.0898] we're not binding ourselves to anything in particular, these are just suggestions about what we "should" think about [13:34:36.0733] I guess @nicolo-ribaudo:matrix.org's topic may cover this [13:35:14.0741] For `using`, the request is that the desugaring is simpler for engines. But it sounded like shu said that if the desugaring is simple then that's a motivation to not implementing it at all? [13:35:24.0431] correct [13:35:50.0397] I interpret this to mean syntax should be neither simple or complex to transform [13:35:54.0847] incidentally the using issue is https://github.com/tc39/proposal-explicit-resource-management/issues/215 [13:36:06.0137] it is _technically_ pure sugar but it's really annoying in this one edge case [13:36:11.0405] * incidentally the `using` issue is https://github.com/tc39/proposal-explicit-resource-management/issues/215 [13:36:52.0853] so, maybe littledan's proposal should be understood to mean we eliminate this sharp not-quite-sugar edge that provides little corresponding benefit [13:37:06.0342] (or would do so were the proposal coming through the process now) [13:37:28.0312] i interpret it to mean that if you want a pure DX syntax that's a nice, easy, local transform, that sounds good, i see no reason for engine support there to get most of the benefit of such a proposal [13:37:38.0761] Would this mean consider transpiler "implementer feedback" as first class as browser implementer feedback during stage 3? [13:37:41.0388] but i'd support such a feature to be blessed as standard [13:37:43.0138] can somebody screenshare the captured queue? [13:37:56.0808] @robpalme:matrix.org ^? [13:38:17.0464] yes though also browsers are often basically transpilers for sugar, so there's not that much difference [13:39:32.0867] returning to overflow items is giving me whiplash [13:39:40.0955] people need to set better timeboxes [13:39:50.0773] that makes sense. I personally marry this with improved dev-tooling where the tooling transform can be made more transparent to the developer. [13:43:42.0615] "2 must support", when did we make that a requirement? i don't see it in the process doc [13:43:57.0700] i know it's ideal but it seems like it quietly evolved in people's minds to be a requirement over time [13:44:16.0586] we did make it explicit at some point [13:44:19.0135] I remeber having an explicit process discussion about it ~2 years ago [13:44:19.0436] should have written it down [13:44:27.0109] I recall this [13:44:46.0981] I don't recall where it got documented [13:44:50.0542] (or if) [13:44:52.0140] a notes link would be good, and someone should make a PR to the process doc then [13:45:02.0906] because i recall it coming up but my feeling is that it was never made a requirement, just a guideline/ideal [13:45:38.0833] I did write it down somewhere, let me find it... [13:45:38.0980] here we go https://github.com/tc39/notes/blob/main/meetings/2023-01/jan-30.md#a-procedure-for-multiple-active-supporters-in-committee-to-achieve-consensus [13:45:51.0800] it's still in PR, linked from that notes section [13:46:12.0316] https://github.com/tc39/notes/blob/main/meetings/2023-01/jan-30.md#conclusionresolution is the conclusion [13:46:26.0565] ah sorry about that... https://github.com/tc39/how-we-work/pull/122 [13:46:34.0431] does anyone want to pick this up? [13:46:58.0741] I nominated JHD [13:47:12.0992] * I nominate JHD [13:47:14.0758] ahhh voluntold [13:48:28.0720] I did ask in that PR whether it should move into the process-document and no one answered. Any thoughts here? [13:48:52.0829] i think probably polishing the wording in how-we-work, and then separately, adding a quick sentence to the process doc that links to it? [13:49:07.0406] > <@ljharb:matrix.org> i think probably polishing the wording in how-we-work, and then separately, adding a quick sentence to the process doc that links to it? yeah that sounds right [13:49:33.0615] OK sure sounds good thanks [13:55:58.0303] last call on additional breakout session topics: https://github.com/tc39/Reflector/issues/552 [13:56:26.0934] when do we vote? [13:56:59.0240] * when do we vote on breakout sessions? [13:58:00.0972] right after this session [13:58:18.0992] actually you can already vote if you feel like it, since the last call on breakout session topics was an hour ago in principle [13:59:01.0982] the voting link is a comment in that thread [14:00:35.0280] have we ever had a single-member veto for Stage 4 advancement? [14:00:46.0883] yeah what are we solving for there [14:00:47.0902] i'm confused [14:00:54.0293] yes, on two occasions. [14:01:00.0256] oh really? [14:01:19.0398] but as i said to mark, i don't think that "3 → 4" is actually the problem michael and sympathizers are trying to solve [14:02:58.0416] i really want to hear what chip has to say [14:03:05.0037] very ominous phrasing [14:03:09.0098] > <@ljharb:matrix.org> yes, on two occasions. What were they? [14:03:14.0634] i feel like really bad moments in the process are rare enough in comparison to all the time that it works that they are a better fit for e.g. per-occurrence CoC as mentioned before, rather than full rule changes. [14:03:19.0096] * i feel like really bad moments in the current process are rare enough in comparison to all the time that it works that they are a better fit for e.g. per-occurrence CoC as mentioned before, rather than full rule changes. [14:03:22.0355] dynamic import, and private fields `in` [14:03:24.0618] yeah no we figured this out during class fields [14:03:48.0244] the former was good faith and ended up being bypassed by shipping on the web outside the committee, the latter ended up being resolved by updating the process doc. [14:03:56.0194] * the former was good faith and ended up being bypassed by shipping on the web outside the committee during the intervening years, the latter ended up being resolved by updating the process doc. [14:04:04.0090] was that the 360 thing? [14:04:07.0986] yes [14:05:27.0453] look of course nobody wants rules [14:05:43.0450] but this is the only technology we have to scale social interaction! this is like, the history of civilization! [14:07:18.0493] > <@devsnek:matrix.org> was that the 360 thing? 360 thing? [14:07:23.0981] my disagreement with mark is that mark's world is great is everyone was a mark [14:07:28.0702] which is very much not the case [14:07:38.0833] the member org was called 360 [14:07:46.0965] this is what dan is currently saying [14:07:49.0531] I agree also [14:08:21.0171] browser markers also have a de-facto anti-veto [14:08:25.0360] they can just implement things if they want to! [14:08:32.0751] cf `import()` [14:08:44.0972] Do browsers have a veto? Like, if Goggle and Mozilla were to implement something, would Apple keep refusing? [14:08:54.0032] * Do browsers have a veto? Like, if Google and Mozilla were to implement something, would Apple keep refusing? [14:08:58.0497] that'd be up to market pressures [14:08:59.0885] Tail-call optimization. [14:09:01.0625] *cough* PTC *cough* [14:09:01.0879] browsers as a category do not have a unitary veto, it is unstable for that exact reason. interop risk is real [14:09:02.0286] * Tail-call optimization, right? [14:09:19.0121] i think that speaks more to PTC the feature than the general pressure [14:09:27.0664] yeah that's a special case [14:09:31.0841] like, you know, see captureStackTrace [14:10:18.0330] oops, we really should've put msaboff's topic before mine [14:10:23.0362] I didn't realize he was leaving right now [14:12:06.0740] I am probably also going to have to leave before getting to my point, which is this: we should consider requiring a higher bar to block proposals which have a higher level of support. if only one or two people are enthusiastic a feature, then a single person who is anti-enthusiastic ought to be enough to stop it going forward. if many people are enthusiastic about a feature, possible we should require more than single person who is anti-enthusiastic to stop it going forward. [14:12:16.0541] +1 to what Erik Marks says [14:15:55.0619] if someone really wanted to they could argue all browser vendors are one financial entity [14:16:23.0497] several governments are doing that rn [14:16:36.0434] we all derive our livelihoods from web technologies existing [14:16:48.0299] that's not what i meant :P [14:16:49.0188] is this collusion? [14:17:17.0239] standardization is literally legal collusion, yes [14:17:33.0468] that's why we do it, so it's not illegal [14:17:39.0083] we = all of us, not google [14:18:04.0730] yeah, antitrust law has specific carveouts to encourage standards [14:18:19.0176] “Big Tech” as homogenous monolith. [14:18:37.0524] Much like "Government" [14:18:39.0614] it was initially unclear whether companies could even collaborate on open source, whether that would consist of an antitrust violation. We're all past that now, though [14:18:54.0518] big government want to take away your javascript!! [14:19:07.0590] “All standards must be de facto. “No, actually, de facto standards are collusion too.” [14:19:24.0370] * “All standards must be de facto. “No, actually, de facto standards are collusion too. Every company must design their own power plug.” [14:19:45.0829] yeah, standards bodies organize themselves to have uniformly open membership and such so that they don't constitute collusion [14:20:04.0076] uniformly open to those with deep pockets [14:20:14.0939] oh sorry this is not tdz [14:21:40.0043] well, Ecma, Unicode and W3C genuinely have membership open [14:22:11.0358] and we all genuinely do the technical development work through committees of membership [14:22:49.0477] * “All standards must be de facto. No, actually, de facto standards are collusion too. Every company must design their own power plug.” [14:23:28.0435] (the WHATWG antitrust legal argument is more subtle, though...) [14:25:56.0956] Reflector link for breakout sessions: https://github.com/tc39/Reflector/issues/552 [14:26:12.0373] 📣 https://github.com/tc39/Reflector/issues/552#issuecomment-2672116236 vote 🫵 [14:32:10.0376] do we still use the tcq during the breakout sessions? [14:33:13.0258] Probably depends on the size of each session. Creating TCQ meeting is open, so facilitators can do it [14:35:11.0947] I'm unclear as to which sessions are overlapping, as I'd like to participate in both the TS discussion and the pattern matching one [14:43:54.0113] Can we post the final list of breakouts somewhere for the remote attendees? [14:44:32.0028] Will there be zoom meetings for the breakouts? [14:49:13.0166] These are the ones happening [14:49:28.0982] If anyone wants to dial-in to the workgroup on Type Annotations that Mark Miller has proposed, please dial into the zoom that we used for plenary now. It will run for the next 40 mins until 15:30PT. [14:49:30.0117] 1 starting soon, and 2 later [14:49:46.0142] Facilitators will share a call link [14:49:54.0150] So annotations and pattern matching overlap? That's unfortunate. [14:50:00.0336] i have no idea what's happening for remotes [14:50:10.0514] Remotes can dial in. [14:50:14.0246] does anyone would like me to attend any of the sessions [14:50:23.0973] * does anyone want me to attend any of the sessions [14:51:46.0334] lol what is that map [14:51:49.0613] attend whichever session you're interested in. I'd be happy if you joined the JSSugar discussion [14:51:50.0731] is that a map of intenstines [14:52:00.0015] * is that a map of intestines [14:52:08.0024] That's my art [14:52:23.0398] Small JS Engines meet link https://meet.google.com/csp-utwi-cqy [14:53:43.0509] Is anyone interested in pattern matching? It's just Luca and me here; we'll close this session if no one wants to join [14:54:32.0353] I would join remotely [14:54:43.0861] OK perfect, I'll set up a zoom now [14:55:08.0324] pattern matching call: https://bloomberg.zoom.us/j/93962399209?pwd=Uwg6q9dCYMWBNRTCux51qgKgW2uah4.1 [15:09:59.0453] Is there a tcq for type stripping? [15:11:31.0246] Rob Palmer^ [15:14:18.0227] when does breakout session #1 officially end? [15:14:31.0078] 3:20 [15:14:58.0024] [Type Annotations discussion doc](https://docs.google.com/document/d/1zh4qMrO3PPWXd6ro4e2jZSSZXMrYsDx5gO2fosQax0M/edit?tab=t.0) [15:16:25.0024] ecma262 PR burn-down break-out session video call: https://f5networks.zoom.us/j/2545766102 [15:16:33.0006] starting in 9 minutes [15:23:18.0446] There will likely be pressure on the engines to do the erasing transparently like Deno supporting TS created pressure on Node.js to do something, so eventually it will happen. If the syntax allowed the parser to, after finding an opening sequence, ignore all characters until a specific character or short sequence is reached, that would make the cost of ignoring it similar to leaving whitespace in. Is that option on the table at all? [15:23:41.0449] Stdlib breakout notes: https://docs.google.com/document/d/17u9l-TRdEasF5cKHJnTmcBUNRqGQpsYxLNraV8sChfw/edit?tab=t.0 [15:25:46.0711] session two starting now [15:26:33.0430] Continuation of layering/JSSugar discussion starting now in https://bloomberg.zoom.us/j/98987937963?pwd=fSfw9H9kwiZ3269am0s5v3bT9k4TRO.1 [15:26:49.0112] shu: it'd be great if you joined [15:27:03.0860] is that happening now? [15:27:09.0359] Ashley Claymore: what is the turbofish thing? Is it documented anywhere? [15:27:09.0955] this is already different from the photo of the whiteboard [15:28:07.0218] > <@shuyuguo:matrix.org> this is already different from the photo of the whiteboard It turned out some of the intestines were vestigial [15:30:04.0323] I'll find a link. But it's: TypeScript: `new Set([])`, would be written as `new Set::([])` [15:30:20.0981] because `new Set([])` is already valid JS [15:30:30.0815] would TS add a setting to require the syntax and forbid the old? [15:30:55.0131] I can't speak for TS but I think that would add a lot of value [15:31:05.0776] if TS users were pushed into only using the erasable subset then that might actually approach the “unfork” goal [15:31:16.0475] otherwise i don’t think it achieves it [15:32:05.0535] danielrosenwasser and I were talking about transforms that VSCode (and other IDEs) could do when a file is renamed from `.js` to `.ts`. The turbofish could be one that is applied when renaming `.ts` to `.js` [15:32:36.0476] as one idea [15:32:49.0160] That should be a LSP thing, not VSCode [15:33:07.0267] unforking can’t happen without a clear/likely path to.ts and .tsx etc dying out [15:34:03.0842] And getting rid of enums [15:34:07.0672] “unfork” meaning “it all literally is the same language”? [15:34:21.0096] (while ensuring no runtime costs for engines) [15:34:27.0921] yep [15:34:38.0075] rekmarks: I think it means TypeScript is an implementation of a Type system for JavaScript and nothing else [15:34:46.0108] that TS users are only using tsc to typecheck, basically [15:35:01.0580] it could be an optional downleveler, i suppose [15:35:20.0993] presumably there’d also be an easy transform from tsdoc to this new syntax [15:35:35.0156] Getting erasure-only as a `tsc` compiler option would be an amazing start [15:35:55.0043] there’s other issues beyond that, but one of the primary goals is unforking, and i can’t see how that end state isn’t a requirement for unforking to be achieved. [15:36:20.0041] > <@ljharb:matrix.org> presumably there’d also be an easy transform from tsdoc to this new syntax This is a relatively trivial transform to write today, and would be surprised to find that one does not exist in the wild today [15:50:50.0932] Strangely the only ones I can find covert JSDoc to d.ts files and not inline [15:51:58.0656] There's been some interest from some of the NodeJS maintainers about trying to bring `enum` back to TC39, in part so that it could be used in a type-stripping only mode, just based on the sheer number of TS developers using `enum`. [15:53:02.0319] `enum` does have some advantages over `{}`, especially when working with numbers/bitflags. [15:54:33.0067] Enum with its current TS implementation is considered an anti-pattern today, not to say that a native enum implementation in ES would not be much better (since most C-like languages have them) [15:55:06.0043] > <@rbuckton:matrix.org> There's been some interest from some of the NodeJS maintainers about trying to bring `enum` back to TC39, in part so that it could be used in a type-stripping only mode, just based on the sheer number of TS developers using `enum`. My feelings are..... Mixed. I think it would be unfortunate to bring back but also there would be definite advantages [15:55:20.0287] Which parts are what you'd consider an anti-pattern? [15:55:48.0739] Largely just in terms of expanding language syntax [15:59:00.0615] `enum` has the benefit of defining a closed domain of values. You can do that in a limited way with `{}`, but without some of the convenience like: ```ts enum Flags { None, Flag1 = 1 << 0, Flag2 = 1 << 1, Mask = Flag1 | Flag2, } // vs const Flags = { None: 0, Flag1: 1 << 0, Flag2 : 1 << 1, Mask: (1 << 0) | (1 << 1) } // or Flags.Mask = Flags.Flag1 | Flags.Flag2; ``` 2025-02-21 [16:01:19.0107] And I do think there's a world where `enum` could be extended to support ADTs, e.g.: ```ts enum Message { Quit, Write(text), Move({x, y}), } ``` [16:01:33.0260] Rob Palmer: do you have the link to the stdlib breakout session notes? [16:02:41.0373] * Rob Palmer: do you have the link to the stdlib breakout session notes? nvm [16:04:40.0515] did you mean https://devblogs.microsoft.com/typescript/announcing-typescript-5-8-rc/#the---erasablesyntaxonly-option ? [16:08:08.0286] 📣 come back to the main plenary room for a summary of breakouts [16:09:00.0955] > <@bakkot:matrix.org> did you mean https://devblogs.microsoft.com/typescript/announcing-typescript-5-8-rc/#the---erasablesyntaxonly-option ? Another reason I love TypeScript is that they frequently know what I want—and give it to me—before I do [16:10:20.0907] I'll take notes of the summaries of the presentatoins in https://docs.google.com/document/d/17u9l-TRdEasF5cKHJnTmcBUNRqGQpsYxLNraV8sChfw/edit?tab=t.0 [16:13:17.0013] > <@anthonybullard:matrix.org> Enum with its current TS implementation is considered an anti-pattern today, not to say that a native enum implementation in ES would not be much better (since most C-like languages have them) +1, although current TS enums have some nice properties, they are ultimately inessential [16:16:17.0072] I'd still like to hear feedback as to what exactly is considered an anti-pattern regarding `enum`? The two things I've heard have been: - Don't use `enum` in TS because it's not in ES - `enum` defaulting to numbers and not something like `Symbol()` [16:17:05.0948] (considering the alternative is manually defining a fixed set of forgeable strings, or unforgeable but inconvenient objects or symbols, and manually validating those) [16:17:06.0281] Maybe the merging too? [16:17:22.0741] Merging? as in `enum A { ... } enum A { ... }`? [16:17:45.0374] I'd be suprised if a 262 version had that [16:18:24.0163] I agree that's an anti-pattern and is something we probably wouldn't want to carry forward. [16:21:15.0585] enums being numbers is also bad, in my opinion [16:22:38.0574] it makes it too easy for adding new values to accidentally be a breaking change [16:23:00.0495] Regarding Number vs String vs Symbol, my version of the proposal had a solution to that: ```ts enum Color of String { Red, // "Red" Green, // "Geen" Blue, // "Blue" } enum Kind of Symbol { A, // Symbol("A') B, // Symbol("B") } enum BigFlags of BigInt { None, // 0n Flag1 = 1n << 0n, Flag2 = 1n << 1n, } // etc. ``` [16:23:10.0501] I would be ok with them being strings but at that point you might as well just use strings [16:23:26.0363] it's still helpful to simplify validation and enumeration [16:24:00.0820] Numeric enums are the most common in C-like languages, and being numbers might be necessary for TS compat. [16:24:24.0510] yeah the experience from C-like languages is one of the main reasons I am opposed to them being numbers [16:24:50.0752] Due to how existing .d.ts files work, it would be almost impossible to change that default behavior for TS. [16:25:25.0010] understandable, and I wouldn't want to add enums which conflicted with TS, but the conclusion I'd draw is that we should not add enums to JS at all [16:27:05.0333] would a TS user notice the value of the enum in typical usage? or is it just that a JS consumer would be using it [16:27:21.0021] Re: “enums are an antipattern”, I haven’t verified all of the claims in this myself but have experienced / agree with a plurality of them: https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh [16:30:43.0480] > <@ljharb:matrix.org> would a TS user notice the value of the enum in typical usage? or is it just that a JS consumer would be using it IME no [16:32:01.0144] > <@rekmarks:matrix.org> Re: “enums are an antipattern”, I haven’t verified all of the claims in this myself but have experienced / agree with a plurality of them: https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh Note that I can’t replicate the enum type unsafety example in this and have not encountered it previously [16:33:13.0836] * Re: “enums are an antipattern”, I haven’t verified all of the claims in this myself (and it’s a bit sensationalist) but have experienced / agree with a plurality of them: https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh [16:37:36.0398] > <@rekmarks:matrix.org> Re: “enums are an antipattern”, I haven’t verified all of the claims in this myself (and it’s a bit sensationalist) but have experienced / agree with a plurality of them: https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh Some of those reasons are no longer true. I'll read through and follow up after dinner. [16:41:26.0705] https://github.com/linusg/ecmascript-wiki [16:57:03.0720] 1. Enum's emit code - is irrelevant if `enum` exists natively 2. Numeric types unsafe - this has since been fixed 3. String ENUM's are named types - this does seem to be an odd behavior, though its specific to TS type checking and would be irrelevant to an ES enum There is an issue with TS `enum` where there are a few cases where an enum member value's emit can be type-directed, but I think that's fixable in TS and wouldn't impact an ES enum. [17:02:19.0357] Also, I still think `Number` values make the most sense for the default, especially when working with `Atomics` (e.g., `.load()`, `.xor()`, etc.) and I/O (protocols, headers, etc.), not to mention bitmasks. I also imagine number comparisons to be generally more efficient than string comparisons. I imagine they're also more readily inlineable into something like a jump table for use with `switch`. Numbers generally just work in most places. [17:04:09.0028] One "compatible" approach I've also considered is that an ES `enum` might *require* the `of` clause if there are any members that are missing initializers. TS `enum` could elide it (as it does today), but emit `enum E of Number {}` to JS. [17:09:18.0514] * One "compatible" approach I've also considered is that an ES `enum` might _require_ the `of` clause if there are any members that are missing initializers. TS `enum` could elide it (as it does today), but emit `enum E of Number {}` to JS, or in the case of auto-numbering, emit `enum E { A = 0, B = 1, ... }` and populate the auto-numbered enums during emit. [17:45:23.0941] do we need the `of Type` ? If an MVP was that the values had to be explicitly assigned, no auto-increment. ``` const MyFlags = enum { None: 0, A: 1, B: 2, AB: enum.A & enum.B }; ``` [17:48:41.0612] as ADT wouldn't need them right? [17:48:48.0927] The `of Type` syntax is a convenience for those who specifically prefer something like a string or symbol by default for enums. In those cases, the repetition of `enum E { A = Symbol(), B = Symbol(), ... }` would be unnecessarily unwieldy. [17:49:50.0739] It also provides a convenient way to describe the defaulting behavior for both auto numbered enums as well as string and numeric enums: https://github.com/rbuckton/proposal-enum?tab=readme-ov-file#evaluation [17:50:52.0196] if it's a connivence could it be a follow on? [17:51:44.0429] IMO, the above syntax is a non-starter. `const x = enum` certainly doesn't help the "erasable syntax" case for TS, and `enum.A` would prevent future use of `enum` for any other metaproperty, which was a blocking issue for the the `class.x` syntax as well. [17:52:31.0505] I'd personally be ok with the bare `A` resolving the the member [17:52:38.0653] * I'd personally be ok with the bare `A` resolving to the member [17:52:41.0425] I would not, unfotunately. [17:53:09.0237] how comes? you're early example had it bare [17:53:10.0248] `enum.A` would have the exact same issue as `class.A`, and I've come around to agreeing with that position. [17:53:14.0264] * how comes? your early example had it bare [17:54:03.0610] One of the motivations for an `enum` proposal would be to reduce the runtime syntax friction between TS and ES. Proposing a wholly different syntax does not address that concern and would make adoption very difficult. [17:57:12.0057] makes sense. but we potentially need the syntax to be at least slightly different if the semantics are not identical? [17:57:24.0435] Also, the mechanism for explicit autonumbering as part of emit ends up not being truly "eraseable" as it requires the introduction of temporaries to handle initializers, i.e.: ```ts import { x } from "./other.js"; enum E { A = x, B, C } ``` This is also an example of the problematic type-directed emit in TS today that I hope to fix in the future. I cannot statically know what the value of `x` is without type checking, and thus could not reliably emit the auto-incremented values for B and C without additional overhead, i.e.: ```js var _a; enum E { A = _a = x, B = ++_a, C = ++_a, } ``` [17:58:06.0765] The `of` syntax is an invocation of an explicit mapper function that handles defining the default initializer of each value. [17:58:48.0157] Ideally, I would prefer a native syntax where `enum E {}` is the equivalent of `enum E of Number {}`, and thus the syntax could be identical in both cases. [17:59:59.0339] This would also allow those who have a specific preference around using strings or symbols to express that via, e.g., a linter, while preserving the predominant base case of using numbers. [18:02:15.0197] I'm probably in the minority, I prefer the values being explicit. Even if it is repetitive [18:03:25.0759] are there other languages where the enum delegates to a runtime protocol to construct the values? [18:03:28.0028] The other caveat of TS vs ES enums to address would be the reverse mapping aspect of TS enums, which is great for diagnostics purposes but unreliable for serialization/deserialization use cases. That's why my version of the enum proposal offloads reverse mappings to a symbol protocol and is made accessible via the `Enum` API. It introduces a more reliable and formal mechanism for parsing and serializing. [18:03:51.0807] Python does [18:04:04.0615] thanks, I'll check that out [18:05:12.0912] ```py class E(Enum): A = auto() B = auto() ``` [18:05:21.0227] the parts I like the most about the proposal is the self reference during initialisation, and the object being frozen. [18:05:55.0626] Also, while not quite runtime, Go uses `iota`. C# enums use a similar auto-numbering mechanism to the one defined in TypeScript, but are also handled at compile-time. [18:09:48.0145] The other benefit to a syntactic `enum` type would be future support for decorators for things like control over serialization, formatting, and marshalling, e.g.: ```ts enum Position of Symbol { @JSONSerializer.Alias("emp") @JSONSerializer.SerializeAs("employee") Employee, @JSONSerializer.Alias("mgr") @JSONSerializer.SerializeAs("employee") Manager, ... } ``` [18:11:20.0563] * ```py from enum import Enum, auto class E(Enum): A = auto() B = auto() ``` [18:14:43.0785] This is also a hard comparison to make, considering the ratio of dynamic to static languages. By nature of JS being dynamic, more things often need to be done at runtime or are expressed via runtime operations (i.e., `Object.defineProperty`, `Reflect.*`, etc.). [18:17:56.0192] I also hold out hope that a syntactic `enum` might be able to establish an object shape for the enum declaration that could eventually be used by bytecode generators for specific performance tuning, much like how we hope the fixed shape nature of `struct` could be utilized. For example, a `switch` over cases of `E.A`, `E.B` could potentially inline those values if it is known that `E` is an enum with a fixed shape, and thus convert the `switch` to a jump table. [18:19:02.0785] As mentioned in one of the talks today, that's not something we can depend on, but its potentially feasible w/o needing any kind of whole program optimization on the part of the bytecode generator. [18:19:22.0867] if enums are mostly static I can see minifiers being able to inline the values [18:19:36.0962] the constructs might make that too hard [18:19:40.0061] * the constructors might make that too hard [18:19:41.0809] That's already the case in tools like `esbuild` [18:19:57.0442] right, but there isn't a symbol protocol today [18:20:42.0022] But that depends on whole program optimization. The `enum`-ness of `E` could be encoded into its map/shape and is thus available when collecting type feedback on a `switch` case [18:21:52.0002] doesn't need to be whole program, only need to see the two modules [18:22:00.0271] follow the import and look at the export [18:22:28.0975] Are you referring to the `@@toEnum` symbol? [18:23:05.0377] I'm not sure if the proposal changed since I last looked [18:23:11.0613] I thought the `of T` looked up a symbol on T [18:23:38.0295] We could make those frozen on built-in constructors, so for the most common use cases it can be determined statically. Edge cases using a custom `@@toEnum` would be slower, but thats pay-to-play. Also, the performance cost is only during startup. [18:24:32.0955] I thought we had a rule that we couldn't freeze intrinsics [18:24:55.0602] I mean `{ writable: false, configurable: false }` [18:25:18.0030] I'd have to defer to TG3 if that fits their model [18:25:19.0992] And if that's not viable, then an opt-out if it differs from the expected value. [18:27:18.0855] I'd personally be Ok with the possible patterns being baked in statically, without ways to create custom constructors. For strings if someone wanted a constructor that created lowercase or uppercase strings for example doesn't feel like enough of a motivation to introduce the dynamic lookup [18:27:35.0055] number+string+symbol sounds more than enough :) [18:27:51.0532] Also bigint [18:28:00.0074] interesting [18:28:06.0312] Also flags, and eventually ADT enums [18:28:14.0737] flags are numbers though right [18:28:40.0590] Yes, but the auto-numbering behavior differs [18:28:41.0151] is bigint for when needing a larger domain of possible flags? [18:29:26.0780] Yes, if bigint were fast enough I'd have plenty of TS `enum`s that I'd make into bigints. In TS we regularly have to worry about running out of space in an SMI [18:29:38.0071] I do see the wins, but I also feel like explicit assignment is unambiguious as to what will happen. It's "just JavaScript" :D [18:29:55.0825] and the repeitiveness feels like a small price to pay [18:30:08.0389] Flags enums would autonumber as `0`, `1 << 0`, `1 << 1`, `1 << 2`, ... [18:30:22.0481] I really hope we get the enum proposal and it feels like that's more likely to happen if it's kept simpler [18:30:37.0204] Explicit assignment just isn't backwards compatible with TS, unfortunately. [18:31:04.0957] could tooling help here, I'd happily write the codemod! [18:32:06.0124] also thanks for helping answer my queries, much appreciated [18:32:22.0809] The problem is the thousands of existing .d.ts files. Hand-generated .d.ts files can contain `enum E { A, B }` even though we normally emit them with hardcoded initializers. [18:32:34.0662] gotcha [18:32:53.0214] We have over a decade of legacy to deal with that ties our hands in many ways. [18:33:02.0555] so would need a way to mark the 'new' enums when generating `.d.ts` [18:33:22.0822] No, *generating* a .d.ts is fine since we always generate with hard-coded initializers. [18:33:36.0219] We have no control over hand-rolled .d.ts files [18:34:12.0631] I mean we'd preserve the auto-increment type inference for existing `.d.ts` [18:34:18.0217] i.e., much of DefinitelyTyped, any code that's behind the firewall, etc. [18:35:42.0446] JS enums could be `enum E # {}` to differentiate? [18:35:47.0450] * JS enums could be `enum E #{}` to differentiate? [18:35:48.0988] That's only possible if we preserve auto-incrementing numbers for native enums by default.\ [18:36:12.0799] Why though? What value does that bring? `of T` at least has some benefits. [18:36:21.0368] * That's only possible if we preserve auto-incrementing numbers for native enums by default. [18:36:26.0872] it's simpler [18:36:41.0997] no dynamic lookup [18:37:02.0388] Why is dynamic lookup bad for `enum E of T {}` but ok for `class C of B {}`? [18:37:28.0316] * Why is dynamic lookup bad for `enum E of T {}` but ok for `class C extends B {}`? [18:37:52.0008] I'd put forth that `class C extends B` is worse because it requires dynamic lookup during `new` [18:37:57.0957] because classes need to extend from an infinite set [18:38:11.0214] `Number` is an infinite set. [18:38:12.0756] enums can be a few built in types [18:38:18.0125] I mean the set of types [18:38:21.0105] not the set of values [18:38:40.0027] we can't hard code that classes can only extend from number/string/symbol [18:38:46.0101] we can for enum [18:39:26.0473] What good does hard coding it do? `of T` doesn't enforce any constraints on the values of each enum member, it only affects auto-numbering. [18:39:36.0941] it's simpler [18:39:39.0741] You could say `enum E of Number { A = "foo" }` [18:40:04.0197] I don't think this kind of simpler will pass muster for others on the committee. [18:40:32.0935] I think the complexity of `of` is also not aligned with the feedback we are currently getting in committee to keep proposals simpler [18:40:39.0362] for other proposals [18:40:40.0659] "simpler" would be `enum E { A, B }` produces auto-numbered values. That is a tried and true implementation that matches what TS has been doing for a decade [18:42:01.0413] Lots of code uses plain object literals for enums today, the biggest downside is not being able to self reference [18:42:03.0129] IMO, auto-numbering is a very important part of the feature and is something a large number of existing TS developers rely on. [18:43:36.0626] And without some form of auto-numbering, we have no way of making `enum` work with a pure "erasable types" solution as it would still require additional downlevel emit. [18:43:41.0513] I'd be OK if un-initalized names were auto-incrementing [18:43:56.0277] strings would need explicit assignment [18:44:07.0697] Yes, but ljharb and bakkot would not. [18:44:34.0001] `of` is designed to find a compromise between those positions. [18:44:42.0317] i don’t mind auto increment. But i mildly prefer only explicit [18:45:35.0450] if `of` is the only way to resolve the comittee's constraints I get that. But I'd really like to be sure we've exhausted 'simpler' options. [18:45:56.0813] The other benefit to `of` is to specify the backing type for auto-increment behavior, such that you could have `enum E of BigInt { None, A, B }` produce bigints instead of numbers. [18:46:13.0823] the value is imo in covering enumeration and validation, i don’t care about the one time that might have to be explicitly written. read > write and all that [18:46:17.0690] that benefit seems small [18:46:33.0497] * that benefit seems small (incrementing bigint) [18:46:49.0673] enumeration and validation are important, but only a small piece of the pie. [18:47:01.0060] for me it’s like 99% of it [18:47:02.0628] My preference continues to be not having enums, rather than trying to rationalize TS enums as a JS feature. [18:47:20.0351] Yes, but for me its maybe like 40% of it. [18:47:42.0673] what’s the rest? Surely it’s not “not having to type out a few numbers and/or strings” [18:48:21.0443] types i guess, but im assuming a JS context here :-) [18:48:59.0681] My major use cases have been ordered ranges, bitflags/bitmasks, and binary serialization formats (network I/O, binary file/section headers, etc.) [18:49:41.0397] bitflags only work if you can increment by powers of two, and i don’t see how that’s doable automatically [18:49:45.0520] `SyntaxKind`, for example, uses auto-numbering and pre-defined ranges for fast comparison of AST node kinds. [18:49:49.0857] and formats are strings which are explicit [18:50:32.0036] Its doable with `of`. [18:50:34.0160] auto numbering does seem like it make unintentional breaking changes highly likely [18:50:35.0203] I would be enthusiastic about a native BitSet, possibly backed by an arraybuffer [18:51:19.0160] (not with syntax though) [18:51:43.0652] You can do something similar in Go a well: ```go type Foo int32 const ( FooA E = 1 << iota // E(1) FooB // E(2) FooC // E(4) ) ``` [18:52:13.0966] * You can do something similar in Go as well: ```go type Foo int32 const ( FooA E = 1 << iota // E(1) FooB // E(2) FooC // E(4) ) ``` [18:53:43.0518] As would any unintentional change to your public API. [18:54:05.0021] sure. But those are harder to do by accident. [18:54:07.0555] Zig's support for fixed-width ints of any width, with packing into binary representations, is quite nice [18:55:29.0875] I would argue that banning auto-numbering, or requiring `of String` or `of Symbol`, is something a lint rule could handle, but it isn't a rule I would enforce by default. [18:56:44.0421] implicitness should be either allowed or prohibited, it shouldn’t be pushed to linters [18:58:08.0214] I would, in general, be fine with a MVP version that has no `@@toEnum` and explicitly checks if the expression passed to `of` is one of the built-in `Number`, `String`, `Symbol`, or `BigInt` constructors, as that leaves room for future extensibility (i.e., `of Enum.BitFlags`, `of Enum.ADT`, etc.) [18:58:39.0229] stuff it’s ok to push to linters is when it’s a preference; this is different imo. Autonumbering is either fine, or a footgun, so we’d have to make a call [18:58:57.0191] I believe the implicitness should be allowed, and is essential for compatibility. [18:59:33.0300] Even without `of`, you can always enforce explicitness if you need, but `enum E { A, B }` producing numbers would be essential for compatibility. [18:59:44.0151] what kind of compatibility? [18:59:55.0321] TS can transpile to explicit numbers [19:00:25.0271] Not without running into problems with "legacy" .d.ts files hand written before native enums existed. [19:00:42.0930] Its the TS version of "this is already legal JS" [19:02:34.0400] You also can't transpile to explicit numbers without either whole program analysis or introducing temporary variables. [19:03:27.0296] I'm not following this bit still. Legacy `.d.ts` would only impact the types, not the emit right? [19:05:01.0617] The types describe the runtime behavior. [19:05:46.0176] I mean, the exiting interpretation of those files doesn't need to change [19:08:04.0654] It does if we adopt an interpretation of `enum` for ES that requires explicit initializers, and then adopts some other behavior for auto-initialization later. [19:08:06.0585] * I mean, the existing interpretation of those files doesn't need to change [19:09:35.0070] Either way, not having auto numbering is incompatible with "erasable types" (i.e., such as ts-blank-space) as we have to inject initializers, or manually auto-number as in the example I mentioned above: ```js var _a; enum E { A = _a = x, B = ++_a, C = ++_a, } ``` [19:10:09.0848] `ts-blank-space` only erases the parts with no runtime semantics. So it would preserve enums as written [19:10:20.0161] as they would be valid 262 [19:11:06.0126] Maybe it gets us half way, and if you run with `--erasableSyntaxOnly` you have to explicitly number your enum values, but I'd still prefer to have auto-numbering. [19:11:25.0080] right, the point is to make enums non erasable [19:11:56.0794] It would not be pleasant to introduce a new `*Keyword` entry into `SyntaxKind` and have to shift 250+ entries up one integer. [19:12:01.0004] prefer is fine, but then it’s not a compat issue? [19:12:13.0706] > <@rbuckton:matrix.org> It would not be pleasant to introduce a new `*Keyword` entry into `SyntaxKind` and have to shift 250+ entries up one integer. breaking changes are supposed to be unpleasant to add [19:12:27.0413] feature not bug [19:12:36.0942] I wholeheartedly disagree [19:12:53.0103] why would it be relevant what number backs the ast nodes? [19:13:06.0771] Because we group those nodes for fast comparisons. [19:13:10.0346] other than to consumers who wouldn’t want the numbers to shift [19:13:29.0807] you’re implying that neighboring integers compare faster in engines? [19:13:32.0566] i.e., `node.kind >= SyntaxKind.FirstKeyword && node.kind <= SyntaxKind.LastKeyword` [19:13:37.0200] ah [19:13:50.0179] how comes we need a new syntax kind? [19:13:59.0284] so, good api design would suggest designing groups initially that had enough gaps to never run into that problem? [19:14:04.0615] I think the SyntaxKind use case is quite specific to TS's code base [19:14:11.0650] Years ago it was suggested to write a function that converts them to ints, but that's only making the problem 100% worse and killing the performance of that check. [19:14:22.0924] I assure you it isn't. [19:14:33.0944] alternative would be to add a new flag to the existing syntax kind [19:14:36.0865] * alternative would be to add a new flag to the existing syntax kind node [19:14:55.0002] That is terrible for memory usage. [19:17:11.0553] How many programs are making more than a dozen different tagged variants of one kind of thing? [19:17:37.0502] I have literally only ever done that when writing parsers or general purpose binary formats. [19:18:03.0170] Anything using `jsdom`? [19:18:26.0716] Any DSL involving a tree of disjoint nodes? [19:18:28.0767] Jsdom itself, yes. Things using it, no. [19:18:48.0710] How many programs are making DSLs? [19:18:48.0778] Games in Unity, or any other JS framework? [19:18:54.0600] most programs don’t deal with a DSL or a tree in first party code [19:18:57.0570] wouldn't it only be an extra 64bits * number of enums in program? i.e. orders of magnitudes less impact than adding a prop to the identifier nodes [19:19:56.0648] Storing an extra field on every Node just to group the kind of node? This is empirically terrible. We're regularly trying to claw back memory by removing fields we can infer rather than store. [19:20:42.0094] And how would you store something like that on the enum itself without having to do some kind of comparison/hashtable lookup just to pull out the group? [19:20:49.0635] it's not every node, I think I'm not following the original issue [19:23:29.0119] At least in TypeScript's case, ordered integer enum values are a major performance feature. Being able to do fast math on `node.kind` is essential. That would apply to any application focusing on performance optimization, not just TS. [19:23:47.0682] * At least in TypeScript's case, ordered integer enum values are a major performance feature. Being able to do fast math on `node.kind` is essential. That would apply to any application focusing on performance optimization, not just the TS compiler. [19:24:25.0004] That does not apply to any application for using on performance, just those with dozens of variants of one kind. Which is very very unusual outside of a parser, which most JS programs do not contain. [19:24:51.0094] also even if the TS codebase can’t use native enums, that doesn’t mean it’s not a valuable feature for the majority of programs [19:25:57.0574] nicolo-ribaudo: explained it to me. I thought the new syntaxKind was to represent these new enum syntax. [19:26:10.0401] as opposed to just the general TS change of needing to add any new syntax [19:26:19.0156] caught up. sorry for confusion [19:26:46.0394] I don't disagree, but I'm trying to thread the needle of: - convenient syntax - avoiding unnecessary compat risks - aligning with "erasable types" - fast math - allowing non-numeric enumerated values [19:27:20.0921] if all can be achieved then great. But some of those don’t matter to the majority of codebases, so they should be the first to be sacrificed if needed [19:28:02.0579] auto-increment in userland with AOT inlining could be done with a magic comment :D [19:28:31.0337] I agree not lovely to build a custom tool for the project [19:28:43.0255] but I think the case of these huge enums with 100s of values is rare [19:29:19.0081] Extremely rare [19:29:33.0788] All of those bullets are currently satisfied by the *current* TS enum syntax. The only case that would not be would be something like "Symbol by default" or "String by default", which would break all but the last bullet point. [19:30:02.0944] the `of T` syntax was suggested to make "Symbol by default" or "String by default" far easier. [19:30:29.0237] of T seems fine to me fwiw [19:30:40.0426] symbol and strings needing to be explicit assignment seems like an OK compromise [19:31:21.0820] And that's exactly how current TS enums work (for String, at least. Symbol isn't currently supported, but could be) [19:31:28.0971] (implicit strings is actually fine with me too, there’s no footgun there) [19:31:49.0865] For almost all programs, the benefit of having something which does not make it trivial to introduce breaking changes outweighs the benefit of auto-incrementing values. So the default should not be auto incrementing integers. [19:32:27.0837] I like current TS enums! (minus the merging and not being 262) [19:33:18.0351] In a world where you had, say Symbol by default, how would that differ from auto-incrementing integers if you never explicitly tried to hard code the value of an enum? [19:33:26.0515] * In a world where you had Symbol by default how would that differ from auto-incrementing integers if you never explicitly tried to hard code the value of an enum? [19:33:35.0506] because the symbols and strings aren’t ordered [19:33:43.0195] That doesn't matter [19:33:47.0851] The very ordering/grouping property you went with numbers is why it’s a footgun [19:33:56.0673] it’s the only thing that matters afaict? [19:34:07.0647] If you consider the value to be a black box, which is what Symbol by default implies, then whether the integers are ordered is irrelevant. [19:34:13.0489] adding a thing shouldn’t change other things [19:34:27.0148] that’s the concern [19:34:44.0897] that concern only exists with auto increment, not with implicit values [19:34:56.0674] the ordering/grouping property is a performance optimization, not a footgun. If they were Symbols by default, there is no way I could have the same performance optimizaiton. [19:35:02.0917] * the ordering/grouping property is a performance optimization, not a footgun. If they were Symbols by default, there is no way I could have the same performance optimization. [19:35:14.0173] it’s both [19:35:30.0646] For "Symbol by default", the initialized values change on every application startup [19:35:33.0096] nobody objects to the perf part from what i can tell, but it’s inseparable from the footgun part. [19:35:50.0459] > <@rbuckton:matrix.org> For "Symbol by default", the initialized values change on every application startup that’s in observable tho since it’s just identity. So it’s fine. [19:35:57.0568] > <@rbuckton:matrix.org> For "Symbol by default", the initialized values change on every application startup * that’s unobservable tho since it’s just identity. So it’s fine. [19:36:02.0676] > <@rbuckton:matrix.org> the ordering/grouping property is a performance optimization, not a footgun. If they were Symbols by default, there is no way I could have the same performance optimization. Sure there would! It just wouldn't be the default. [19:37:13.0934] Even without enums you could do what I do and have a generated file with the mapping of kinda to integers and regenerate whenever it changes. [19:37:22.0512] This is such a specialized use case. [19:37:38.0496] Symbol by default wouldn't work with shared memory multithreading, though Auto-numbering and strings by default would. [19:37:38.0953] *kinds not kinda [19:39:37.0711] Auto-numbering works because the nature of `shared struct` correlation depends on the module resolution cache, so you can be fairly confident that the enum is evaluated in the same way in both the main and worker threads. Strings work because they would be the same. Symbols would not because they would result in unique values in each thread. [19:41:11.0867] This requires something like a hashtable lookup to produce the integer for comparison, which has a major impact on performance. It wouldn't be a solution for this case. [19:43:00.0520] e.g., you go from something that is essentially `5 >= 1 && 5 <= 15` to `map[sym] >= 1 && map[sym] <= 15`, or `x = map[sym]; x >= 1 && x <= 15`, which requires more steps and more stack space in a tight loop/hot path [19:43:48.0484] I think you misunderstand. The mapping is just like `export const DECL_KIND = 12` [19:44:40.0081] That's a compatibility issue, and again blows up the first four bullet points above. [19:45:42.0662] Right. It only satisfies TS's very niche use case. But other use cases do not have the auto-incrementing constraint. [19:46:43.0212] Auto-incrementing is a very unusual thing to want and is harmful to most programs. We should not make it easy to reach for. [19:52:17.0031] It's getting late. I need to think on this more and chat with my team tomorrow. Unfortunately, the auto-numbering concern has been the biggest blocker for years, IMO. [21:17:54.0156] oh man, it hurts that someone has chosen REK for their signifier, given that those are my actual initials 😆 [23:03:25.0668] > <@rkirsling:matrix.org> oh man, it hurts that someone has chosen REK for their signifier, given that those are my actual initials 😆 I would’ve picked REKM but I was told to pick three letters 😛 [09:28:52.0347] can i come to the tg5 event if i didn't register? [09:31:39.0485] Michael Ficarra: ^ [09:32:26.0960] yep [11:07:44.0835] > <@rbuckton:matrix.org> I'd still like to hear feedback as to what exactly is considered an anti-pattern regarding `enum`? The two things I've heard have been: > - Don't use `enum` in TS because it's not in ES > - `enum` defaulting to numbers and not something like `Symbol()` > > auto-incrementing is bad because if library authors use it it becomes a footgun. at least it should be opt-in [11:10:07.0270] Potentially stupid question, but when we say "auto-increment should be opt-in", can it just be "opt-in" like this? ```js let counter = 0; enum TokenType { Arrow = counter++, Identifier = counter++, ParenL = counter++, ParenR = counter++, // ... } ``` [11:11:39.0417] Or, for binary flags, ```js let counter = 1; enum TokenType { Arrow = counter <<=1, Identifier = counter <<=1, ParenL = counter <<=1, ParenR = counter <<=1, // ... } ``` [11:12:37.0667] > <@nicolo-ribaudo:matrix.org> Potentially stupid question, but when we say "auto-increment should be opt-in", can it just be "opt-in" like this? > ```js > let counter = 0; > enum TokenType { > Arrow = counter++, > Identifier = counter++, > ParenL = counter++, > ParenR = counter++, > // ... > } > ``` maybe `auto enum T {}` or `enum T with Number { a; }` (compared to `enum T { a = 1 }`) [11:12:40.0612] * Or, for binary flags, ```js let counter = 1; enum TokenType { Arrow = counter <<=1, Identifier = counter <<=1, ParenL = counter <<=1, ParenR = counter <<=1, // ... Paren = ParenL | ParenR } ``` 2025-02-22 [16:17:26.0631] rbuckton: riddle me this [16:17:48.0995] i see in your explicit resource management test262 PR you have a test that `for (using of of [1,2,3]) {}` isn't supposed the parse [16:18:19.0662] the grammar as i read it says that for the production for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [16:18:57.0206] because of the negative lookahead, `for (using of of [1,2,3]) {}` is always parsed as for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [16:19:36.0018] but `for (using of of [1,2,3]) {}` _does_ parse as that: `using` is an identifier, the first `of` is the of in the for-of, and `of[1,2,3]` is an assignment expression of a computed property access on the identifier `of` [16:19:41.0415] what am i missing [16:19:46.0584] or is this language getting more cursed every day [16:29:38.0938] Wow that is cursed [16:30:22.0048] The way we implemented it in Babel matches your reading [16:53:29.0031] Why are the whitespace rules so incredibly lax/cursed, omg [19:17:44.0225] this is a feature [19:20:50.0967] that might be one of the best parses I've ever seen [19:22:46.0213] we found a new wat [19:51:52.0535] > <@shuyuguo:matrix.org> but `for (using of of [1,2,3]) {}` _does_ parse as that: `using` is an identifier, the first `of` is the of in the for-of, and `of[1,2,3]` is an assignment expression of a computed property access on the identifier `of` I'm not near a computer to check. If it's legal than the test is wrong. The important bit is that the parse isn't ambiguous. [19:52:25.0283] * I'm not near a computer to check. If it's legal then the test is wrong. The important bit is that the parse isn't ambiguous. [19:53:09.0968] I'll have to check later. If you could file a bug on the repo, I'd be greatful. 2025-02-24 [17:51:54.0421] The test is wrong. I find it odd we consider this to be legal as well, but I suppose that's JS for you: ```js var of = { 3: [4] }; for (of of of[1, 2, 3]) { console.log(of); } // prints: 4 ``` [08:15:16.0366] Is there interest in try-expressions to create return values? - [Repo](https://github.com/arthurfiorette/proposal-try-operator) - [Request for sponsorship/mentorship](https://x.com/arthurfiorette/status/1893829221446762903) from Arthur Fiorette [08:55:16.0385] https://es.discourse.group/t/try-catch-oneliner/107 https://es.discourse.group/t/enhanced-try-syntax/2119 [11:43:16.0800] thanks for confirmation on curse [13:23:53.0539] Aki: In the CSSWG we make it a requirement that any slideshows be saved as PDF and sent to www-archive@w3.org, then have its location in the minutes. We should probably adopt a similar policy for slides in tc39 since we're *even more* slideshow-dependent here. [13:25:24.0109] TabAtkins: lol could you read the exasperation in my "i'm so tired of linkrot" [13:25:31.0042] lol yup [13:26:23.0717] add another bullet point to "ways the new US executive branch is triggering me" [13:29:26.0812] anyway, the exma secretariat DOES archive slides at the end of every meeting [13:29:37.0390] Oh, nice, didn't realize [13:30:36.0330] it's just very "don't make me think". don't make me chase down the archive PDF when we could super easily put the siides in the same place as the agenda. (i'm not decreeing a new policy, just expressing a deeply personal opinion) [13:30:49.0966] you should decree a new policy imo 2025-02-25 [01:54:58.0002] I don't get it; do we want to encourage people to silently swallow and ignore errors? [02:47:46.0003] I believe the motivation is to avoid using a big try-catch scope to catch errors for multiple statements. Rather, it encourages to handle error for each function call that may throw, comparing to the "typed" catch blocks. Such syntax also presents in languages like Swift (https://docs.swift.org/swift-book/documentation/the-swift-programming-language/errorhandling/#Converting-Errors-to-Optional-Values). However, Swift has a stronger enforcement that the error can not be easily discarded with this syntax. [03:01:08.0179] yeah I guess this depends whether we're talking about the [error, value] version or the just-return-undefined-in-case-of-error version [08:08:03.0981] > <@tabatkins:matrix.org> Aki: In the CSSWG we make it a requirement that any slideshows be saved as PDF and sent to www-archive@w3.org, then have its location in the minutes. We should probably adopt a similar policy for slides in tc39 since we're *even more* slideshow-dependent here. When our company was acquired and we had to move from GSuite to M365 (don't get me started), they disabled all our accounts and broke all of the links for *years* of my presentations to TC39. I had to escalate to very high levels to get them to turn my account back on temporarily so I could download PDFs and put them in the agendas repo. A policy to just do this at the end of each meeting would be so helpful. [08:55:45.0757] for the `try ...` expression. Maybe any non-object exception would get put into a new Error object with the value as the cause? To avoid having to distinguish between code that threw or returned undefined [08:56:05.0503] or maybe that ship has sailed as this isn't a thing that catch blocks support [08:56:16.0465] * or maybe that ship has sailed as this isn't a thing that catch blocks do [08:56:18.0908] So, for future reference, Patrick C does gather and download all the slides and throw them in a zip file after every meeting. They are in the Ecma_Documents/TC39/[year] folder of the ecma file server. But I agree it would be really, really nice if everyone just put them with the agenda. [08:57:19.0555] > <@aclaymore:matrix.org> for the `try ...` expression. Maybe any non-object exception would get put into a new Error object with the value as the cause? To avoid having to distinguish between code that threw or returned undefined One of the alternatives that the proposal has is three values: a boolean to tell whether it errored, the error, and the return value [08:58:41.0779] right, this is an alternative to needing to return 3 args [08:58:54.0095] can 'just' check if err is truthy [09:00:04.0122] throwing falsey values is ?never? a good idea in the first place? [09:43:54.0185] I find it rather hard to justify that `[ok, error, value]` is needed just because `error` might be falsy. If your error might be falsy, that's something you ought to fix in your own code rather than having the spec make allowances for it. [09:48:05.0380] There’s also language precedent in `Promise.allSettled` [09:49:10.0105] That is, precedent for a taggèd union of `{status, value, reason}` [10:04:12.0741] > <@eemeli:mozilla.org> I find it rather hard to justify that `[ok, error, value]` is needed just because `error` might be falsy. If your error might be falsy, that's something you ought to fix in your own code rather than having the spec make allowances for it. I disagree. It doesn't matter if it's a bad idea to throw a falsy value, it's *possible* to throw a falsy value so it must be possible to differentiate the result. Otherwise the feature is unreliable in corner cases and developers could make poor assumptions about whether the code actually executed successfully. `using` allows for this case as well. [10:12:14.0950] Given that a try-expression would be constructing a Result, why not fix this the way that Ashley Claymore suggests above? As in, always wrap a non-Error value in an Error with a cause. As a developer, I'd find it much more useful to be able to rely on `result.error` always being either undefined, or an Error. [10:15:27.0247] That seems like wasteful allocation of an extra object, along with collecting a stack trace, if a user writes a `try foo()` in a tight loop and ignores the result [10:15:49.0830] It's convenient, yes, but may not be performant. [10:16:23.0918] Warning: in reviewing the notes, I saw an unknown speaker attributed as `ABC`. Note takers, please don't do this. Use `???` or something. [10:17:51.0310] Is an exception-based control flow ever going to be performant in JS? If performance at this level is a concern, shouldn't the user code never be throwing anything in the first place? [10:22:57.0262] > <@michaelficarra:matrix.org> Warning: in reviewing the notes, I saw an unknown speaker attributed as `ABC`. Note takers, please don't do this. Use `???` or something. Also some quotes were misattributed to me and I've corrected them with who I think said them using `KG?:` notation. So if you're searching for quotes attributed to you, you may want to look for that form as well. [10:27:51.0029] Having said that, now I'm not actually sure if exceptions are in fact as performant as any other style of code in JS, or if they introduce a penalty. I might be remembering things from 10-20 years ago. [10:28:21.0001] * Having said that, now I'm not actually sure if throwing and catching exceptions are in fact as performant as any other style of control flow in JS, or if they introduce a penalty. I might be remembering things from 10-20 years ago. [10:29:34.0200] eemeli: `try` deopts the surrounding function in V8, but that’s easy to work around. best practice today is to make a tiny function with a `try/catch` and sandwich it between optimizable frames [10:31:06.0577] Interesting. That is basically a verbose version of the proposed expression-try. I wonder if using expression-try, then, could avoid the deopt. [10:31:07.0768] that said, javascript and high performance javascript are not similar languages [10:33:56.0804] While you’re thinking about this, please also think about `try {} catch {} then {}` so folks can continue the lexical context of the `try` block without being subject to the `catch`. It’s very common to do way too much work in the `try`, for the convenience of the lexical bindings there. [10:35:44.0854] Do you mean `try {} catch {} finally {}`? [10:36:03.0558] I do not. [10:36:33.0543] I’m proposing a block that executes only along the happy path, continuing the lexical bindings of `try`. [10:37:37.0177] This is pretty straight-forward to express in terms of promise `then` chains, but much less obvious with `try`. [10:37:40.0748] That seems like a use case that try-expressions are also looking to somewhat solve. [10:42:36.0536] Like, `try { } catch {}` is the synchronous analog of `tryback().then(null, catchback)` whereas `try {} catch {} then {}` is analogous to `tryback().then(thenback, catchback)` [10:43:13.0763] I am reasonably sure this hasn't been true for a long time now [10:44:00.0071] yeah since 2016 https://groups.google.com/g/v8-users/c/maH60gh_a8s [10:44:03.0123] I’m prepared to believe. I last checked five years ago. [10:45:18.0246] Evidently on an already old Node.js timeline. Thanks, bakkot [10:50:53.0041] then how can i determine if what was thrown was an error with a cause, or the falsy value? there are empirically use cases for throwing non-object values, falsy or not, and we can't be pretending that's not the case in language design. [10:56:06.0692] > <@ljharb:matrix.org> then how can i determine if what was thrown was an error with a cause, or the falsy value? > > there are empirically use cases for throwing non-object values, falsy or not, and we can't be pretending that's not the case in language design. It could _always_ wrap, so you can also check .cause to see what was actually thrown [10:56:25.0785] lol so you'd get an error with a cause that's an error with a cause, if the latter was thrown? [10:56:31.0925] what's the value of that [10:57:04.0234] Why would you need to differentiate errors at this sort of resolution? [10:57:05.0349] imo things that deal with exceptions should all be consistent; you can throw any value, so you must always be able to catch any value [10:58:03.0293] That would still continue to be just as possible as it is today, though. [10:58:05.0080] exceptions can (and often are) be used as a form of flow control, like promises but synchronous. throwing undefined, null, false, etc is all something i've seen on nonzero occasions [10:58:23.0997] > <@ljharb:matrix.org> what's the value of that That it prevents you from accidentally forgetting that thrown values can be falsish, which is very easy to do if you have separate .error and .ok properties [10:59:23.0686] as opposed to accidentally forgetting any other distinguishing things besides falsiness? what if you forget they can be truthy primitives [10:59:44.0146] they can also be an object with getters that throw when you access them, which you could also forget [11:00:01.0857] Hence my suggestion above, "always wrap a non-Error value in an Error with a cause". [11:00:16.0828] right. but imo that would be a very confusing inconsistency with the rest of the language [11:00:20.0902] * right. but imo that would be a very confusing inconsistency with the rest of the language, for very little benefit [11:00:25.0030] all exceptions are of type `unknown` and it doesn't make sense to me to implicitly wrap them in any context [11:01:39.0996] * all exceptions are of type `unknown` and it doesn't make sense to me to implicitly wrap them in any context (since they can't be made to be wrapped in every context) [11:01:41.0327] Then the immediate `result.error` would always be an Error, and if you really case, you could get the original thrown value in cause, modulo the concern about the thrown error itself having a cause. [11:01:59.0593] * Then the immediate `result.error` would always be an Error, and if you really care, you could get the original thrown value in cause, modulo the concern about the thrown error itself having a cause. [11:02:03.0396] "always be an error" isn't a universal or objectively correct thing to want [11:02:23.0825] * "always be an error" isn't a universal or objectively correct thing to want (at least not in JS as it is) [11:02:35.0144] Why not? I mean, we're calling the property `.error` after all. [11:02:48.0535] What if we did the ADT/enum proposal first [11:02:55.0514] i mean we could call it `.exception` but the name should be descriptive rather than dictating the semantics [11:03:07.0199] colloquially the error is whatever a catch block would catch [11:03:16.0984] how does that change this? [11:03:40.0782] Then we'd have Success(value) and Failure(thrown value) [11:04:12.0018] With no need for rewrapping [11:04:21.0295] maybe i'm missing context on which enum proposal you mean, but enums aren't wrappers for values, they're a list of constants? [11:04:31.0559] or do you mean like extractors [11:04:36.0836] * or do you mean like extractors + pattern matching? [11:04:44.0128] > <@ljharb:matrix.org> maybe i'm missing context on which enum proposal you mean, but enums aren't wrappers for values, they're a list of constants? I vaguely remember some version of it that allowed attaching a payload to the enum values [11:05:04.0305] i can't conceive of how that would work or make sense, but lmk if you find the link [11:05:21.0495] Oh it was this https://github.com/Jack-Works/proposal-enum?tab=readme-ov-file#future-steps-adt-enum [11:06:26.0257] i don't recall if that was presented, but since it requires pattern matching i assume the way you'd do that is as an extractor [11:06:54.0055] but that still requires a wrapper object to be extracted from, and users wouldn't be forced to use the extractors, so you'd still need three properties [11:07:30.0168] * i don't recall if that was presented, but since it requires pattern matching i assume the way you'd do that at this point is as an extractor [11:07:37.0547] * but that still requires a wrapper object to be extracted from, and users wouldn't be forced to use the extractors, so you'd still need three properties, and we'd still need to bikeshed their names [11:10:18.0268] man I really do not like the `[error, result] = whatever` style proposals [11:10:32.0486] I do not currently think any new syntax is a good use of our time but this one seems particularly bad [11:11:52.0056] if someone is motivated to do anything in this area, do expressions seems like the obvious thing; then you don't need a box: `let result = do { try { whatever } catch { null } }` and it's on you to ensure that `null` is not a valid value in the happy path, or use some other value if it is [11:12:26.0209] I am not currently planning on doing any work on do expressions and would discourage anyone from doing any work on any syntax proposals [11:12:43.0548] but if someone really really wants to do so I'm not going to stop people from picking up do expressions [11:13:56.0900] (any syntax sugar proposals, I should say; for example module declarations are new syntax but the point is they provide a new capability) [11:39:18.0589] > <@nicolo-ribaudo:matrix.org> I vaguely remember some version of it that allowed attaching a payload to the enum values That is something I've also been considering for my version of an enum proposal [13:25:56.0497] I use this sort of syntax for other things in my Python code right now, it really doesn't feel that bad. I suppose Python has the slight advantage of not needing the `[]` on the LHS for tuple unpacking. [13:26:28.0373] (my parser projects are littered with `val, i, err = parseFoo(...)` calls) [13:44:45.0260] so lol `for (using await of []) {}` is fine [13:44:59.0210] also why did we hate on `let let` specifically but `using using` is fine? [14:35:52.0125] > <@shuyuguo:matrix.org> also why did we hate on `let let` specifically but `using using` is fine? I think there's still time to add new contextual keyword restrictions [15:06:53.0189] `for await (await using` what is we doing 💀 [15:07:55.0334] what about the other side? do you think `using let` should be allowed [15:08:16.0564] actually we already disallow `const let` so it should stay disallowed 2025-02-26 [18:56:56.0126] > <@bakkot:matrix.org> (any syntax sugar proposals, I should say; for example module declarations are new syntax but the point is they provide a new capability) Do you see do expressions as a capability? [18:57:10.0687] no [18:59:15.0581] > <@akirose:matrix.org> anyway, the exma secretariat DOES archive slides at the end of every meeting Can we put these archives in the notes repo in addition to the Ecma filer, so it is easier for people to access? [19:01:23.0979] > <@bakkot:matrix.org> (any syntax sugar proposals, I should say; for example module declarations are new syntax but the point is they provide a new capability) You mentioned at TG5 that it could be worth studying pipe syntax’s effects on developers again. Or maybe studying other syntax-sugar proposals for TG5. Do you figure any of that still might be worth doing? [19:03:00.0040] bakkot: do you feel like ?. Was a mistake in retrospect? Or like we already did the highest value ones? [19:04:45.0944] > <@bakkot:matrix.org> (any syntax sugar proposals, I should say; for example module declarations are new syntax but the point is they provide a new capability) * You mentioned on Friday at TG5 that it could be worth studying pipe syntax’s effects on developers again. Or maybe studying other syntax-sugar proposals for TG5. Do you figure any of that still might be worth doing? [19:10:11.0760] second thing [19:10:29.0988] that was probably someone else? unless you mean some previous TG5 meeting. I wasn't able to make this one. [19:11:37.0574] Ah, sorry, I must have misremembered. Thinking harder, it was probably Michael Ficarra instead. [19:17:25.0526] and to be clear, I don't mean to express 100% confidence that there's not some equally valuable sugar waiting to be found. I just don't really expect this to be the case; most of the really good ideas, including optional chaining, have been tossed around for a long time. also "accessing a property of an object only if it's present" is one of the most frequent and (previously) annoying things you do when writing JS and so was almost uniquely ripe for sugar. by contrast there's a lot more low-hanging fruit for standard library stuff. stuff like `getOrInsert` or base64. and since standard library functions are also much lower cost to add than new syntax, I think the committee's time would be better spent working on those than new syntax [19:29:55.0710] like, we should have a priority queue, we should have some sort of concurrency primitives, we should have `debounce`, we should be able to shuffle arrays, we should have seedable RNGs, we should be able to sort numerically without having to remember how to write the custom comparator for that [19:30:01.0873] there's a lot of stuff [19:48:24.0426] I did plan on bringing debouncing back after https://github.com/tc39/proposal-function-helpers was rejected for being too broad. Maybe I should have focused first on debouncing, rather than demethodize and pipe functions. It hadn’t occurred to me that `debounce` would be particularly less controversial as low-hanging fruit. I wonder if any of the others would be the same. [19:50:32.0695] debouce will be controversial because it has a timer in it [19:50:40.0646] Debounce does touch the “timers” rail, but if you anticipate that argument, I’m sure you can find a path. [19:50:53.0031] possibly the right path is doing it in whatwg instead [19:51:08.0818] Or accept a `now` arg. [19:51:31.0838] alternatively you could start a long process fight about whether we care more about the "no timers in the language" constraint some delegates have than the "make the language actually useful for developers" goal [19:51:32.0592] Oh, yeah, I had forgotten… [19:51:39.0750] which would be worth doing but I have not stomach for it [19:51:45.0316] maybe people would accept it being normative optional [19:51:58.0951] * which would be worth doing but I have no stomach for it [19:54:40.0031] Has seeded random gone through a tg3 review? [19:56:46.0685] I think its last activity was prior to tg3 existing [19:57:29.0679] TG3’s repository doesn’t have any search results for “random” or “seed”. I’m interested in pursuing seeded random later if someone doesn’t beat me. [19:57:35.0595] Speaking of process fights, I saw in https://github.com/WebKit/standards-positions/issues/292#issuecomment-2682983190 that annevk wanted “at least one conversation with TC39 to have happened” for WHATWG Observables. “It's a big enough new language-like feature that explicitly getting their feedback is important.” But I’m not sure if that means he would like someone to present it as a plenary topic. [19:57:42.0482] * Speaking of process fights, I saw in https://github.com/WebKit/standards-positions/issues/292#issuecomment-2682983190 that annevk wanted “at least one conversation with TC39 to have happened” for WHATWG Observables. “It's a big enough new language-like feature that explicitly getting their feedback is important.” But I’m not sure if that means he would like someone to present it as a TC39 plenary topic. [19:59:05.0666] https://github.com/tc39/proposal-seeded-random is the existing proposal; I believe TabAtkins hasn't had time to work on it but would plausibly appreciate help [19:59:32.0394] I left some random comments in issues a while ago and I think with those incorporated it would probably be ready to advance [19:59:45.0842] yeah I know ljharb at least was also annoyed it went through WHATWG [20:00:05.0731] Would love to discuss. [20:04:02.0146] With regard to Anne’s comment, has TC39 ever “commented on” or “reviewed” a WHATWG proposal, like how TAG has done? [20:04:13.0467] not that I can recall [20:09:39.0561] > <@bakkot:matrix.org> I left some random comments in issues a while ago and I think with those incorporated it would probably be ready to advance Yeah it's ready to advance with those incorporated, I would indeed appreciate help, and wouldn't mind discussing with Kris Kowal [20:11:26.0321] And yeah, the proposal predates tg3 afaik [20:17:06.0279] Do not be so sure. I will tell my `new Math(seed)` joke at every opportunity. [20:17:35.0713] > <@bakkot:matrix.org> not that I can recall We have had reflector threads that I think were interpreted as asking TC39, like the one preceding elementInternals [20:19:00.0973] We should probably do something to reduce the risk that someone could interpret TC39 delegates’ input on proposals as being from TC39 generally. Like by demonstrating some good constructive examples where TC39 as a whole gives input on something. [20:45:06.0976] I would expect missives of TC-39 to other standards bodies to be a product of plenary. [21:10:52.0377] * Speaking of process fights, I saw in https://github.com/WebKit/standards-positions/issues/292#issuecomment-2682983190 that annevk wanted “at least one conversation with TC39 to have happened” for WHATWG Observables. “It's a big enough new language-like feature that explicitly getting their feedback is important.” But I’m not sure if that means he would like the proposal’s authors to present it as a TC39 plenary topic. [21:40:20.0255] @jschoi on Observables, Dominic Farolino has asked to present at the April 2025 TC39 meeting so this is on a promising path. [21:40:27.0804] We messed up on logistics/scheduling in the Oct 2024 meeting else this conversation would have happened earlier. [22:16:47.0155] Kris Kowal: Should we have something akin to a "positions repo" with updates blessed by plenary? I guess it would be more like "committee feedback on external things" given we're not inflicting a verdict, but more expressing suggestions that external groups would not be obligated to follow. [22:27:22.0230] I’m not sure. The status quo is individual delegates representing their own positions and relaying perspectives of other delegates to the best of their knowledge, which can be confusing and ambiguous. We would have to be careful about what signals and commitments an official position provides regarding TC-39s own specs. [22:28:19.0348] “Tentative Communications of TC-39” [22:47:10.0953] I guess even if it boils down to individual opinions, "this issue was raised to TC39 and $person expressed the following feedback" is better than "we asked $person about this issue because they're part of TC39" [23:49:16.0566] I suspect there would be times we could say a committee position has consensus (to provide a clear steer), and times where we could cite individuals having differing opinions. [23:56:55.0468] Kris, it's interesting that you mention we need to be careful about such statements because they could also have consequences on our own work. It is already the case today where individuals can make unqualified statements that may be inferred as impactful committee positions. What we are missing is the other side of that coin. [23:57:02.0665] Having a venue/repo to document current positions could also allow us to be clear on things that are widely held vs contentious. [03:42:15.0746] I've gotten a number of "cold" emails recently from people on Discourse asking me to champion a proposal that they are interested in, and I know others have received the same request from the same person, in at least one of these cases. I'm not so interested in the ideas presented, but I don't want to be too discouraging. I don't think we should encourage community members to try to "break through" to the committee by soliciting the support of a committee member in this spammy way. I'm not sure what to do about this, how to respond to the emails, or if we should make some kind of outlet for people if they feel like Discourse isn't enough to get their idea considered. [07:30:00.0047] Discourse is the canonical place; I have been redirecting people back there [08:07:26.0670] do we have policy for meeting hosting wrt discrimination and local laws? I searched around the github repos a bit but I might have missed it. I ask in particular due to today's memo from the us secretary of state regarding visas... [08:07:48.0519] * do we have policy for meeting hosting wrt discrimination and local laws? I searched around the github repos a bit but I might have missed it. I ask in particular due to yesterday's memo from the us secretary of state regarding visas... [08:16:19.0824] I don't think we have policy although IIRC we've talked about it before, can't remember when [08:17:07.0174] I think in the context of individual US states? [08:17:36.0817] we discussed it last time when considering hosting in Texas [08:17:46.0135] adjacent to the OpenJSF event [08:20:07.0195] sounds a bit like: https://github.com/tc39/Reflector/issues/106 [08:45:21.0888] this is literally an impossible problem to solve, given that some people are unable to leave the US, and others are unable to enter. (and this is affecting standards participants currently) [08:45:36.0025] it's very sad. I don't know what to do (besides continue hybrid) [08:46:43.0784] when you say "back there" do you mean when you get similar emails? I guess I can just write that redirection once and keep sending it... [08:46:56.0426] maybe we could document somewhere that you shouldn't spam all the TC39 delegates... [08:47:01.0380] Do you have any link to what you mean by "some people cannot leave the US"? e.g. on Friday I walked in front a Microsoft office in Vancouver, and I was thinking that it'd be nice for example to have the in-person NA meeting there rather than always in Seattle [08:47:04.0097] I've only gotten such an email once but yes [08:47:10.0529] * Do you have any link to what you mean by "some people cannot leave the US"? On Friday I walked in front a Microsoft office in Vancouver, and I was thinking that it'd be nice for example to have the in-person NA meeting there rather than always in Seattle [08:47:52.0590] it's well-documented that US trans people are having trouble getting passports renewed. [08:48:14.0065] (or obtained in the first place) [08:48:40.0073] and it's not like you can get around it by using the wrong gender, you just flat-out can't get it [08:49:30.0485] anyway we aren't going to solve this by having all conferences in the US, as that would exclude non-US trans people, who are being banned from entering [08:49:50.0107] (as well as tons of other people who can't get visas) [08:50:17.0774] I currently see no reason why Trump won't expand these travel bans further [08:50:32.0449] * I currently see no reason why the Trump admin won't expand these travel bans further [08:50:54.0152] > <@littledan:matrix.org> maybe we could document somewhere that you shouldn't spam all the TC39 delegates... We could say this, but I'm sympathetic to these people. If they feel like they haven't gotten enough feedback on Discourse, it's possible that nobody responded because nobody liked it, but it's also possible that nobody really saw it. Since the only path forward for them is a delegate champion, it's not unreasonable to try to reach out more directly, somewhat like how people interact with elected government representatives. [08:53:03.0931] for the record, I've only gotten one of these unsolicited proposals and it was actually something reasonable that someone put a lot of work into, so not really "spam" [08:55:51.0192] I think email every delegate is spammy, even if you've put a lot of work in, in the same way that sales emails blindly going out to every startup is spammy even when the product being sold has had a lot of work put in [08:56:00.0603] also I really don't want to encourage this behavior in general [08:56:28.0021] if we tell people that the discourse is the correct forum, which we do, then we absolutely shouldn't allow people to go around that [08:56:40.0576] that's privileging people who are choosing to ignore the stated rules [08:56:59.0142] > <@littledan:matrix.org> it's very sad. I don't know what to do (besides continue hybrid) yeah I'm not really sure either... though as it seems we don't have existing policy for this, maybe I'll open an issue for a more structured discussion later this week... what repo would be the right place for that? [08:57:18.0799] reflector I think [08:58:23.0462] The problem with discourse is that for many delegate discourse is just a place to redirect people so that we don't actually have to listen to them. How many of us are active there? 5? [08:58:26.0396] > <@bakkot:matrix.org> if we tell people that the discourse is the correct forum, which we do, then we absolutely shouldn't allow people to go around that it probably wouldn't be as necessary if people were willing to give negative feedback for bad proposals as easily as positive feedback [08:58:39.0983] or even otherwise good proposals that are not really a good fit [08:59:03.0480] > <@nicolo-ribaudo:matrix.org> The problem with discourse is that for many delegate discourse is just a place to redirect people so that we don't actually have to listen to them. How many of us are active there? 5? I read almost all of it, but rarely participate [08:59:14.0170] if people start sending all their proposals to email then everyone will ignore those too [08:59:27.0484] the reason they're ignored is because the proposals are mostly bad, which you can't change by changing the forum [08:59:36.0613] > <@bakkot:matrix.org> if people start sending all their proposals to email then everyone will ignore those too low-effort proposals won't have such determined supporters [09:00:03.0663] yyyyeah I really don't think that's gonna be the case [09:00:05.0497] I now wish we had a breakout session at the last plenary to go through discourse and explain why those proposals are bad [09:00:08.0128] also many proposals are high-effort and also bad [09:00:41.0543] are there any good ones? [09:00:46.0549] (I haven't been reading Discourse) [09:00:55.0299] also also many proposals aren't obviously bad, but I'm not really interested in championing them, like https://es.discourse.group/t/comments-in-template-literals-comment/2304/6 [09:01:03.0139] and I don't really know how to respond to those [09:01:20.0397] I do try to respond to the definitely-not-viable ones but I don't consistently manage it [09:01:39.0602] > <@nicolo-ribaudo:matrix.org> I now wish we had a breakout session at the last plenary to go through discourse and explain why those proposals are bad I could see the community spinning this as "in coordinated effort, TC39 delegates angrily unload on community forum" or something [09:02:05.0550] > <@littledan:matrix.org> are there any good ones? Yes, a few. Math.clamp, which was recently presented, was proposed on the Discourse a while back. [09:04:55.0025] anyway if we think the discourse isn't working I'd be OK with telling people they can email delegates directly, but as long as we're telling people to use the discourse I definitely don't want to filter for the people who are going around that (cf https://siderea.dreamwidth.org/1209794.html ) [09:12:24.0471] > <@michaelficarra:matrix.org> I could see the community spinning this as "in coordinated effort, TC39 delegates angrily unload on community forum" or something yeah, the discourse already feels a bit like this from an outsider's point of view, TBH! I would actually not encourage most delegates to do community relations on the discourse, as I think most of us are going to be quite bad at it. I think it'd be great if we identified who in the committee is good at it, who would like to become good at it, and give those people whatever support and training they need so they don't burn out on it [10:23:00.0107] Could the breakout session be framed as “TC39 gives feedback on Discourse proposals” rather than “TC39 picks bad proposals on Discourse and makes replies on why they’re bad”? It could be a systematic “position-writing” process that could add to a “community-proposal-positions” document…or maybe https://github.com/tc39/rationale or https://github.com/codehag/documenting-invariants. Like how WebKit and Mozilla give standard positions. [10:27:50.0825] Of course, this means that some Discourse proposals will be received positively or neutrally rather than negatively yet will have no champion available for it. But that’s still probably better than the status quo; it’d still give a persistent reference list of TC39 signals that anyone can point the community to, before they write a new proposal. The list of Stage-0 proposals on tc39/proposals is somewhat like this but requires that a real champion have presented it. [10:38:07.0104] * Of course, this means that some Discourse proposals will be received positively or neutrally rather than negatively yet will have no champion available for it. But that’s still probably better than the status quo; it’d still give a persistent reference list of TC39 signals that anyone can point the community to, before they write a new proposal.
The list of Stage-0 proposals on tc39/proposals is somewhat like this but is restricted to proposals that a real champion have presented. [10:39:50.0683] * Of course, this means that some Discourse proposals will be received positively or neutrally rather than negatively yet will have no champion available for it. But that’s still probably better than the status quo; it’d still give a persistent reference list of TC39 signals that anyone can point the community to, before they write a new proposal.
The list of Stage-0 proposals on tc39/proposals is somewhat like this but is restricted to proposals that committee champions have presented. 2025-02-27 [20:24:08.0838] > <@eemeli:mozilla.org> I find it rather hard to justify that `[ok, error, value]` is needed just because `error` might be falsy. If your error might be falsy, that's something you ought to fix in your own code rather than having the spec make allowances for it. Could we do something like `[value]` if success and `[undefined, reason]` if throw. That way anyone that want to handle the unexpected case can use the arity of the returned tuple? Or if we absolutely want to put the error first, use a hole in the array instead of a reason. [20:28:20.0888] this was an interesting read, and for like three extra reasons too: TIL that LJ lived on in a new form, TIL that "straitened" means "narrowed" (feel like this would be unintelligible when spoken 😅), and boy do I ever feel attacked by the "never identify with your virtue [of agreeableness]" part 🙈 [22:08:34.0839] we should never, ever, ever have a new API that produces holes [22:34:20.0226] new design goal: topological homogeneity [22:34:39.0900] * new TC39 design goal: "topological homogeneity" [22:41:25.0206] * new normative convention: "topological homogeneity" [23:17:42.0209] as responsible language designers and maintainers, it's entirely appropriate to reflect on the nature of holes and come to a good conclusion about what to do. So I'm just gonna drop this here: https://plato.stanford.edu/entries/holes/ [23:20:52.0201] That article is gold. [23:20:56.0426] this article reads like there's a dozen SCP reports between the lines, i love it [23:23:06.0593] also it reminds me of the infocom game where you can pick up a hole, have it in your inventory, and drop it on an arbitrary surface. [23:25:07.0974] I seem to recall a Loony Toons character that also had a hole? (Was it Bugs Bunny?) [23:27:13.0181] That's one for the positions repo >TC39 regrets the _horror vacui_ of Arrays [23:28:07.0701] https://www.youtube.com/watch?v=XaakNHzFoXE&t=97s [23:32:58.0305] > as urged by Lewis 2004 hell yeah, I was just thinking about mr. counterfactuals yesterday [23:33:02.0570] * > as urged by Lewis 2004 hell yeah, I was just thinking about mr. counterfactuals yesterday [23:33:22.0982] * > if one accepts that absences can be causally efficacious, as urged by Lewis 2004 hell yeah, I was just thinking about mr. counterfactuals yesterday [23:34:19.0895] * > if one accepts that absences can be causally efficacious, as urged by Lewis 2004 hell yeah, I was just thinking about mr. modal realism yesterday [23:36:45.0424] * I unironically love this article 😂 also: > if one accepts that absences can be causally efficacious, as urged by Lewis 2004 hell yeah, I was just thinking about mr. modal realism yesterday