00:50
<Rob Palmer>
Good morning, all!
00:53
<Rob Palmer>
We're kicking off the meeting in 7 mins!
00:54
<Rob Palmer>
Could anyone dialling in one teams give us feedback on the AV?
01:01
<Rob Palmer>
We believe AV is all good
01:09
<Justin Ridgewell>
We really have to change my image in these slides.
01:21
<ljharb>
JS already has a logo, we should use it
01:24
<Michael Ficarra>
as a picture for Justin?
01:40
<bakkot>
why is iana un-deprecating timezones?
01:40
<rkirsling>
I too would like to know
01:41
<rkirsling>
does this make this the Hell Freezes Over meeting
01:41
<Chris de Almeida>
THE PEOPLE YEARN FOR AN UPDATED ECMA-404 SPEC
01:41
<Richard Gibson>
it's the question on everyone's mind
01:42
<Andrew Paprocki>
 The backward-compatibility names EST5EDT, CST6CDT, MST7MDT, and
 PST8PDT now conform better to POSIX.  For example, EST5EDT now
 always uses the abbreviation "EST" for standard time (now always 5
 hours behind UT) and "EDT" for daylight saving time, whereas it
 formerly had different UT offsets before standard time was
 introduced and sometimes used abbreviations like "LMT", "EWT" and
 "EPT", all contrary to POSIX.  Also, though not required by POSIX
 these names now use US federal rules rather than rules of places
 like New York, reverting to 2024a behavior.  This change affects
 only timestamps before 1966-10-30 at 01:00 standard time.
