| 15:10 | <Chris de Almeida> | looking for someone to help with notes please! 🙏 |
| 15:10 | <Aki> | Helping out with notes is so much more low-key than it used to be |
| 15:10 | <Aki> | way easier |
| 15:10 | <Aki> | just sayin |
| 15:12 | <ljharb> | (yay for CLE) |
| 15:18 | <eemeli> | https://fosdem.org/2026/news/2025-09-18-fosdem-2026/ |
| 15:18 | <Andreu Botella> | The dates are now published: Jan 31, Feb 1 |
| 15:18 | <Aki> | YAY |
| 15:18 | <Aki> | finally |
| 15:21 | <rbuckton> | Regarding Invited Expert status, there's an open issue in Admin-and-Business to transition me back to delegate status that is awaiting action. |
| 15:32 | <ljharb> | sorry for the delay on that; i've been out of the country |
| 15:42 | <bakkot> | last call for comments on https://github.com/tc39/how-we-work/pull/164 |
| 16:03 | <Ben Allen> | Seems like we've lost the transcriptionist |
| 16:04 | <Chris de Almeida> | we have not. refresh? |
| 16:05 | <Michael Ficarra> | people should not be doing anything with string enums other than === |
| 16:06 | <eemeli> | I've now filled out the missing parts of my comment. |
| 16:07 | <rbuckton> | while I'm not a fan of the idea of ignoring case on input for string enums, imo kebab case is better for readability if we do. that said ignoring input case has a number of concerns, including performance and readability (inputs could be all uppercase or all lowercase and can make words run together). |
| 16:10 | <Michael Ficarra> | out of curiosity, where are we on time? |
| 16:10 | <Chris de Almeida> | few mins remain |
| 16:10 | <Michael Ficarra> | (this is a feature I wish was part of TCQ) |
| 16:10 | <Chris de Almeida> | we can start posting the end times ITC if people want |
| 16:11 | <Michael Ficarra> | I want to make sure we have enough time at the end to clearly state a coherent proposal that we can accept/decline |
| 16:11 | <Chris de Almeida> | might need a continuation |
| 16:12 | <nicolo-ribaudo> | I'm hoping we are not not cancelling the last day for continuing this 🤞 |
| 16:12 | <rbuckton> | that said, string enums based on existing names (i.e., identifiers, well-known OS-specific constant names from C++ headers, etc.) are a reasonable exception, mostly to take advantage of prior knowledge and make discovery easier |
| 16:13 | <Michael Ficarra> | I'm hoping this remaining an open issue doesn't block iterator chunking |
| 16:13 | <nicolo-ribaudo> | Getting myself off the queue to not waste time, but just for context: the thing about Mark mentioned comes from Unicode, that defines some base units and then combines them with modifiers like -per-. Amount didn't design it, it does not actually enforce it (but unit-conversion methods will, in a separate proposal, will) |
| 16:13 | <Chris de Almeida> | I captured the queue before everyone removed items |
| 16:14 | <Michael Ficarra> | if we're fine going forward with kebab case and possibly adding an accept-both across a large swath of APIs at a later time, I'm good |
| 16:17 | <rbuckton> | Enum members are generally expected to be camel/pascal-cased, though it is possible to use any string as a member name. Avoiding non-identifier characters in an enum member name makes auto-complete easier. Enum member values, however, have no such requirement. So enum E { FooBar = "foo-bar" } is perfectly reasonable, while enum E { "foo-bar" = "foo-bar" } is possible but discouraged. |
| 16:18 | <Andreu Botella> | is this about millions in Spanish? |
| 16:19 | <nicolo-ribaudo> | In italian too, I think. 1M kebab vs 1 millione di kebab |
| 16:19 | <nicolo-ribaudo> | Or at least that's how I'd write it |
| 16:21 | <eemeli> | Ok, that makes sense. |
| 16:51 | <eemeli> | In Intl we have this:
|
| 16:54 | <bakkot> | I did not understand dminor if that was intended to be a comment |
| 16:54 | <dminor> | Sorry, I was asking for the next speaker. |
| 16:54 | <dminor> | My dog is causing a lot of noise due to a delivery. |
| 16:55 | <Zb Tenerowicz (ZTZ/naugtur)> | You were not legible now and previously. |
| 16:55 | <Zb Tenerowicz (ZTZ/naugtur)> | Do a mic check before you speak next |
| 17:01 | <Zb Tenerowicz (ZTZ/naugtur)> | Sounded distorted, might be configured too loud or googlmeet needs a second to stabilize |
| 17:02 | <dminor> | Just did an os update right before the call :( Hopefully it will be better after a restart. |
| 17:04 | <waldemar> | new Intl.NumberFormat('en', { minimumSignificantDigits: 3, maximumSignificantDigits: 3 }).format(0.03) // "0.0300" |
| 17:05 | <waldemar> | It's not "0.03" |
| 17:11 | <waldemar> | Just tried the example I gave at the meeting. new Intl.NumberFormat('en', { minimumSignificantDigits: 2, maximumSignificantDigits: 2 }).format(0.03) produces the value I'd expect: "0.030". It's not "0.0". |
| 17:20 | <ptomato> | right, I have never heard leading zeroes counted as significant digits, except in 0 itself |
| 17:30 | <eemeli> | Huh, you're right, I should've checked this more thoroughly. My position here is that the understanding of "significant digits" in Amount should match the existing understanding that's in Intl.NumberFormat and in Number.p.toPrecision(), whatever that might be. |
| 17:54 | <Richard Gibson> | I belive that is inconsistent, e.g. (450).toPrecision(2) is "4.5e+2" while new Intl.NumberFormat('en', { minimumSignificantDigits: 2, maximumSignificantDigits: 2 }).format(450) is "450" |
| 18:00 | <Aki> | Remember, notetaking way chill now |
| 18:00 | <Aki> | you just have to make corrections |
| 18:02 | <Michael Ficarra> | 🙏 please take notes, I have to catch a flight! |
| 18:03 | <Justin Ridgewell> | Joke joke joke! |
| 18:04 | <nicolo-ribaudo> | Rob Palmer: I see TCQ on "lunch" |
| 18:05 | <Rob Palmer> | There was a setTimeout on the joke. The offer expired. It may return at a future call for notetakers. |
| 18:06 | <eemeli> | I don't see an inconsistency here, as Intl.NumberFormat only formats with exponential notation if you ask for it:
|
| 18:06 | <nicolo-ribaudo> | Lol I thought MF picked space case just to cause controversy, while waiting for us to decide on the only two possible reasonable options |
| 18:07 | <waldemar> | kebab-case outbreak? |
| 18:12 | <Michael Ficarra> | use cases include running/continuous computations, pairwise comparisons, carousels, ... |
| 18:13 | <bakkot> | carousels want undersized but the others mostly want only-full |
| 18:13 | <bakkot> | and a "real" carousel is usually infinite so it ends up not mattering |
| 18:14 | <bakkot> | also reminder to everyone to fill out summary / conclusion |
| 18:14 | <bakkot> | also also good job Michael Ficarra doing that fast despite attempts at more bikeshedding |
| 18:17 | <Zb Tenerowicz (ZTZ/naugtur)> | .concat? |
| 18:17 | <nicolo-ribaudo> | concat always gives you a new array though |
| 18:17 | <nicolo-ribaudo> | Sometimes I want to mutate (often) |
| 18:18 | <bakkot> | I suspect the quadratic behavior is not actually plausible; every impl I have seen doubles the size when it hits capacity which keeps overhead at most ~log~ constant |
| 18:18 | <Zb Tenerowicz (ZTZ/naugtur)> | let + .concat is what I used to do |
| 18:19 | <Zb Tenerowicz (ZTZ/naugtur)> | It is horribly easy to forget to reassign tho |
| 18:21 | <Ryan Cavanaugh> | "it runs fine in JSC" -> speaks to the criticality of it, right? You can run your tests in one runtime and then crash in a user browser |
| 18:22 | <Ryan Cavanaugh> | Re Jordan, not all data processing occurs over a network |
| 18:22 | <bakkot> | "I am skeptical that large arrays are common" is... a claim |
| 18:23 | <Richard Gibson> | ljharb this also came up in jQuery DOM manipulation, in which there is no "wire" |
| 18:24 | <rbuckton> | At one point in the array slice notation proposal, I'd suggested a splice mechanism as well, i.e.:
|
| 18:24 | <nicolo-ribaudo> | I like .splice 😬 |
| 18:24 | <nicolo-ribaudo> | (but yeah we don't need the other ones) |
| 18:24 | <bakkot> | it's awkward to use but it does a specific thing which needs to be done |
| 18:25 | <bakkot> | it's true that if we have spliceFrom then we don't need pushFrom |
| 18:26 | <kriskowal> | It’s true that spliceFrom is the only mutative method an array ever needs. Everything else is for ergonomics. |
| 18:26 | <ljharb> | (ignore, matrix blip) |
| 18:26 | <rbuckton> | Not being add prototype methods to array is constantly frustrating. Maybe we need a new List type we can use in place of Array |
| 18:27 | <kriskowal> | Though arguably, only applyOperationalTransform would be more general than spliceFrom. |
| 18:27 | <Ryan Cavanaugh> | I've written a lot of code that operates in the range where sharding is not needed but .push(...arg) fails |
| 18:28 | <nicolo-ribaudo> | We added the .to* ones. It's difficult but possible |
| 18:28 | <Ruben> | I think the problem is that it happens in production when it causes actual issues that are difficult to forsee. No matter that I agree that it's better to chunk, I think this is going to prevent applications from crashing badly. |
| 18:28 | <Michael Ficarra> | sorry, I pressed the done speaking button! |
| 18:29 | <kriskowal> | I had to rewrite a binding library to compensate for RangeError over splice in terms of a userspace spliceFrom in order to propagate changes that included initialization from as few as 10k values, about ten years ago. |
| 18:29 | <kriskowal> | (I called userspace spliceFrom swap) |
| 18:29 | <Ryan Cavanaugh> | Like would anyone support saying that we should throw if push(...args) has args.length >= 10? No, right? But we're saying throwing at a nebulous unspecified number is fine |
| 18:31 | <bakkot> | the example from the slides fails for me in Safari |
| 18:31 | <bakkot> | I guess maybe there's an optimization which I don't have yet? |
| 18:31 | <Michael Ficarra> | @Ryan Cavanaugh the spec assumes unlimited resources, there's violations like this all over the place |
| 18:32 | <rbuckton> | While its not necessary to tie to this proposal, I'd love to see a Set.prototype.addAll (or .addRange), i.e., a mutating union, in the same fashion as pushAll |
| 18:32 | <Zb Tenerowicz (ZTZ/naugtur)> | .conpcat would be consistent with splice 🙈 |
| 18:32 | <bakkot> | (instead of specifying Array specially here we should just freeze ArrayIterator :D ) |
| 18:34 | <keith_miller> | Oh I ran it in our CLI. Maybe it's different in the browser |
| 18:35 | <bakkot> | the current state of the art is people getting RangeErrors in production |
| 18:36 | <Michael Ficarra> | @eemeli https://github.com/DanielRosenwasser/proposal-array-push-all/issues/5 |
| 18:37 | <Michael Ficarra> | they'll still do that, there's just an ergonomic way to do the right thing that their editor will suggest to them |
| 18:38 | <bakkot> | I'm on 17.6, which is quite old, because I refuse to update my computer because Apple keeps making the OS worse every time I update it |
| 18:38 | <bakkot> | so it's reasonably likely there's a new optimization I'm missing |
| 18:39 | <nicolo-ribaudo> | An infinite array! |
| 18:40 | <bakkot> | fwiw I would guess
|
| 18:40 | <rbuckton> | If we optimize ar.push(...ar2), we still have the issue with ar.push(...ar2.values()) (or any other iterator generated over a large array) |
| 18:41 | <Michael Ficarra> | I'm sure the spec already answers the question of mutating an array as it is iterated |
| 18:41 | <rbuckton> | That wasn't what my comment was about. |
| 18:42 | <Ryan Cavanaugh> | ".push(...arr) crashes but only on Suchandsuch browser" is the worst-case scenario |
| 18:42 | <rbuckton> | I'm more stating that having engines work around ar.push(...otherArray) only solves the problem for arrays, not for arbitrary iterators. |
| 18:42 | <keith_miller> | I can't think of any optimizations that would have changed the behavior here remotely recently but maybe there's something |
| 18:43 | <keith_miller> | It's version 26 now so you're way behind :P |
| 18:45 | <nicolo-ribaudo> | Note that whether ... works doesn't depend only on which engine you are in, but also on how deep you are on the call stack |
| 18:45 | <Ruben> | Would it be a better idea to change the spec that the limit for .push(...array) is removed or defined to a specific upper bound? |
| 18:45 | <Ryan Cavanaugh> | "It should be straightforward and safe to add elements to an existing target array" |
| 18:45 | <bakkot> | there is no limit in the spec |
| 18:46 | <bakkot> | spec does not believe in stack size limitations |
| 18:46 | <Ruben> | there is no limit in the spec |
| 18:46 | <Michael Ficarra> | ➕️ also change the proposal name to reflect the problem statement before transferring to tc39-transfer |
| 18:46 | <rbuckton> | As far as how to handle ar.push(...ar) (or ar.push(...ar.values())), I would support that just exhausting resources and throwing rather than special casing, considering we also do that for for (const e of ar) ar.push(e); |
| 18:46 | <bakkot> | you can write down whatever you want but implementations are unlikely to start requiring unbounded hardware to run |
| 18:47 | <bakkot> | that is: there will always be a limit |
| 18:47 | <kriskowal> | And there will never be a limit that is the right size for every job |
| 18:50 | <Ruben> | that is: there will always be a limit |
| 18:52 | <bakkot> | there's lots of JS implementations which run on less than 4gb of memory, so even that would be violated in practice |
| 18:52 | <bakkot> | but yes, we could. in practice I suspect implementations would not want to rewrite their calling conventions to make that work |
| 18:52 | <nicolo-ribaudo> | Zb Tenerowicz (ZTZ/naugtur): I think you have some option that turns aaa into monospace aaa. Could you try disabling it? |
| 18:58 | <bakkot> | https://github.com/microsoft/TypeScript/issues/8240 |
| 19:03 | <nicolo-ribaudo> | Rob Palmer (I had an <EOM> point of order). Can you ask for new note takers? Or, I see maybe it's not needed? |
| 19:11 | <iain> | For the record, this is false in SM. We collect spread-called arguments into an array (with a fast-path for spreading an existing dense array) before pushing them onto the stack. If we optimized Array.push to avoid stack overflow (which we already do with Math.min/max), that would fix the problem for arbitrary iterators, not just arrays. |
| 19:20 | <iain> | There are other builtins (Math.min/max, String.fromCharCode, ...) where similar problems arise. Adding a new variant for each of those seems unwieldy. I wonder if it would be sufficient to have a note listing specific functions that are expected to take a large number of arguments, with a Strong Recommendation that engines should consider optimizing them to avoid stack overflow. |
| 19:21 | <bakkot> | fwiw I have actually been intending to pursue adding new variants for at least those specific functions |
| 19:21 | <keith_miller> | FWIW, this does throw if you change it to 200_000_000 for me too |
| 19:23 | <bakkot> | not Object.assign or the Function constructor or .bind/etc, probably not String.prototype.concat, and I think that's the whole list? |
| 19:24 | <bakkot> | undecided on Math.hypot |
| 19:27 | <mgaudet> | Mathieu Hofman: I'll need your help to validate if we're capturing what you are looking for, but we have thenable instrumentation already; -- the basic gist here being that -when- we look for "then" we track where the thenable came from; was it an own property, on a standard prototype, or on object.proto. Notably we don't report for Promise.prototype.then |
| 19:30 | <mgaudet> | Reflect.ObjectIsNativePromise |
| 19:30 | <iain> | I can't speak for other vendors, but from SM's point of view, if it's just this handful of functions, it would be a day or two of work to implement. |
| 19:31 | <Olivier Flückiger> | I am actually not sure if we have precedent for such an optimization or if it would be a larger change to calling conventions in v8. |
| 19:32 | <Olivier Flückiger> | But in general it seems more invasive to add this as a blanket capability. |
| 19:33 | <Olivier Flückiger> | given thus far stack overflow is purely implementation defined |
| 19:33 | <hax (HE Shi-Jun)> | What isThenable should be? just typeof p.then == "function" ? |
| 19:33 | <ljharb> | p &&, but yes |
| 19:33 | <kriskowal> | You mean it would be invasive in general to divert large variadic arguments to the heap? (I would assume so) |
| 19:34 | <kriskowal> | Though, I suppose you might mean that in some specific cases, just not copying to the stack or heap is an optimization that might work. |
| 19:34 | <bakkot> | (typeof p === "object" || typeof === "function") && p !== null && typeof p.then == "function", primitives aren't thenable |
| 19:35 | <bakkot> | (this assumes that if someone puts .then on document.all then the computer will set itself on fire in self defense) |
| 19:36 | <Olivier Flückiger> | that is a possible implementation strategy, but I guess we would not spec it with these words. but rather something like "should not fail if creating such an array does not fail". |
| 19:36 | <Olivier Flückiger> | but if you add that as a "capability" for calls it essentially means that every engine needs a generic implementation that can support that. (and that is what I meant by invasive) |
| 19:36 | <Andreu Botella> | can we specify this? |
| 19:37 | <Justin Ridgewell> | :halt-and-catch-fire: |
| 19:38 | <ljharb> | sure - items with the isHTMLDDA internal slot can have a custom internal [[DefineOwnProperty]] that normatively requires the program to terminate if the key is "then", right? :-p |
| 19:43 | <Olivier Flückiger> | personally I actually like the idea of making push(...x) "just work". but I need to figure out if we would want the implementation. |
| 19:48 | <Mathieu Hofman> | I believe this is necessary but not sufficient. The case we're concerned about is when the resolution is a native promise. So basically we need the existing GetThenValue instrumentation, but also add a check after .then is found whether IsPromise(resolution) is true. Only on those native promises, we're concerned with .then found that comes from an unexpected place. |
| 19:49 | <mgaudet> | Ok. Let me open a bug -- I can't promise I'll get to this shortly but we'll see if someone else (perhaps a volunteer) can do so |
| 19:51 | <Mathieu Hofman> | Happy to add details to the issue. I assume we need new instrumentation for the .constructor check in PromiseResolve too |
| 19:53 | <mgaudet> | I actually have to run unexpectedly, so I just dumped what I had here: if you could expand, we can see who can maybe pick this up: https://bugzilla.mozilla.org/show_bug.cgi?id=1990075 |
| 19:53 | <mgaudet> | Thank you very much! |
| 20:08 | <bakkot> | unrelated to the meeting today, I suspect many here will be interested in this project, an object-capabilities-based RPC library for the web, including in particular pipelining https://blog.cloudflare.com/capnweb-javascript-rpc-library/
which rhymes with https://github.com/tc39/proposal-wavy-dot |
| 20:44 | <Richard Gibson> | this came up in real time as well, but
|