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:

new Intl.NumberFormat('en', { minimumSignificantDigits: 3, maximumSignificantDigits: 3 }).format(0)
// "0.00"
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:

new Intl.NumberFormat('en', { notation: 'scientific', minimumSignificantDigits: 2, maximumSignificantDigits: 2 }).format(450)
// "4.5E2"
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.:

ar[^1] = x; // set at ar.length-1
ar[^0] = x; // set at ar.length (i.e., push)
ar[^1:]; // get slice from ar.length-1 to end
ar[^0:]; // get slice from ar.length to end (e.g., empty)

ar[^0:] = ar2; // splice ar2 into ar at ar.length
ar[^1:] = ar2; // splice ar2 into ar at ar.length - 1
// etc.
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 pushFrom would be web-compat, https://github.com/search?q=%28language%3Ajs+OR+language%3Ats%29+%22.pushFrom%28%22&type=code

group had a conflict because it was a name you might put on other objects, and flatten had a conflict because it was an obvious name to use, but pushFrom is a pretty weird name to use unless you are following our language convention of "from = iterable"

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
I meant to make it explicit that this should not happen 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
It could be the array bound. That way, it would be consistent (while having an issue if the array already contains elements and would therefore overflow)
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/

When you start an RPC, you get back a promise. Instead of awaiting it, you can immediately use the promise in dependent RPCs, thus performing a chain of calls in a single network round trip.

which rhymes with https://github.com/tc39/proposal-wavy-dot

20:44
<Richard Gibson>

this came up in real time as well, but isThenable in general is ill-advised because Promises/A+ requires a single Get of "then". So really you'd need something else anyway, e.g.

const snapshotThenable = value => {
  const then = !isPrimitive(value) && value.then;
  if (typeof then !== "function") return undefined;
  return { then: (...args) => Reflect.apply(then, value, args) };
};