01:42
<Michael Ficarra>
well we are discussing PTCs again, so definitely yes
01:42
<ljharb>
the intl enumeration is just strings?
01:42
<Richard Gibson>
now introducing Crystal JSON™️
01:43
<Andrew Paprocki>
They make these pedantic changes and cause untold hours of agony as issues spread through downstream packages
01:43
<Andrew Paprocki>
Can't tell you the number of hours wasted already on 2026d
01:48
<Rob Palmer>
Jarred Sumner is experimenting with AOT JS citing performance, memory, user benefits at the expense of binary payload size.
01:49
<Michael Ficarra>
@Rob Palmer my exasperation was that the microphones also take forever to turn on
01:50
<Chris de Almeida>
deferred power evaluation
01:52
<rkirsling>
just gotta take a quick beat
01:52
<rkirsling>
"and ONE"
01:55
<Andrew Paprocki>
amplification dead zone
02:11
<Ashley Claymore>
+1 keith_miller could you say more about why transfer AB is considered deprecated? (Just curious)
02:13
<keith_miller>
When a page transfers ArrayBuffers it causes all(?) engines to perform worse because every access has to validate the buffer isn't detached
02:13
<keith_miller>
This is independent of which buffer is detached
02:14
<Olivier Flückiger>
We can now detach buffers without the protector.
02:14
<Olivier Flückiger>
If you only have a single typedarray on top of it.
02:14
<Ashley Claymore>
Would you suggest SharedArrayBuffers instead?
02:15
<rkirsling>
this bug involves a head-spinning combination of constructs for me 😂 (spoken as someone who's never used the Atomics API)
02:15
<keith_miller>
How do you know they don't alias the view somewhere?
02:15
<keith_miller>
Or do you mean ArrayBuffer with no attached views?
02:15
<Olivier Flückiger>
buffer with strictly less than 2 views attached
02:16
<Olivier Flückiger>
Basically we keep a back-ref to the views with is: None | One(view) | Many
02:17
<Olivier Flückiger>
If it's just one view we can mark just that one as detached without firing the global protector.
02:18
<rkirsling>
(sorry I read it more slowly and get it now)
02:23
<Richard Gibson>
thanks; it is so difficult to accurately describe the scenario in prose
02:25
<keith_miller>
I think you're running in our state that's when the protector fired.
02:27
<keith_miller>
We assume the length is constant (for non-resizeable buffers anyway), which is what the protector protects
02:29
<Olivier Flückiger>
yes, same.
02:30
<keith_miller>

How do you do the increment without a length check?

  for (let i = 0; i < view.length; ++i) {
      if (i == 100)
         view.transfer()
      view[i]++;
  }
02:30
<keith_miller>
JSC emits no length check
02:30
<Olivier Flückiger>
the typed array itself changed to a special detached typed array map
02:30
<Olivier Flückiger>
so we deopt once you detach
02:30
<rkirsling>
wild getting to this right in the first morning
02:31
<Olivier Flückiger>
but by a type assumption, not by a global protector
02:33
<Ashley Claymore>
Only a 1 line change
02:35
<Jesse (🇯🇵)>
the best kind of change
02:38
<bakkot>
it is true that PTC being in the spec has caused some of the people writing new engines to add PTC, and I think that's good
02:38
<rkirsling>
it's hard to jump in with this but I feel like the argument can be made that even under the current process, this would be a case of "getting stuck upon implementer feedback"
02:39
<rkirsling>
it actually surprises me that none of the other engines in eshost have though 🤔
02:39
<Justin Ridgewell>
I hear Mark
02:40
<ljharb>
what would be the benefit of adding it if very little code is written to support it because it's not usable on every browser?
02:44
<Michael Ficarra>
this is true, but to be fair I have also witnessed someone working on a compiler that targets JavaScript assuming that JS had PTCs, only to find out much too late that it wasn't actually the case, which is really unfortunate
02:44
<bakkot>
oh yeah that sucks
02:45
<Michael Ficarra>
(I still support keeping them in the spec)
02:49
<Ashley Claymore>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Execution_model#tail_calls does mention the browser compat
02:52
<Ashley Claymore>
I'd like to hear from more implementers in this discussion if possible :D
03:00
<Michael Ficarra>
those 2016 objections had very good responses from MLS, and it's a shame we did not get to hear them as well
03:01
<Chris de Almeida>
fair but I was only answering the query about why they didn't implement
04:05
<rkirsling>
runtime SyntaxError is so gross
04:07
<ljharb>
imo it's perfect when it's about invalid syntax :-) it's not "JavaScriptSyntaxError", so it can apply to anything
04:11
<Chris de Almeida>
really gotta admire the thoughtfulness on even little things from our Sony hosts 🙌
04:12
<Richard Gibson>
for reference, it shows up in places like JSON.parse("x") and BigInt("x")
04:13
<Ashley Claymore>
and new Function :D
04:14
<rkirsling>
yeah eval was the main case I was prepared to view as an exception
04:14
<rkirsling>
I guess JSON.parse makes sense too...at which point I guess you can make the case for any parse error
04:15
<rkirsling>
but I guess I wish we had a ParseError
04:15
<bakkot>
but not decodeURIComponent("%")! for some reason
04:15
<ljharb>
tbh there's a lot of subtypes it would be nice to have that would make way more sense than whatever error type an arbitrary step usually throws
04:15
<Michael Ficarra>
btw I do not share @ljharb's opinion that these things are "the right type", as JS is unityped, so no value is a wrong type
04:15
<Jesse (🇯🇵)>
did we forget RefernceError?
04:15
<Michael Ficarra>
I didn't think it was worth spending plenary time on though
04:15
<ljharb>
typeof exists, JS doesn't just have one type
04:16
<ljharb>
by any definition of "type"
04:16
<Lea Verou>
Also RegExp()
04:16
<rkirsling>
typeof is just "which branch of the variant / tagged union are we in" though
04:16
<bakkot>
... apparently HTML actually throws DOMExceptions whose .name is SyntaxError, but throws real TypeErrors, for some unimaginable reason
04:17
<ljharb>
JS values aren't a tagged union, so i'm confused by this
04:17
<bakkot>
try { (new CustomElementRegistry() ).define(' ', function(){}) } catch (e) { e instanceof SyntaxError } // false
04:18
<rkirsling>
I'll let Michael come up with a more satisfying phrasing then :p
04:18
<bakkot>

ok, from webIDL:

A simple exception is identified by one of the following types:
EvalError
RangeError
ReferenceError
TypeError
URIError
These correspond to all of the JavaScript error objects (apart from SyntaxError and Error, which are deliberately omitted as they are reserved for use by the JavaScript parser and by authors, respectively).

