| 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> |
|
| 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?
|
| 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:
|
| 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 interfacenew 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> |
|
| 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? |
| 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: |
| 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. |
| 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 |
| 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 |