04:19
<bakkot>
(of course this is missing AggregateError and SuppressedError but those are kind of special)
04:20
<peetk>
from the perspective of implementations they are
04:20
<Michael Ficarra>
I can almost guarnatee you that implementations are using a uniform representation
04:20
<ljharb>
they certainly might be. but that's irrelevant to JS practitioners, it's just an implementation detail
04:21
<Lea Verou>
DOMException is such an abomination, I wish we could kill it with 🔥 😕
04:21
<Michael Ficarra>
they only due that because the language doesn't treat those as distinct classes of values
04:22
<rbuckton>
A TypeError is for when the incoming value does not belong to the category of input types (category theory), like passing in a string when a number is expected, or a method for one class being called with another class instance. RangeError is usually reserved for something that is outside of a range of a set of unit values (specific strings, numbers, etc.)
04:22
<Christian Ulbrich>
I never differentiate on built-in errors, but catch any error and throw custom ones, that I can differentiate on.
04:23
<peetk>
in this conception, is the critical distinguishing factor finiteness of the set? because "not a number" or "not a string" could also be said to be a case of the value not being in the set of allowable values
04:23
<Michael Ficarra>
typeof is not an argument for these being distinct "types", any more than function numericType(n) { return n < 0 ? 'negative' : n > 0 ? 'positive' : 'zero'; } defines three distinct "types"
04:23
<Ashley Claymore>
I have seen code switch on the Error message, which is even more scary
04:24
<Christian Ulbrich>
I would not expect the error message to be actually standardized, are they? :)
04:24
<Ashley Claymore>
They are not
04:25
<ljharb>
ha, i once broke every user of angular-cli and ember-cli by changing an error message in resolve
04:25
<Ashley Claymore>
https://grep.app/search?q=err.message.includes
04:25
<Jesse (🇯🇵)>
at runtime: "Jev, we are in an error state of a JavaScript program. The error message is: MESSAGE. Which category of error is this?"
04:25
<rbuckton>
Roughly, yes.
04:25
<rbuckton>
except that string vs number are distinct categories of values.
04:29
<peetk>
then that seems like a very reasonable criterion even if it is not the one currently encoded by the spec
04:29
<rbuckton>
A RangeError generally means you are outside the range of a finite set of unit values.
04:32
<Jesse (🇯🇵)>
I might extend that a bit and use RangeError for being inside a finite range of disallowed values (e.g., empty string is bad, but all other strings are fine)
04:32
<bakkot>
1n ** -2n // RangeError
04:32
<bakkot>
so... no?
04:32
<Andrew Paprocki>
What about IANA time zone identifiers?
04:32
<Jesse (🇯🇵)>
or: 0 and -0 are bad, but all other Numbers are fine
04:33
<Andrew Paprocki>
"Asia/Tokyo" is in the set but "Asia/WTF" is not. Is that a "range"?
04:34
<rkirsling>
I guess that's sort of a question of whether a range implies an ordering
04:35
<ljharb>
Jesse: "NaN is fine"
04:35
<bakkot>
I do have a strong intuition that RangeError is correct for 1n ** -2n
04:35
<bakkot>
couldn't tell you why though
04:36
<Nikolaos Papaspyrou>
I believe we wouldn't have all this discussion if RangeError was ValueError, like in Python... :-)
04:36
<rkirsling>
I mean it's basically saying that BigInts aren't closed under **, so that seems rephrasable as "you can end up out of range"
04:38
<bakkot>
mm, technically yes but that one does not end up out of range
04:38
<peetk>
ig my intuition is RangeError is for when you're not in some set, where that set is not just "things of type X" for some X (for some folk definition of "type" that michael may disapprove of)
04:38
<bakkot>
so it's really that the input is not in range
04:39
<bakkot>
I don't really understand how people are using the word "type" in a way that is different from "set of values"
04:39
<rkirsling>
yeah like, my agreement that "JS is unityped" is kind of irrelevant to the actual discussion in my view. it's fine if TypeError just means "wrong wrt typeof"
04:40
<peetk>
the types are string, number, object, bigint, symbol. that's what everyone means
04:40
<ljharb>
"odd numbers" is not a type. "numbers" is a type. is it really that confusing?
04:40
<bakkot>
ljharb ... yes? I don't know how those things are different for you
04:40
<bakkot>
I'm not being obtuse, I genuinely do not understand what makes those different to you
04:41
<peetk>
those are the types. typeof names them
04:41
<ljharb>
typeof and TypeScript and common intuition all treat those as different
04:41
<ljharb>
"odd numbers" is a subset of the "numbers" type.
04:41
<ljharb>
so if something is not a number, it's a type error. but if it's a number that's not odd, it's a range error
04:42
<bakkot>
pretty sure I could make a "only odd numbers" typescript type, and to the extent I couldn't it would be because of mechanical limitations in the compiler, not, like, fundamental facts about ontology
04:42
<Ashley Claymore>
We also throw a TypeError when the value doesn't quack like the expected interface
new Set().union({}) // TypeError
04:42
<peetk>
it's just typeof
04:42
<ljharb>
(also no, p sure you can't make an only "odd number" TS type, nor an "integer" TS type, but that's more fundamental limitations of TS than an argument one way or the other) (if you can, please tell me how, because i'd love to use that type)
04:44
<Jesse (🇯🇵)>
I thought you could do anything with TS types using branded types?
04:45
<ljharb>
there's tons of limitations. "a finite number" can't be represented, for example. nor can -0 (or "not -0")
04:45
<bakkot>
that is a reasonably answer but doesn't seem to actually match how we've been using the terms? for example, object.#foo on an object that doesn't have a #foo field is a TypeError, and that feels correct to me; do you think that ought to be a RangeError?
04:45
<rkirsling>
okay so "wrt typeof or instanceof" maybe (... in a world where instanceof weren't stupid, that is)
04:45
<ljharb>
that's a case of "we don't have a better error class than TypeError for this case"
04:46
<bakkot>
hm, ok. that one feels right, to me, because the error is "you tried to access this field on an object of the wrong type". but you do not think of it like this?
04:46
<Ashley Claymore>
TypeError -> "I can't do the operation I need to do with this value"
RangeError -> "I could do the operation but I won't like the result"
04:47
<ljharb>
i do, because "a class instance" is a kind of type. but since we don't have a "WrongInstanceError", TypeError works
04:47
<peetk>
yea ok fair. let's say "typeof type or instanceof type"
04:48
<ljharb>
tbc, just because it's hard to verbalize a rule that works in every case does not mean there's not an intuitive distinction to be made.
04:49
<bakkot>
union expect as its argument something with keys and has and Symbol.iterator, not a Set specifically; it doesn't work off of instanceof (this was the outcome of very extensive discussions)
04:50
<bakkot>
it's about an abstract interface, not a typeof or instanceof type
04:50
<ljharb>
true but in a world with first-class protocols, it'd be a "SetLike" protocol
04:50
<rkirsling>
whoops
04:50
<rkirsling>
yeah
04:50
<Christian Ulbrich>
obviously its more philosophical or structural vs. nominal typing. Disjunct types would be TypeErrors, but in structural type systems with bad types, things are not so easy a type error, if you assume TypeScript types as a proper Type System for JavaScript (which it is not), there are many types, which are too broad, i.e. a string where it would be just a union of string literals.
04:52
<peetk>
we are slowly converging on the correct definition of "type"... or "schmype" or whatever we want to call it
04:52
<ljharb>
tÿpe
04:52
<Jesse (🇯🇵)>
do what the philosophers do: "kind"
04:53
<peetk>
i think philosophers will agree at lot less than us about what any given word means
04:53
<Jesse (🇯🇵)>
or in category theory and some PLs that borrow from that literature (e.g., Lean): "universe"
04:55
<rkirsling>
but kind has a fixed meaning in Haskell and "universe (of discourse)" is too "it means whatever we need it to" 😅
04:56
<rkirsling>
(sorry I'm taking this more seriously than necessary lol)
04:56
<peetk>
"ilk"
04:56
<Richard Gibson>
"landrace"
05:01
<bakkot>
https://www.typescriptlang.org/play/?ssl=18&ssc=1&pln=19&pc=1#code/C4TwDgpgBA8gJnAIgSwObOFAvFA5ARlygB88BmI03AVkrwHY7cBOXAbgCgPRIoBJAM7w4AGQwQATgEMANgB4AclAgAPYBAB2cAVA0BXALYAjSQD5sHKFAAGAEgDeCgL7XlazdpsOBwCcg2oTg64AHRMELhB9j5+AS5QAPxQAGayAhCWUABcXo7xqupaOnbRvv6BDsIo6MDxSb56GVY5qTLpnNzg0MIAshDGkgKKboWe+gMS5liZSgUeOnoaANYaAPYA7hqJUAAUgsJi6tLyCuZzRVAN0ElKORoQAG6SAJTZuo+SHTzQggCCGiA5AAVKZQAAMI3mUHwUAAZFAgdsrm9Wu0uN9YAhhucxoYTBJsLo8WYLFY-gDFGd3BdkUl7k8JJkcgBtBQAXUhF2Z9MkHLpH0ZzSgrI5OJ0zN6-XxQ1OfKgCiZ7wZHWSiwAxsBkKstsApEsIEIsbNqbiJqYdhocsJKc8ckp7FAJBBgHoJFsNGwoE50XqDcIdmRnp6APTBqCrJbcX2GuA7AAsQagoeUEgkq0ZQA
05:02
<bakkot>
cannot recommend actually doing this, but it does work; typescript's type system is quite powerful
05:02
<bakkot>
(as you say, this is not an argument one way or another)
05:03
<ljharb>
interesting
05:06
<Jesse (🇯🇵)>
IIRC it was examples like this that were part of the proof that TS's type checker is Turing complete
05:06
<Jesse (🇯🇵)>
so while "odd number" probably has no natural encoding in TS, it does have an encoding
05:07
<ljharb>
can you do the same trick with integers? that's the type i want :-)
05:09
<bakkot>
yeah just remove the ${OddDigit} from line 5
05:09
<Christian Ulbrich>
I think thats doable.
05:09
<bakkot>
https://www.typescriptlang.org/play/?#code/C4TwDgpgBAkgzjAdsCBzCAnAMgSxRgQwBsAeAOSggA8VEATOKRAVwFsAjTAPigF4AoKFAAGAEgDeZAL7DKNCPUZjxcYBhyJUUiQHIAdDqgAfKDog7tKtRq2yA-FABmxOBEFQAXCInTZ1WgzeVuqaMlAOasxuQl7ORK4A3Pz8oJCwyGiYALIQHJhw5HIBjCx5GDwCQhT+CoHMiADWiAD2AO6I4VAAFPBIKOjYeJjE5Dw1ilCR0A4UXogQAG6YAJSeTIuYSSng0PAAgoggJAAqFVAADEW1jACMUABkUMedU2txicmpuxkDheOBpU4GD4TDYQIq7n2h1GVwmrwc8yWGHcXgA2mQALqwwKoxGYLEIjbImJQdFY-6MVF9TIYHJlApkLgEqBkFHrJFbRz1ADGwBwzQ6wAIDQgCB+mD+8gmgO4XUQXmpv0Zyy8FHEUAwEGAzAwHUQCSgUk+wtFiswXQAzMsDQB6G1QZoNFImsX9c0AFmtUDtDqdQpFrppXXOegArF6fZgMM1kUA
05:09
<bakkot>
though again do not actually do this
05:10
<peetk>
can you make a type so big that even typescript can't lift it
05:11
<bakkot>
oh, also this version would need special handling for NaN and Infinity I guess
05:11
<Ashley Claymore>
I think there's an even easier way that is something like ${BigInt}
05:12
<ljharb>
that's easy, i've done that a lot
05:12
<ljharb>
i mean i'm definitely going to actually do this
05:12
<rbuckton>
type IsInt<N extends number> = `${N}` extends `${bigint}` ? true : false
05:13
<ljharb>
hm, i don't see how that'd work
05:14
<Ashley Claymore>
Need to apply that same trick to Kevins playground example
05:14
<bakkot>
doesn't work for large numbers
05:14
<dminor>
I have no problems with the delegates.txt name change for me, either Dan or Daniel is fine.
05:15
<bakkot>
also, moving this conversation to TDZ, sorry
05:21
<Chris de Almeida>
appreciate the feedback
05:22
<Chris de Almeida>
I am overall very positive on the tc39 data efforts from MF and JHD. all concerns I have are just about the details. thank you for doing this! 🙏
05:29
<bakkot>
Michael Ficarra: just in case I am asleep when you do the "Active proposals missing champions" topic (which is not scheduled until day 3) I want to keep destructuring-private active; I can champion it if we need someone to sign up to champion for it to be considered active
05:29
<bakkot>
it's an easy/obvious one imo
05:38
<bakkot>
petition to rename Proxy's "target" to "witness"; I think it is easier to think about how they work if you think about the purpose of the underlying object as being to prove that the Proxy is obeying the essential invariants rather than actually being the thing the Proxy is emulating
05:38
<bakkot>
(witness in the sense of https://en.wikipedia.org/wiki/Witness_(mathematics) )
05:42
<Aki>
I can't join the call from my phone, it just says "we couldn't complete the call". cmd+f doesn't work in element so I can't see if anyone else was having this issue.
05:42
<Jesse (🇯🇵)>
I think of "witness" in a mathematical sense as an object that makes an existential claim true
05:43
<bakkot>
yes, that is the sense I mean it in
05:43
<Michael Ficarra>
just you AFAIK
05:43
<bakkot>
you are exhibiting an object that has the same behavior as the Proxy, so it proves that the Proxy obeys the invariants as long as that object does
05:43
<Leo Kettmeir>
Michael Ficarra could TCQ maybe have the capability that anyone can request a temp check with everything populated and chair can see that & "approve" it which then actually triggers it? would prevent some of the chaos like we have experiencing today
05:43
<Chris de Almeida>
try private/incognito browser
05:43
<ljharb>
lol i asked for that out loud like 30m ago. great idea
05:44
<Aki>
I'm trying from my phone, only the app is supported. I tried not signed in and signe din.
05:44
<Jesse (🇯🇵)>
twin?
05:44
<Leo Kettmeir>
whoops i missed that
05:44
<Chris de Almeida>
https://github.com/michaelficarra/michael-tcq/issues/new/choose
05:44
<ljharb>
wasn't on the mic, no worries
05:44
<Leo Kettmeir>
even better: ill open a PR directly
05:45
<Michael Ficarra>
and this is exactly why I wanted to rewrite TCQ
05:45
<Chris de Almeida>
hell yeah
05:45
<Michael Ficarra>
so any of us could contribute, as if it was a real OSS project
05:46
<Chris de Almeida>
you gonna transfer to TC39 org or are you committed to BDFL'ing it?
05:47
<Michael Ficarra>
🤔 I haven't thought about it
05:47
<Michael Ficarra>
are you volunteering to take over hosting it too?
05:47
<Chris de Almeida>
if you need
05:48
<rkirsling>
BMFL. benevolent michael ficarra for life
05:48
<rkirsling>
oops not TDZ
05:51
<ljharb>
absolutely ecma should cover hosting
05:52
<Michael Ficarra>
even Ecma can afford $1.50/year in hosting costs
05:53
<Chris de Almeida>
big, if true
05:58
<bakkot>
I would expect this to fit comfortably in the free tier of something like cloudflare's durable objects
05:59
<Aki>
The thing that keeps me from having Ecma take over this manner of infra is just that there isn’t a role at Ecma with the knowledge and job description to manage it
06:00
<Michael Ficarra>
that is understandable but also kind of unfortunate because supporting committees often requires technological infrastructure
06:00
<Ashley Claymore>
+1 PR 12
06:00
<Christian Ulbrich>
I find it hard to follow discussion, but all I can say, I want to be Proxy to be transparent, i.e. not detectable if that means anything to anyone.
06:00
<Olivier Flückiger>
I think then we basically have to do PR12 (or maybe combo)
06:00
<Michael Ficarra>
like the Ecma members area (NAS under someone's desk in Switzerland)
06:01
<Olivier Flückiger>
given the conversation so far, that might be the best option.
06:01
<Aki>
It’s in an infomaniac DC
06:01
<Justin Ridgewell>
Mathieu Hofman: What was the weakmap virtualization response you wrote?
06:03
<Ashley Claymore>
Combo feels a tiny bit odd to me, as we are trying to say "non-extensible means you can't add private fields" but there is their period of time where we don't enforce it
06:04
<Ashley Claymore>
Wouldn't block it, but personally prefer PR12
06:07
<ljharb>
to my understanding, a proxy in the absence of a full membrane is only transparent if you're not trying to emulate a class whose instances have internal slots or the equivalent, whose methods you have direct access to
06:09
<nicolo-ribaudo>
Does Teams have something like Google Meet's companion mode?
06:09
<nicolo-ribaudo>
I thought it did but don't see a button for it
06:31
<Mathieu Hofman>
Mathieu Hofman: What was the weakmap virtualization response you wrote?
A proxy object on which you can always install private fields basically means we go back to the undeniable WeakMap for proxy objects. Unfortunately that's one of the type of objects we need to support, so it's a non starter for us.
06:32
<Mathieu Hofman>
Also any approach that unconditionally install or not install also creates a partial predicate for proxy objects.
06:32
<Olivier Flückiger>
combo would enforce it. it would just limit the number of traps
06:33
<Olivier Flückiger>
first trap, so proxy can say no. if the proxy says yes, then we proceed and only check the underlying object from that point on
06:34
<Olivier Flückiger>
but it is a bit odd, I agree. And given that it's complicated already...
06:35
<Mathieu Hofman>
For never install , it's the most egregious since most objects are extensible. And that's on top of the composition problem Mark tried to explain.
06:35
<Olivier Flückiger>
and it would mean we install private properties even though the proxy would say no now. so it basically has the same issue like what I named TG3 on my slides.
06:35
<Olivier Flückiger>
(in the case of proxies)
06:40
<waldemar>
What should we do with spam issues on GitHub? Report them or just close as not planned?
06:45
<Michael Ficarra>
Is it your own proposal's repo? I think you can do whatever you prefer, but we typically replace the title/body with [spam] and then close as not planned in tc39/ecma262.
06:45
<Leo Kettmeir>
https://github.com/michaelficarra/michael-tcq/pull/63
06:45
<Chris de Almeida>
we just edit the title+ description as [SPAM] and close as not planned
06:47
<Michael Ficarra>
okay I love the name "poll requests"
06:48
<ljharb>
also add an "invalid" label; that helps github's own spam classifier
06:50
<Michael Ficarra>
THEY HAVE A SPAM CLASSIFIER?!
06:51
<Michael Ficarra>
why don't they turn it on?
06:51
<ljharb>
it is turned on. they're just very hesitant about false positives. the spam we see is the stuff they don't catch (they do catch a lot, i'm told)
06:52
<ljharb>
although it's pretty weird for a proxy to start saying no during the installation of private methods, which is supposed to be an atomic operation, so it's probably ok that it can't do that?
07:00
<Michael Ficarra>
@Chris de Almeida I forgot @Richard Gibson is here lol.
07:00
<Michael Ficarra>
you all looked at me like I was the only one in the room
07:04
<Chris de Almeida>
tbf, I was looking at Peter
07:04
<Chris de Almeida>
and you are Peter-adjacent
07:06
<ljharb>
maybe v8 can make null objects not be slower?
07:06
<ljharb>
i'd think they should be faster since you don't need a prototype lookup
07:07
<ljharb>
oof, an object literal with __proto__:null is the only safe way to make one in JS :-/
07:08
<Richard Gibson>
https://adventures.nodeland.dev/archive/optimizing-objects-with-null-prototypes/ suggests that null-prototype objects can be fast in V8
07:08
<Richard Gibson>
Object.setPrototypeOf({ a, b, c }, null) is not in dictionary mode
07:09
<Olivier Flückiger>
Yeah, I will look into if we can deprecate the {proto: null} heuristic
07:09
<ljharb>
yeah but that's not syntactic, it depends on Object.sPO
07:09
<Olivier Flückiger>
I don't like it either...
07:09
<Olivier Flückiger>
Unfortunately I think websites rely on it.
07:09
<ljharb>
the article tho does imply that const o = { __proto__: null }; ({ __proto__: o }); might put it in fast mode?
07:09
<ljharb>
how could they rely on something being slow?
07:09
<nicolo-ribaudo>
__proto__: null -> dictionary mode ; __proto__: null, __proto__: null -> the other mode
07:10
<ljharb>
especially since it seems the other browsers don't have this problem
07:10
<ljharb>
ooh, so all my null object literals should double-mention dunder proto?
07:10
<nicolo-ribaudo>
Sorry I should have mentioned it in TDZ, it was a bad suggestion to allow people to opt out of dictionary mode without affecting those that wanted to opt in
07:11
<ljharb>
i mean if it works it's not a bad suggestion :-p it's just extra noop bytes
07:11
<nicolo-ribaudo>
And they'd get gziped away!
07:11
<ljharb>

like i'm literally going to make this change in all of my packages if it in fact works.

update: SyntaxError: Duplicate __proto__ fields are not allowed in object literals in strict mode :-(

07:12
<Olivier Flückiger>
ah, because it can also be slower of course to not go to dictionary mode
07:13
<Olivier Flückiger>
if the site e.g., does use the object as dictionary
07:14
<Olivier Flückiger>
This is probably from before we had Maps...
07:14
<Olivier Flückiger>
But I seem to remember that there was also something about objects being used as modules.
07:15
<Ruben>
I would expect that in most situations, the dictionary mode is not the favored form
07:15
<Olivier Flückiger>
I would not say that at all.
07:16
<Richard Gibson>
if nothing else, { __proto__: null, … } (i.e., with properties defined at initialization) seems less likely to be used as a dictionary than { __proto__: null }
07:16
<Olivier Flückiger>
If you truly do use the object as open dictionary, then tracking, and optimizing for, the current properties adds a lot of overhead.
07:17
<Olivier Flückiger>
ah, that is actually a good suggestion
07:17
<Ruben>
I would not say that at all.
I guess you have better data, it is more about code that I have seen using it
07:17
<Richard Gibson>
I have my moments
07:19
<ljharb>
i still don't understand how "an object can have any properties and you have to account for that" is made slower by "you don't have to look at a prototype chain"
07:22
<Olivier Flückiger>
{__proto__: false?{}:null}
07:23
<Olivier Flückiger>
(please don't :) )
07:23
<ljharb>
lol i just benchmarked it, it's slower than the : null one
07:23
<Olivier Flückiger>
the cost comes from the fact that any time you add a new property, then the internal type of that object changes
07:24
<Olivier Flückiger>
that has all kinds of possible ripple effects. code becomes invalid, pre-allocated object sizes being off, instances have to be migrated, etc...
07:24
<ljharb>
ok, but that's true with a normal object literal also
07:24
<Olivier Flückiger>
yes
07:25
<Olivier Flückiger>
it's a heuristic
07:25
<ljharb>
so in what scenario is "dictionary mode" ever faster?
07:25
<Olivier Flückiger>
sorry I don't understand. in the scenario I just said
07:26
<Olivier Flückiger>
you use an object as a dictionary
07:26
<Olivier Flückiger>
then dictionary mode from the start is better
07:26
<Olivier Flückiger>
and {__proto__:null} we currently treat as a signal that you are going to do that
07:27
<ljharb>
ah ok
07:27
<ljharb>
(btw i was measuring wrong; the false ? {} : null is actually fastest!)
07:28
<Olivier Flückiger>
since this heuristic is probably older than the addition of actual dictionaries to the language, it might not be a good heuristic nowadays
07:28
<Olivier Flückiger>
otoh, you can also find articles online where people did benchmarks and found out that using a Map is (or at some point was) slower than using a {__proto__: null} as a dictionary.
07:29
<Olivier Flückiger>
and thus argue to do the latter.
07:29
<Olivier Flückiger>
that is why it is kinda difficult to change such heuristics
07:30
<Aki>
EVERYONE CAN USE THIS TIME TO WRITE THEIR SUMMARIES AND CONCLUSIONS
07:30
<Aki>
(thank you to everyone who already has❣️)
07:31
<ljharb>
fwiw the fastest one that DCE wouldn't mess up so far is var NULL = null; var o = { __proto__: NULL }; - sometimes, it changes
07:31
<Chris de Almeida>
😳
07:32
<Aki>
sorry i had to yell to get past the din of the room
07:33
<Olivier Flückiger>
I guess it creates again an asymmetry where you could detect if the underlying object is a proxy itself or an object, depending on if it has this capability
07:34
<Olivier Flückiger>
I think as long as no implementer things that PR12 breaks their optimizations, it's better, since it's simpler.
07:38
<Michael Ficarra>
Unless that var is at the top level (creating a property of the global object), even a very dumb optimiser will inline that. Math.random() < 1 ? null : {} would be safer.
07:58
<Mathieu Hofman>
ah, that is actually a good suggestion
I suggested that on twitter the other day too. But couldn't tag you as I don't know your handle (if you have any)
07:59
<Olivier Flückiger>
twitter, what is that?
07:59
<Aki>
Thanks for the shout-out at the community event last night ♥️
07:59
<Aki>
(btw who shouted me out?)
08:02
<Chris de Almeida>
one of the local (non-TC39) presenters
08:03
<Chris de Almeida>
it was the talk on TC39 agent
08:03
<Mathieu Hofman>
FYI same for object create. If it has properties descriptors it likely won't be used as a dictionary
08:03
<Michael Ficarra>
@Aki https://github.com/tc39/notes/issues/423
08:05
<Mathieu Hofman>
But what surprises me the most is that for these these dictionary mode objects if the heuristic made a mistake, they never transition away from it (outside of the prototype tricks mentioned)
08:07
<Aki>
omg thank you linus i do not deserve that degree of credit 😱
08:08
<ljharb>
btw were the talks recorded last night?
08:08
<Chris de Almeida>
I know they were streamed, not sure if recording available
08:10
<Mathieu Hofman>
The combo is not as much a proxy predicate issue, but more of a membrane transparency issue, albeit a very weird one, so a lesser one than always piercing is.
08:10
<Aki>
(i do work hard on the notes, but not THAT hard)
08:10
<Mathieu Hofman>
But the thing is that the target may be a proxy itself. So you really need to recurse until you bottom out in a regular object
08:12
<Mathieu Hofman>
That complexity is likely not worth the simpler alternative: opt out of any optimizations if you are in a return override case.
08:12
<Mathieu Hofman>
I have no sympathy for anyone doing return override and expecting performance
15:54
<bakkot>
incidentally I was just looking at this same issue for node's sqlite results. node gets to use V8's API directly so I thought it would be able to avoid this by summoning objects of the correct mode from the void, but it turns out there's some bugs which make the approach I was looking at not work https://issues.chromium.org/issues/557521320 https://issues.chromium.org/issues/557938121
15:55
<bakkot>
(probably there is a better approach that would work but I gave up at this point)
21:06
<Mathieu Hofman>
I have a last minute scheduling constraint. Please let me know if it can or cannot be accommodated: https://github.com/tc39/agendas/pull/2167
21:06
<Mathieu Hofman>
And really sorry about that
23:03
<Chris de Almeida>
as per the above, the schedule has shifted around a bit