2024-02-01 [19:06:49.0007] what does a signals proposal mean? reading the angular docs about "signals" they don't appear to be anything special enough to need runtime integration [21:34:50.0662] i indeed was being salty from abortcontroller and observables and predicting a bad outcome for signals, and i know dan's got good motives here so hopefully it'll work out [21:35:25.0229] but pretty much every time someone's prioritized faster shipping over a better result it's ended up being a major wart, and it's frustrating that we collectively never seem to learn from those mistakes [10:44:39.0062] Opened https://github.com/tc39/proposal-shadowrealm/issues/396 and https://github.com/tc39/proposal-shadowrealm/issues/397 2024-02-02 [16:36:30.0709] That's really great mgaudet, I appreciate it! I'll have my team looking at it and if we have the chance we can discuss those around the plenary next week. [13:02:50.0028] gentle reminder to please add any and all schedule constraints as soon as possible [14:26:38.0653] Wow - we are now at 37 attendees for next week in San Diego! Please bring a brolly ☔ [14:27:49.0956] a what [14:28:02.0097] san diego is in america [14:53:14.0345] Alright alright. Please bring a bumbershoot ☂ 2024-02-03 [01:27:44.0558] (San Diego was home to Theodore Seuss Geisel, famous for “U is for Parasol”) [03:51:43.0923] I love how the style is so distinct that a simple drawing of an umbrella can be so obviously Seussian 2024-02-04 [21:26:31.0141] plenary schedule is up on the meeting reflector issue [01:44:53.0431] Reminder: We have a matrix room for those attending this week's meeting in-person in San Diego. We use this to organize things like taxis and where to eat. Please say if you would like an invite. 2024-02-05 [01:21:01.0713] FYI "iterator unique for stage 1" is on the draft schedule twice, just in case that is an accident [07:29:52.0686] It's too late for this meeting, but we should probably demote decorators from Stage 3 to the new Stage 2.7, since it has almost no tests (there are only a copule of syntax tests, but a huge part of the proposal is about runtime behavior) [07:43:48.0156] > <@aclaymore:matrix.org> FYI "iterator unique for stage 1" is on the draft schedule twice, just in case that is an accident thanks, fixed. not sure how that happened, as the timebox for the sessions were accurate. so no additional time freed up ☹️ [07:43:55.0295] > <@aclaymore:matrix.org> FYI "iterator unique for stage 1" is on the draft schedule twice, just in case that is an accident * thanks, fixed. not sure how that happened, as the timeboxes for the sessions were accurate. so no additional time freed up ☹️ 2024-02-06 [09:38:32.0395] Ok, the Zoom is now running for the plenary. Please could someone remote dial in so we can test AV. [09:39:29.0243] waiting for host to let me in [10:03:49.0060] please add your name to the top of the meeting notes [10:07:21.0480] for people on the opposite side of the room, can you hear Rob over the PA ok? [10:09:28.0925] yep [10:09:59.0151] splendid, thank you [10:19:42.0095] FYI this is replay.io if people are wondering [10:20:00.0464] Is it just me, or is the sound coming from the room very low? I had to turn up the volume on my speakers quiet high to hear, so I'm wondering if the gain on the microphones in the room is too low. [10:20:02.0636] also I want to call the TC for WinterCG "WinterTC" :) [10:20:43.0193] > <@rbuckton:matrix.org> Is it just me, or is the sound coming from the room very low? I had to turn up the volume on my speakers quiet high to hear, so I'm wondering if the gain on the microphones in the room is too low. not just you [10:21:28.0384] how would WinterCG standardisation in Ecma work? it's already in W3C [10:21:43.0347] also super excited for Sentry to join! [10:22:09.0505] Yes!! [10:23:02.0887] > <@michaelficarra:matrix.org> how would WinterCG standardisation in Ecma work? it's already in W3C similar to TC54 or Dart or C#: Technical development takes place in an open community forum (W3C WinterCG) and then the Ecma TC is responsible for reviewing, validating and standardizing just the parts of the work which are new APIs (and not upstreamed into other standards bodies), for example minimum common API, or a module-based raw socket API, etc. [10:23:42.0014] we know why [10:24:04.0934] * we know why _(reference to the ecma-262 access)_ [10:26:34.0177] not sure if Ecma is the best host for that work if they want actual web support. It might be challenging for WinterCG. I'd be interested to know what might not be working at W3C. [10:26:48.0066] * not sure if Ecma is the best host for that work if they want actual web support. It might be challenging for WinterCG. I'd be interested to know what may not be working at W3C. [10:27:36.0085] Rob Palmer: Can you have someone check either the mic gain in the room, or the input level of the room microphones to Zoom? I had to increase my volume to hear, which means if any other remote attendee speaks it will probably be far too loud. I think this is the source of the static remote attendees are hearing too. [10:28:13.0402] Zoom doesn't let me fine tune volume for volume for individual participants [10:30:44.0871] AV technicians have recommended rebooting the room. We will do that at the break. [10:30:56.0874] they did consider a W3C WG but opted for an Ecma TC instead, but I don't know how the discussion went [10:33:08.0669] it seems the full mics are much louder than the lapel mics... ? [10:33:35.0804] I truly hope they work towards inclusive Web support [10:34:44.0432] lapel mics are highly directional [10:34:53.0472] gotta be careful to point it directly at your mouth [10:35:04.0506] yeah I think you just need to basically eat them [10:35:15.0277] 😋 [10:35:15.0676] who is the Zoom host? [10:35:35.0160] i am [10:35:44.0946] i'm trying to join in prep for sharing slides at some point. it says waiting for host to let me in [10:36:46.0361] i'm in now, thank you very much [10:37:02.0520] done. sorry about the delay, we have a few co-hosts adimitting people [10:37:13.0595] Rod, Duncan, Chris, Ujjwal and I are Zoom hosts and we must let people into the Zoom. [10:37:39.0794] you can change that setting [10:37:52.0260] assuming that's undesirable [10:40:18.0814] sorry, we can't. company policy. [10:49:49.0912] rbuckton: i set the mics gain to the maximum, is it better? [10:50:22.0800] It still sounds very quiet. [10:50:33.0061] I don't think that changed anything. [10:50:54.0156] should check if the mic itself has a knob on it [10:51:48.0100] lapel mics should be hold closer to the mouth... btw, i have an extra mic here [10:52:32.0686] Shu's volume sounds good. [10:52:59.0802] shu has a big mic [10:53:17.0255] littledan: how do you think we should track addressing your feedback? do you want to open issues? [10:53:58.0106] Michael Ficarra: if the outcome of your topic was consensus, add that to the notes? we currently lack a conclusion/summary [10:54:10.0717] okay [11:05:28.0640] Was the microphone off when Dan Minor was speaking? I couldn't hear what was said. [11:05:33.0747] I also can't hear Rob [11:05:50.0820] stage 2 or 2.7? [11:06:12.0347] 2 [11:06:31.0080] IMO process-wise we *should* be using stages for these kinds of things [11:09:18.0560] sorry for jumping out of turn [11:09:19.0890] littledan: thanks for handling that clarification [11:09:29.0229] no, I appreciated it! [11:10:22.0443] > <@rbuckton:matrix.org> Was the microphone off when Dan Minor was speaking? I couldn't hear what was said. The microphone was on, but maybe I didn't hold it close enough. It's one of the lapel mikes. [11:10:54.0474] Could you hear Michael Saboff? [11:11:53.0190] I *thought* I could hear myself on the room speaker. [11:12:01.0890] should we do a tutorial on how to use a lav mic [11:12:11.0983] It seems like the lapel mics are turned down or aren't balanced properly with the handheld mics? lapel mics should be able to pick up your voice from 5-6 inches away (i.e., as if clipped onto the lapel or collar). [11:12:48.0714] I recall addressing the specific case of advancing directly from 2 to 3 when introducing stage 2.7 [11:13:28.0506] the correct way it to where it on your lapel [11:13:37.0336] * the correct way it to wear it on your lapel [11:13:47.0370] We have no rules forbidding advancing multiple stages in one meeting. No need to introduce one now. [11:14:57.0899] you can attach them to hats/wigs too [11:15:43.0632] * the correct way is to wear it on your lapel [11:19:09.0186] apparently yes, since I keep picking it up and talking into the antenna [11:22:03.0490] the battery pack? [11:22:54.0192] I am so happy the process document rewording was merged today [11:23:21.0547] it's great that you put so much work into clarifying things here! [11:23:56.0305] 😀 thanks [11:24:09.0397] the way we communicate, especially to the community, about our process is important [11:26:22.0606] I'm really happy about the shape of the API--it's a really intuitive extension [11:26:31.0764] * I'm really happy about the shape of the API for iterator sequencing--it's a really intuitive extension [11:27:24.0834] The discussion was on an open GitHub thread + in recorded meetings and open WinterCG Matrix chats [11:27:34.0091] it took place over many months [11:27:37.0055] if put on the lapel it would be even quieter... [11:27:55.0873] there will definitely be interaction with W3C, and technical development will continue to be in the W3C CG [11:29:10.0574] To summarize: Ecma is a very lightweight and agile place to publish a standard. Personally, I know how to work us through Ecma's processes. I understand W3C's process to involve a bunch of convincing people to approve a charter, repeatedly, which I don't feel like doing. [11:29:43.0838] See this thread: https://github.com/wintercg/admin/issues/58 [11:31:11.0564] Ecma is just an equally legitimate place to do work, and we will work to accommodate collaboration with everyone who wants to get involved [11:31:34.0711] there's no consistent layering separation between Ecma and W3C 😄 [11:34:38.0441] rust Iterator.flatten: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.flatten results in GH code search: https://github.com/search?q=.flat%28+language%3ARust+&type=code [11:38:02.0480] variadic `Iterator.append` sounds great to me [11:41:12.0898] `distinct()` is essentially `distinctBy(x => x)` [11:43:53.0316] I have a preference for comparator. Not every thing you would want to compare can be mapped into a natively comparable key. [11:44:29.0767] doesn't the comparator require quadratic time instead of nlog(n)? [11:45:20.0625] a comparator of `(a, b) => boolean` isn't efficient, but a comparator of `{ equals(a, b), hash(a) }` is more efficient [11:45:59.0801] about R&T: Sorry for it being stalled. Expect to see an update in committee some time this year. [11:48:11.0844] Given the way `groupBy` works, along with the most straightforward userland implementation using a `Set`, it is hard for me to imagine something more complex than a mapper. [11:49:33.0271] let me rephrase - I can imagine it, but I am drawn to the mapper :) [11:50:19.0979] rbuckton: Wait, how is that better than quadratic, still? Pairing a mapper with the comparator is *also* good for reducing the work in the comparator, but you still end up needing to compare everything to everything, no? [11:50:31.0912] no, you make a hash set internally [11:50:37.0403] I agree - a userland polyfill of this is trivial with a mapper, but less so with a comparator: ``` function* distinct(iter) { const set = new Set(); for (const val of iter) { if (!set.has(val) { set.add(val); yield val; } } } ``` [11:50:38.0218] Or are you imagining you only compare things that hash equal? [11:50:47.0696] * I agree - a userland polyfill of this is trivial with a mapper, but less so with a comparator: ``` function* distinct(iter, map) { const set = new Set(); for (const val of iter) { if (!set.has(val) { set.add(val); yield val; } } } ``` [11:51:06.0911] the mapper would compare with `===` or possibly `Object.is`, so yes, you only compare things that hash equal [11:51:07.0398] * I agree - a userland polyfill of this is trivial with a mapper, but less so with a comparator: ``` function* distinct(iter, map) { const set = new Set(); for (const val of iter) { const mapped = map(val); if (!set.has(mapped) { set.add(mapped); yield val; } } } ``` [11:51:15.0091] i.e. the thing luca wrote [11:51:31.0392] * the mapper would compare with `===` [modulo NaN] or possibly `Object.is`, so yes, you only compare things that hash equal [11:51:36.0576] * I agree - a userland polyfill of this is trivial with a mapper, but less so with a comparator: ``` function* distinct(iter, map) { const set = new Set(); for (const val of iter) { const mapped = map(val); if (!set.has(mapped)) { set.add(mapped); yield val; } } } ``` [11:51:38.0477] Examples of an equality comparator: https://esfx.js.org/esfx/api/equatable/equaler-interface.html#_esfx_equatable_Equaler_interface And its usage: https://esfx.js.org/esfx/api/collections-hashset/hashset.html#_esfx_collections_hashset_HashSet_class This is essentially what implementations do under the covers for `Map`/`Set` anyways. [11:51:54.0818] one of these days we should do System.hash(value) [11:52:28.0974] i thought shitposts go in TDZ :-p [11:52:45.0047] this isn't a shitpost :( [11:52:48.0548] > <@devsnek:matrix.org> one of these days we should do System.hash(value) Honestly, I'd love to have that. [11:53:55.0367] ah, there's tons of stuff on es-discuss from back in the day on why it's not an option, iirc [11:54:15.0233] altho maybe WeakRef and FinalizationRegistry changes the landscape there, not sure [11:54:21.0781] For some objects, its inefficient to convert the object into an existing comparable thing, or possibly even impossible to do so. [11:56:01.0027] A mapper seems more efficient when you only consider the comparison algorithm, but doesn't consider the cost of the actual `mapper` call. You are paying for both the comparison *and* serialization into a comparable format. [11:56:35.0110] An `{ equals(a, b), hash(v) }` comparator uses the object as-is and requires no serialization. [11:56:42.0818] > <@rbuckton:matrix.org> For some objects, its inefficient to convert the object into an existing comparable thing, or possibly even impossible to do so. What if we had something like https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey? [11:57:28.0353] you can't build custom collection types without something like hash [11:57:32.0597] Maybe cheaper than serializing into a string, but you are still allocating a wrapper and stuffing values into it purely for comparison. [11:58:56.0888] Implementations are already using hash-based comparators for JS collections internally. [11:59:17.0212] > <@devsnek:matrix.org> you can't build custom collection types without something like hash Though, a sufficient `hash` can be shimmed. [11:59:32.0010] a performant one? [11:59:36.0763] > <@kriskowal:matrix.org> Though, a sufficient `hash` can be shimmed. Not a performant one. [11:59:43.0778] yea ok [12:00:04.0648] https://esfx.js.org/esfx/api/equatable.html#_esfx_equatable_rawHash_function_1_ is a `Object.hash(v)` like thing, but it has a lot of workarounds. [12:00:17.0763] I have to implement a string hashing algorithm for strings, and use weak maps for objects. [12:01:12.0152] Or use NAPI and V8 internals. [12:01:13.0362] wow this esfx repo is pure spaghetti [12:01:54.0208] > <@devsnek:matrix.org> wow this esfx repo is pure spaghetti It's a bunch of individual building blocks. [12:02:10.0654] ok so this depends on a native module [12:02:33.0269] We already have the Array unique proposal: https://github.com/tc39/proposal-array-unique [12:02:48.0513] > <@devsnek:matrix.org> ok so this depends on a native module Depends on environment. I have various fallbacks to support Node native, WASM, and pure JS implementations of hashing [12:03:26.0359] > <@haxjs:matrix.org> We already have the Array unique proposal: https://github.com/tc39/proposal-array-unique true, this seems like it would subsume it [12:03:31.0521] and goes to `GetIdentityHash` in v8 [12:03:40.0532] this is what i wanna expose 🥲 [12:08:02.0006] I’m pretty sure the party line at Agoric for exposing such a `hash` is “no” because we care about determinism and enabling as much of the JavaScript ecosystem to continue to work in a deterministic virtualization. [12:09:13.0290] And regardless of our interests, those identity hashes are going to have to pay a price to not reveal memory layout. Thankfully, Go tells us about how to abuse AES machine instructions. [12:09:15.0082] `{ equals(a, b), hash(v) }` would require no serialization, nor extra allocations in the form of a composite key. Most implementations of `hash` are just bitwise math on 32-bit integers, and we would have roughly the same efficiency that `Map` or `Set` already has since it already uses a similar mechanism. [12:10:53.0769] Maybe an engine VM implementer can tell us about whether there exists an immutable value for every string that can safely reveal an identity. [12:11:02.0711] In my experience, its a bad idea to depend on determinism for non-cryptographic hashes, except within the same process. Many string hashing algorithms generate a random seed value when they're first used. [12:11:08.0270] One that doesn’t require a content address, that is. [12:11:40.0113] > <@kriskowal:matrix.org> Maybe an engine VM implementer can tell us about whether there exists an immutable value for every string that can safely reveal an identity. String hashing usually isn't by address, its usually by algorithm. Addresses generally don't have good avalanche qualities, making them bad for hash table keys [12:12:27.0984] For example, the esfx project I mentioned above uses XXHash64 to generate a non-cryptographic hash with good avalanche properties. [12:13:43.0200] Object identity tends to be the area of concern, as you don't want to expose the address when determining identity. [12:16:46.0539] So you either use something like a monotonically increasing integer for each object allocated, or use a random number and just be aware that there could be collisions. [12:17:31.0577] Or objects all have the same hash value (`0`), and you expect the end user to implement `{ hash(v) }` on the comparator if they want efficiency. [12:24:39.0177] Also, a composite key doesn't help if you want to compare strings with a different sensitivity, as you would need to normalize the string and that's not entirely reliable. [12:24:49.0818] You can avoid a lot of comparator work, too, if we just exposed a composite key structure that sorts lexicographically. Python leans on `key=` returning a tuple a *lot*. [12:25:01.0581] oh lol, colliding composite key opinions [12:25:37.0057] yeah, normalization being unreliable or expensive is the big thing that pushes toward a comparator. [12:29:47.0376] I don't expect most developers are regularly thinking about unicode case folding or the pitfalls of normalizing Turkish ı/İ or German ß. `Intl.Collator` exists for a reason. [12:32:38.0913] A comparator does not preclude the use of a composite key. It means that users can craft their own composite keys, or leverage a shared one that is coupled with an existing comparator it's paired with. [12:59:27.0161] 📢📢📢 all, please note: significant updates to the schedule, as we have freed up time. all overflow topics are now accounted for, but topics have moved, in some cases to a different day [12:59:52.0324] TCQ is still in the process of being updated, but the schedule is the source of truth atm [13:07:01.0667] We believe we have solved the audio issues with remote participants hearing in-room folk using lapel mics by increasing the gain on the lapel units. Please say if you still hear poor/quiet audio. [13:11:30.0065] we don't pick winners in TC39 [13:12:13.0455] we "pave the cowpath" [13:12:38.0090] I think the idea instead is that the option we're picking would most likely become the winner [13:12:50.0474] due to the sheer pervasiveness of JS [13:13:03.0400] but that's not the whole story, obviously [13:13:18.0408] I think you two are saying the same thing, with 'pave the cowpath'? [13:13:44.0724] there's the fact that ICU, which is the de-facto i18n library off the web is heavily involved [13:13:45.0799] "if we build it, they will come" is the exact opposite of "pave the cowpath" [13:14:50.0375] yeah... [13:17:14.0141] my employer would happily rewrite all of our translations for whatever is done here as long as it isn't completely outlandish [13:19:48.0828] wait, so there was breakage due to a change in locale data or was it metadata that was changed without notice? [13:20:40.0924] locale data [13:21:12.0485] my bad. I had never really thought about the expression 'pave the cowpath' before and was interpreting it as 'tread the cowpath' 🤦‍♂️ [13:21:48.0736] shu: there is a diff between data and syntax. IMO they have been coherent when it comes to syntax changes, and structure. As for the data, it is meant to change as localization requirements change. I will categorize the incident that you mentioned as data changes. [13:22:05.0450] > <@devsnek:matrix.org> my employer would happily rewrite all of our translations for whatever is done here as long as it isn't completely outlandish this [13:22:16.0532] caridy: it's accurate to categorize as data change, yes [13:22:43.0778] > <@littledan:matrix.org> this especially if the multi-message format happens. [13:22:57.0175] > <@littledan:matrix.org> this * especially if the multi-message format/api happens. [13:23:06.0979] > <@devsnek:matrix.org> especially if the multi-message format/api happens. yeah, that's not part of this current proposal [13:25:53.0927] bakkot: MF2 has been used by mozilla (which developed it for about a decade now), and used internally to localize firefox, and other pieces of mozilla infrastructure as far as I can tell. [13:27:16.0648] caridy: that's good context! if I think a few dozen more companies also use the syntax for a few years without complaint, that would be enough for me [13:27:47.0687] the experience of a single company with a DSL is very much not sufficient to make me happy, though [13:30:13.0920] bloomberg and salesforce also uses MF2 atm [13:33:00.0994] that speaks to MF2's utility as a standardized format [13:33:18.0044] i still don't make the connection that speaks to the need for a parser in the stdlib [13:33:29.0636] well, we're working on using it; it's not there yet [13:33:52.0379] is the library too onerous to load, too bloated, etc? [13:34:07.0955] Shu, when you refer to "parser", is your concern resolved by Eemeli's use of ASTs instead? [13:34:34.0327] i don't know enough about the AST alternative to say [13:34:44.0474] > <@shuyuguo:matrix.org> is the library too onerous to load, too bloated, etc? How do these concerns relate to, say, Iterator.append, etc? [13:35:13.0663] because the implementation and shipping cost for those as built-ins in the runtime are also small [13:35:14.0071] Should our guiding principle be, "don't propose libraries that are big, only libraries that are small"? [13:35:19.0763] and their utility are broader [13:35:21.0340] DSLs are much harder to get right, and much more infectious, than APIs [13:35:43.0283] so our bar for adding new DSLs should be much (much much much) higher than our bar for adding new APIs [13:35:58.0744] > <@littledan:matrix.org> Should our guiding principle be, "don't propose libraries that are big, only libraries that are small"? libraries that are big and don't benefit from independent re-implementation [13:36:05.0403] > <@shuyuguo:matrix.org> and their utility are broader could you elaborate? [13:36:16.0538] the big/small thing is not crucial imo [13:36:17.0051] i feel like localization is one of the most obvious things to put in a stdlib [13:36:37.0019] everyone needs it and its objectively better [13:36:51.0046] > <@usharma:igalia.com> could you elaborate? my intuition is that the more programs will use iterator helpers as opposed to i18n? [13:36:53.0219] localization information and APIs, certainly; localization DSLs, much less obvious to me [13:37:23.0195] > don't benefit from independent re-implementation This is kinda curious... Which things do you think benefit from independent reimplementation? (I've heard Chrome people muse that it's generally a waste of time to do independent implementations.) [13:37:23.0811] yeah thats true i guess we could make a cldr/unicode/etc api and make people figure it out themselves [13:37:32.0740] i honestly still do not understand what we're losing if the guidance is "use the library" [13:37:53.0091] I don't think when comparing highly specific language APIs whose use is situational based on implementation choices and i18n primitives, I'd make the same conclusion [13:38:01.0627] * yeah thats true i guess we could make a cldr/unicode/etc api and make people figure it out themselves, but why should people have to figure out such a universal thing [13:38:07.0032] > <@devsnek:matrix.org> yeah thats true i guess we could make a cldr/unicode/etc api and make people figure it out themselves, but why should people have to figure out such a universal thing my understanding is that this proposal doesn't particularly expose new information [13:38:30.0015] > <@shuyuguo:matrix.org> i honestly still do not understand what we're losing if the guidance is "use the library" yeah, the idea is a vision of the standard library having stuff for people already... it's sort of irreducible, and it doesn't really make sense for us to add unique, groupBy, etc if we aren't interested in that. [13:38:35.0435] i feel like all counter-arguments are conflating "the world needs a message format" and "JS needs a new parser"? [13:38:50.0588] also i no longer see updates in the thread view when new messages come in [13:38:51.0533] wtf [13:39:03.0162] petition to stop being a thread [13:42:11.0858] littledan: i would argue that we do _not_ have an agreed-upon vision for how "batteries included" the stdlib ought to be [13:42:27.0893] the fact that `groupBy` and `unique` exist is because some champions decided to push for it [13:42:33.0127] not because we are executing on a vision [13:42:43.0231] also a whole new DSL is a much larger battery than iterator helpers [13:44:39.0841] it's like a Tesla battery: large and single-purpose [13:44:43.0575] > <@shuyuguo:matrix.org> littledan: i would argue that we do _not_ have an agreed-upon vision for how "batteries included" the stdlib ought to be Yes, it seems that we don't have a shared vision--we should probably discuss that more generally somehow. [13:45:05.0052] if people stop buying Teslas, it's not that useful to have around anymore [13:45:20.0537] continuing the battery analogy, iterator helpers are like AAs lol [13:45:50.0136] would be pretty nice if making the web localized was a blessed api you could use right off the bat, instead of something you have to build out of intl primitives or try to select a library for. [13:46:25.0208] what is the downside to selecting a library [13:46:32.0908] I feel we're mostly in agreement on that point? [13:46:38.0412] is there a wealth of poor choices or something? [13:46:51.0971] what is the point of this committee meeting and not disbanding? is it just to expose new fundamental capabilities to JS? [13:47:04.0957] I don't think people are saying l10n is not motivating [13:47:20.0326] like, we're already avoiding defining too many new syntax features or things that involve primitive types, for reasons that I understand [13:47:21.0513] and syntax? [13:47:36.0405] (it's been argued that we shouldn't add too much syntax, either) [13:47:40.0289] we're just not in agreement about whether we pick winners [13:49:47.0626] i understand the desire to standardize APIs [13:51:19.0455] why can't we just say "this library is blessed" again? i don't mean something like built-in modules, i just mean literally "this package is blessed" [13:51:24.0445] loading is annoying? [13:53:11.0910] i think the argument is reductive in both directions [13:53:34.0813] but i'd prefer to err on the side of doing things instead of doing nothing [13:54:50.0045] (1) Localization is easy to get wrong and hard to get right and we want to raise the bar for building a Multilingual Web (2) A full MF2 parser is a nontrivial amount of JS payload (3) The longer-term vision littledan mentioned [13:55:17.0252] (2) does not go away by making it part of your JS VM [13:55:44.0708] Any chance of getting extra time for this, I don't think we're necessarily wrapping up in 5 mins? [13:55:46.0247] also Zibi is making a great point here. It took Unicode years to gather the knowledge, experience and effort to nearly finish this effort. [13:55:55.0378] How long are we willing to wait for something else [13:56:10.0048] and who exactly are we expecting to come up with it [13:56:16.0157] Every Intl proposal moves code from every individual web site (N-time download) into the browser (1-time download). That's a principle we've discussed at length in previous proposals. [13:57:26.0655] i agree that is a thing we should solve [13:57:54.0398] > <@shuyuguo:matrix.org> is there a wealth of poor choices or something? Not specifically in JavaScript, but over the years I've encountered a lot of localization systems which lack features which aren't needed in any of the most widely-used European languages. Plenty of developers end up unaware of i18n needs and do it "ad hoc" with systems based almost entirely on English syntax. [13:58:04.0233] there are other ways to solve that distribution problem than to standardize into JS [13:59:26.0972] There's, I think, a bit of a discoverability problem. Making something part of the standard doesn't automatically let people know it exists, but I'd argue it's easier to stumble across it that way than when it's a library you have to search out and specifically add to your project. [14:00:11.0424] IMO that conflates discoverability and distribution with standardization. being a standard _can_ result in being more discoverable and _does_ have "free" distribution [14:00:16.0892] but a standard exists for interoperable implementations [14:00:27.0519] if there is no value add from interoperable implementations and the value add is actually from "blessing" [14:00:35.0115] we should solve for discoverability and distribution directly [14:00:56.0090] littledan: I would describe it like "momentum": the bigger it is or the faster it is being adopted, the less time it will take to reach that confidence [14:01:24.0082] > <@michaelficarra:matrix.org> littledan: I would describe it like "momentum": the bigger it is or the faster it is being adopted, the less time it will take to reach that confidence great, let's keep going, what does momentum look like to you? [14:02:37.0188] API standardization also tries to solve ecosystem fragmentation, insofar that its ecosystem has multiple solutions solving the same problem with difficult interoperability between solutions. I can see an anti-fragmentation justification for MessageFormat 2. It would benefit translators to converge on a single solution that is better than gettext. [14:02:51.0220] * API standardization also tries to solve ecosystem fragmentation, insofar that its ecosystem has multiple solutions solving the same problem with difficult interoperability between solutions. I can see an anti-fragmentation justification for MessageFormat 2. It would benefit translators to converge on a single solution (that is better than gettext). [14:03:03.0040] I can't predict the future, it could look like a lot of things [14:03:16.0463] the room was also rebooted [14:03:58.0878] > <@jschoi:matrix.org> API standardization also tries to solve ecosystem fragmentation, insofar that its ecosystem has multiple solutions solving the same problem with difficult interoperability between solutions. I can see an anti-fragmentation justification for MessageFormat 2. It would benefit translators to converge on a single solution (that is better than gettext). yes, this is a big reason why we are investing in this. It gives a clear point of centralization to follow industry standard best practice. [14:05:02.0850] i think this is also a case where its extremely difficult to get it right, so having a lot of different solutions can imply that every individual solution is a bit worse [14:05:13.0251] * API standardization also tries to solve ecosystem fragmentation, insofar that its ecosystem has multiple solutions solving the same problem with difficult interoperability between solutions. I can see an anti-fragmentation justification for MessageFormat 2 in Ecma-402. It would benefit translators to converge on a single solution (that is better than gettext). [14:05:39.0651] if there's ecosystem fragmentation, isn't that because no solution is strictly best, and we *shouldn't pick a winner from among them*? [14:05:55.0247] * API standardization also tries to solve ecosystem fragmentation, insofar that its ecosystem has multiple solutions solving the same problem with difficult interoperability between solutions. I can see an anti-fragmentation justification for MessageFormat 2 in ECMA-402. It would benefit translators to converge on a single solution (that is better than gettext). [14:07:24.0337] Maybe. That’s not the only possible cause of ecosystem fragmentation. They could also be accidents of history and inertia. But certainly sometimes it’s because the actual requirements vary a lot. It depends. [14:07:48.0225] So: Are the requirements of text localization homogenous enough such that a single solution can cover almost all of them well? [14:08:02.0872] i think most (serious) localization systems are actually somewhat similar, especially in how they author data [14:08:26.0660] I am happy to believe that MF2 is in fact better than all the existing solutions, but if that's so, I'd expect that if there were a permissively licensed production-grade parser for the format, people would want to start using it widely [14:08:29.0500] * Maybe. That’s not the only possible cause of ecosystem fragmentation. They could also be accidents of history and inertia. But certainly, in some cases, it’s because their actual requirements vary a lot. It depends. [14:08:49.0408] and if we saw that happening, and none of those people were like "oh actually I can't adopt this because of [reason]", then it would be a good candidate for standardization [14:09:19.0510] * Maybe. That’s not the only possible cause of ecosystem fragmentation. It can also be caused by accidents of history and inertia. But certainly, in some cases, it’s because their actual requirements vary a lot. It depends. [14:09:27.0075] > why can't we just say "this library is blessed" again? i don't mean something like built-in modules, i just mean literally "this package is blessed" shu on top of what I brought up before. I don't think we can move forward with efforts such as https://nordzilla.github.io/dom-l10n-draft-spec/ without a syntax. [14:09:37.0918] Maybe TC39 can just resolve, as part of the conclusion, that we encourage people to experiment with this library? [14:10:01.0721] also people keep talking about syntax, but the data model is probably more significant (this comes up in the second half of the presentation) [14:10:20.0403] * Maybe. That’s not the only possible cause of ecosystem fragmentation. It can also be caused by accidents of history and inertia. But certainly, in some cases, it’s because their actual requirements vary a lot across applications. It depends. [14:10:24.0330] if our conclusion is recommending a specific library then we've already picked a winner [14:10:38.0351] > <@zbraniecki:matrix.org> > why can't we just say "this library is blessed" again? i don't mean something like built-in modules, i just mean literally "this package is blessed" > > shu on top of what I brought up before. I don't think we can move forward with efforts such as https://nordzilla.github.io/dom-l10n-draft-spec/ without a syntax. i got nothing against standardizing the syntax. i thought that's what Unicode consortium was doing already. did i misunderstand? [14:10:39.0803] * if our conclusion is recommending a specific library then we've already picked a winner, so that objection shouldn't exist to the proposal afterwards [14:11:04.0173] littledan: the data model can be similarly problematic, although less so if it's not the API surface since that layer of indirection can sometimes give us an out [14:11:17.0558] * So: Are the requirements of text localization, across applications, homogenous enough such that a single solution can cover (almost all?) applications well? Or are they heterogenous enough that we should let the ecosystem remain fragmented and different solutions continue to compete? [14:11:44.0672] much easier to repair small flaws in a data model than a syntax, usually (though not always) [14:12:07.0127] repair-by-addition, that is [14:14:01.0146] littledan: questions are not discouragement. [14:14:24.0938] I disagree? sometimes they are? [14:14:27.0848] well, I think that depends on the person [14:15:02.0187] > <@ljharb:matrix.org> if our conclusion is recommending a specific library then we've already picked a winner, so that objection shouldn't exist to the proposal afterwards my concern is different from bakkot's. i'm more easily convinced that there is value to picking a winner here but i have somewhat serious concerns about the mechanism of winner picking [14:15:21.0496] I wonder if it'd help to have a presentation explaining the design of the syntax and data model of MessageFormat v2 to plenary in more detail, including how learnings from other past formats were incorporated. Would people be interested in that? [14:16:08.0593] littledan while such a presentation would be interesting, it wouldn't do much for my concerns, which are about getting experience with the actual thing in practice before standardizing it [14:17:26.0758] having past experience inform the design makes it more likely that the result will be good, but it does actually need to get used in the real world before we can be confident enough to fix the syntax in the language forever [14:17:34.0726] * having past experience inform the design makes it more likely that the result will be good, but it does actually need to get used in the real world before we can be confident enough to fix the syntax in the language forever (IMO) [14:18:06.0205] littledan: i assume you're referring to dr. herman's presentation? (which i missed) or were there more [14:18:12.0178] > <@devsnek:matrix.org> i think most (serious) localization systems are actually somewhat similar, especially in how they author data This does match my experience too; the requirements of text localization seem to be fairly homogenous across applications. (They do vary much more across human languages with very different grammars.) This homogeneity may make the benefit of having translators converge on the same standard language across different applications (potentially) outweigh the cost of convergence preventing ecosystem fragmentation/variation. [14:18:19.0975] > <@ljharb:matrix.org> littledan: i assume you're referring to dr. herman's presentation? (which i missed) or were there more yes [14:19:01.0905] It wasn't referring to any comment from you towards Felienne or that area of work [14:21:40.0546] > <@devsnek:matrix.org> i think most (serious) localization systems are actually somewhat similar, especially in how they author data * This does match my experience too; the requirements of text localization seem to be fairly homogenous across applications. (They do vary much more across human languages with very different grammars. But my assumption here is that all applications want to be able to localize their text to any living human language, so this versatility requirement is similar between applications.) This homogeneity may make the benefit of having translators converge on the same standard language across different applications (potentially) outweigh the cost of convergence preventing ecosystem fragmentation/variation. [14:22:29.0988] * This does match my experience too; the requirements of text localization seem to be fairly homogenous across applications. (They do vary much more across human languages with very different grammars. But my assumption here is that all applications want to be able to localize their text to any living human language, so this versatility requirement is similar between applications.) This homogeneity may make the benefit of having translators converge on the same standard language across different applications (potentially) outweigh the cost of convergence preventing ecosystem fragmentation/variation/innovation. [14:22:37.0284] * This does match my experience too; the requirements of text localization seem to be fairly homogenous across applications. (They do vary much more across human languages with very different grammars. But my assumption here is that all applications want to be able to localize their text to any living human language, so this versatility requirement is similar between applications.) This homogeneity may make the benefit of having translators converge on the same standard language across different applications (potentially) outweigh the cost of convergence preventing ecosystem fragmentation / variation / innovation. [14:25:51.0014] https://github.com/tc39/proposal-arraybuffer-transfer/issues/12 [14:27:31.0184] one mitigation with respect to the risk of TG5 fizzling out: Mikhail is on a tenure track :) [14:29:07.0438] * API standardization also tries to solve ecosystem fragmentation, insofar that the ecosystem has multiple solutions solving the same problem with difficult interoperability between solutions. I can see an anti-fragmentation justification for MessageFormat 2 in ECMA-402. It would benefit translators to converge, across organizations, on a single solution (that is better than gettext). [14:29:40.0108] I believe he actually has tenure-equivalent status at UiB [14:30:10.0008] sgtm [14:32:01.0942] * This does match my experience too; the requirements of text localization seem to be fairly homogenous across applications. (They do vary much more across human languages with very different grammars. But my assumption here is that all applications want to be able to localize their text to any living human language, so this versatility requirement is similar between applications.) This homogeneity may make the benefit of reducing ecosystem fragmentation—having translators converge on the same standard language across different applications—potentially outweigh the cost of convergence preventing necessary ecosystem variation / innovation. [14:50:52.0179] yeap, the position I have is a permanent academic position, equivalent to tenure :) [15:09:42.0580] oops, well, congrats! [15:10:31.0537] Congrats on reaching this milestone to ptomato and all of the Temporal champions! The remaining editorial changes should unblock all implementations to proceed. [15:11:40.0359] if implementers still feel blocked or like it's not ready yet: let's discuss your concerns [15:13:15.0917] can someone let me in the zoom ? [15:14:17.0329] OT: I hope everyone is enjoying our San Diego office, wish I could have made it to be there. [15:14:43.0360] > <@mhofman:matrix.org> can someone let me in the zoom ? you are showing as in the room. all good? [15:15:03.0423] > <@softwarechris:matrix.org> you are showing as in the room. all good? Yup someone let me in now [15:19:18.0892] It's not just locks that need this, but also lock-free, concurrent algorithms that depend on CAS and spin-waiting. [15:20:31.0572] While not shared structs specific, I ran into this when working with the shared structs dev trial in an experiment with the TypeScript compiler. [15:22:06.0724] By *this* I mean `Atomics.microwait()`. [15:22:15.0583] * By "this" I meant `Atomics.microwait()`. [15:26:49.0426] are we gonna get an `Atomics.futex` [15:27:15.0746] Isn't that just `Atomics.compareExchange` and `Atomics.wait`? It's already a futex. [15:27:31.0531] ye [15:27:37.0699] and then this proposal is the natural extension of that [15:28:05.0759] srs question, could this just be an asm-like string pragma, for emscripten? [15:28:10.0713] well, given saboff's feedback, I am imagining a version which did the spin-plus-backoff-then-sleep thing internally [15:28:19.0828] * srs question, could this be an asm-like string pragma, for emscripten? [15:28:20.0711] wdym jordan [15:28:22.0845] > <@ljharb:matrix.org> srs question, could this be an asm-like string pragma, for emscripten? could... what be? [15:28:29.0874] like shu explained this as a hint to the CPU [15:28:36.0588] so `"spin 5"` or something [15:28:40.0678] * so `"spin 5";` or something [15:29:00.0874] a static no-op string, not in the spec, that gives a hint [15:29:18.0889] (i'm assuming there's a reason why that wouldn't work but i don't know what it would be) [15:29:36.0809] like if the engine sees `"spin 5"` in a statement position, it emits a `yield` instruction? [15:29:37.0942] I feel reluctant to bring this slide deck to my colleagues due to the controversial choice of font. What a rebel. [15:30:29.0889] snek: yes, basically [15:30:46.0667] i think like [15:30:53.0365] technically yes that's a thing that could happen [15:30:57.0473] we make the language we can do whatever we want [15:31:11.0450] right but i mean this wouldn't need to be in the spec [15:31:13.0437] i don't think magic strings are generally a good pattern though [15:31:16.0761] * right but i mean this wouldn't need to be in the spec necessarily [15:31:18.0682] oh sure, agreed [15:31:32.0500] was just kind of wondering out loud if that's all that's needed, a static marker [15:31:40.0011] * was just kind of wondering out loud if that's all that's needed, a statically recognizable marker [15:32:38.0006] i'm personally ok with Atomics being a bit of a weird area in the spec [15:32:45.0791] atomics are kind of a weird area in every language [15:36:23.0174] The implementation of a `yield` instruction tends to be a bit more complicated than a static marker. You want some input to the instruction to allow some variance to the spin in the case you have two threads on two independent cores spinning at the same time in lock-step. It's not `"spin 5"` its more like `yieldIfNecessary(spinCount)`. You don't always yield. sometimes you sleep, and sometimes you do nothing, all to combat contention. [15:36:59.0098] it could be `"yield if necessary spinCount"` [15:37:08.0714] we make the rules [15:37:10.0036] but [15:37:11.0872] i don't want that [15:37:12.0449] What is `spinCount` though? [15:37:17.0213] a variable in scope [15:37:18.0952] idk [15:37:21.0338] That's terrible. [15:37:24.0213] yea [15:37:40.0043] could make it a template literal 😄 [15:37:43.0908] `` `yield if necessary ${spinCount}` `` [15:37:57.0184] i'd rather just have this on Atomics [15:37:57.0794] Just call it `Atomics.microwait(spinCount)` and be done. Implementations can and will inline that into instructions. [15:41:24.0062] ok the graph on the screen does not say "goes up steadily" to me [15:41:31.0891] that says "is used by exactly one popular package" [15:45:16.0921] It looks like 2 or 3 popular packages, and 1300 other packages. [15:46:06.0142] `async do { await cb() }` [15:46:20.0692] what's up with do expressions these days [15:46:24.0298] we should do do expressions (and async do expressions :) [15:46:28.0506] * we should do do expressions (and async do expressions ):) [15:46:32.0071] * we should do do expressions (and async do expressions) :) [15:46:40.0399] I think the committee's time and my time is better spent on APIs than syntax [15:46:44.0731] so I am working on APIs rather than syntax [15:46:50.0610] * I think the committee's time and my time is better spent on APIs than syntax at the current margin [15:46:54.0879] we have so many syntax proposals [15:47:02.0030] is there a concrete API i can just read somewhere that has this pattern [15:47:09.0377] the "takes a callback and might throw sync, but otherwise async" [15:47:25.0398] While I certainly hope `do {}` does eventually advance, I have some big concerns about `async do {}` [15:47:38.0894] async blocks are handy in rust [15:47:43.0470] yeah, so nice [15:49:07.0638] It depends on what `do { return; }` does. If it actually causes a return from the containing function, then what do you do with `async do { return; }`. Does `async do` differ dramatically from `do` in this case? It obviously can't return from the containing function. [15:49:49.0593] > <@shuyuguo:matrix.org> is there a concrete API i can just read somewhere that has this pattern No, anything using WebIDL is pretty explicit that if you're returning a Promise, you always return a (possibly rejected) Promise; you never throw sync. [15:49:51.0442] And if `do {}` doesn't support `return`, `break`, or `continue`, it seems far lest interesting to me. [15:49:58.0299] > <@rbuckton:matrix.org> It depends on what `do { return; }` does. If it actually causes a return from the containing function, then what do you do with `async do { return; }`. Does `async do` differ dramatically from `do` in this case? It obviously can't return from the containing function. (syntax error, in current proposal) [15:50:10.0370] that is, `async do { return }` is syntax error [15:50:10.0412] then i'm confused, if this is a bad pattern then... shouldn't we not add this [15:50:15.0781] and `do { return }` returns from current function [15:50:31.0165] > <@bakkot:matrix.org> that says "is used by exactly one popular package" Half of those p-try downloads come from Jest indeed [15:51:12.0328] > <@tabatkins:matrix.org> No, anything using WebIDL is pretty explicit that if you're returning a Promise, you always return a (possibly rejected) Promise; you never throw sync. yeah this conditionally synchronous kind of thing is similarly considered unkosher, at least according to the logic we all had around 2015 [15:51:38.0033] > <@shuyuguo:matrix.org> then i'm confused, if this is a bad pattern then... shouldn't we not add this Is this the Promise.try() discussion happening right now? It doesn't throw sync. It just *calls* the function sync, but still causes a rejected promise. (If the slides are still accurate.) [15:51:43.0552] I see similar pattern in some other libs, like nodejs perf.timerify() [15:51:46.0741] (I'm not in the meeting, I'm just observing from chat.) [15:51:54.0024] > <@tabatkins:matrix.org> Is this the Promise.try() discussion happening right now? It doesn't throw sync. It just *calls* the function sync, but still causes a rejected promise. (If the slides are still accurate.) that's the discussion yes [15:51:57.0393] That means `async do {}` and `do {}` are wildly different things, and potentially a refactoring hazard. I'm not opposed to the capability that `async do {}` offers, but I wonder if it shouldn't use `do` in that case because it could be confusing. [15:52:35.0875] > <@tabatkins:matrix.org> Is this the Promise.try() discussion happening right now? It doesn't throw sync. It just *calls* the function sync, but still causes a rejected promise. (If the slides are still accurate.) yeah the thing is that the use case has to do with something which might throw sync or return a promise... which is a situation that's not supposed to occur [15:52:36.0155] TabAtkins: i know, but the _function_ throws sync [15:52:39.0969] > <@rbuckton:matrix.org> That means `async do {}` and `do {}` are wildly different things, and potentially a refactoring hazard. I'm not opposed to the capability that `async do {}` offers, but I wonder if it shouldn't use `do` in that case because it could be confusing. I have been thinking about maybe `async {}` and `expr {}` or something yeah [15:53:15.0115] > <@shuyuguo:matrix.org> TabAtkins: i know, but the _function_ throws sync Sure, but it might return sync too. You can just hand a synchronous function to this. [15:53:20.0812] > <@bakkot:matrix.org> I have been thinking about maybe `async {}` and `expr {}` or something yeah what about `expr` and `asyncExpr` [15:53:24.0909] Promise construction seems to trip everybody up, so avoiding it I think is generally a win. [15:53:40.0787] > <@usharma:igalia.com> what about `expr` and `asyncExpr` I would prefer to never encounter a camelcase keyword [15:53:42.0443] But also: you might have a function in hand that you just don't know if it's sync or async, and want to consolidate your control flow into async [15:53:45.0095] we could both demonstrate the similarity and avoid the refactoring hazard [15:53:59.0063] > <@bakkot:matrix.org> I would prefer to never encounter a camelcase keyword hm okay fair [15:54:16.0600] > <@tabatkins:matrix.org> But also: you might have a function in hand that you just don't know if it's sync or async, and want to consolidate your control flow into async right, snek just explained this [15:54:33.0171] I was just wondering how we could mark both as related concepts while avoiding the double keyword issue [15:54:40.0261] I see the need for the functionality of Promise.try, but I don't quite see why `Promise.try(callback)` is significantly better than `new Promise(resolve => resolve(callback()))` [15:54:41.0667] I'm just repeating what was in the slides when I read them this morning ^_^ [15:54:59.0388] Bradford Smith: It's identical in functionality, it's just shorter. [15:55:11.0808] I am not convinced this comes up enough to need sugar [15:55:33.0875] maybe it's just that I never try to be defensive against this case? if I ask for an async function and the user gives me a function which sycn throws, that's on them [15:55:35.0448] > <@usharma:igalia.com> I was just wondering how we could mark both as related concepts while avoiding the double keyword issue My point was that they are only related at the surface level, and having too similar of a syntax is actually a detriment. [15:55:41.0758] I would say it isn't just shorter, it expresses the intend better. [15:56:00.0871] I wonder whether the intent might usually be expressed better by Promise.withResolvers + try/catch [15:56:06.0171] i can't confidently say whether it comes up super often or not but i can't come up with any strong reason to be against it [15:56:11.0071] > <@tabatkins:matrix.org> Bradford Smith: It's identical in functionality, it's just shorter. I'm saying, it's not significantly shorter. [15:56:28.0678] > <@devsnek:matrix.org> i can't confidently say whether it comes up super often or not but i can't come up with any strong reason to be against it I would like a higher bar than "no strong reason not to do it" for things to go in the language [15:56:44.0030] bakkot: I think the deal is that, for the *non*-throwing case, you can trivially consolidate both sync and async functions with `new Promise(f())`. But if `f` throws, then the sync version causes a throw, while the async causes a rejected promise. [15:56:44.0221] I guess that's what the consensus topic later is though [15:57:16.0759] yeah its more just how i approach it, especially with something as simple as this function [15:57:24.0097] * bakkot: I think the deal is that, for the _non_-throwing case, you can trivially consolidate both sync and async functions with `new Promise(f())` (or just `await f()`). But if `f` throws, then the sync version causes a throw, while the async causes a rejected promise. [15:57:58.0132] i said nullary, not unary [15:58:02.0422] this doesn't pass any arguments does it [15:58:12.0806] async context is happening? i thought mark was super against that [15:58:19.0059] Correct, nullary [15:58:28.0515] That's also consistent with `setImmediate(cb, ...args)` [15:58:39.0647] @bakkot: me [15:59:04.0612] > <@devsnek:matrix.org> async context is happening? i thought mark was super against that it turned out it was fine [15:59:13.0836] > <@shuyuguo:matrix.org> i said nullary, not unary I mispoke, meant 0 params 2024-02-07 [16:00:05.0824] bakkot: I've run into this when working with non async/await code (i.e., working directly with `Promise`). [16:00:28.0993] > <@littledan:matrix.org> it turned out it was fine love to hear it [16:01:22.0937] shu: finally found the example that AMP hit: https://github.com/ampproject/amphtml/pull/15107 [16:01:45.0985] A better (but maybe harder to answer) question, is how may people incorrectly write `Promise.resolve(f())`? This wouldn't fix those cases, but would give those developers something easier to reach for when they're looking for a solution. [16:01:52.0254] After this, we forced all `Promise.resolve(fn())` to use `tryResolve(fn)` helper [16:01:58.0170] * A better (but maybe harder to answer) question is, how may people incorrectly write `Promise.resolve(f())`? This wouldn't fix those cases, but would give those developers something easier to reach for when they're looking for a solution. [16:02:25.0080] is jest bad [16:02:35.0617] i feel like i've picked up some subtext somewhere that jest is bad, but unsure [16:02:45.0910] jest is a good test framework that unfortunately does some very bad things. [16:02:47.0605] i think jest is ok? [16:02:47.0895] I feel like I'm the only one in the world that still likes Jest [16:02:50.0411] i don't use it often [16:02:58.0832] > <@shuyuguo:matrix.org> is jest bad you don't want to open this can of worms in this group [16:03:11.0116] Jest does Bad Things ^TM just because we haven't shadow realms yet [16:03:15.0156] `Promise.resolve((async () => fn())())` ? [16:03:16.0155] So Node folks hate it [16:03:23.0065] only some parts of Jest are bad... [16:03:29.0409] node folks hate everything, i say this as a node folk [16:03:37.0845] > <@haxjs:matrix.org> `Promise.resolve((async () => fn())())` ? Or just `(async () => fn())()`. [16:05:35.0396] I think we should start using more the number of dependents as a metric, rather than the number of downloads, since it tells us how many people actually needed to write that code [16:05:51.0613] A very popular library can still have shitty code [16:06:20.0633] i will continue to use whatever number best supports my position [16:06:32.0909] > <@devsnek:matrix.org> i will continue to use whatever number best supports my position Number of dependencies [16:06:39.0632] ljharb: npm apparently doesn't let you fetch more than 10 pages of dependents so this is useless but since I've written it now https://gist.github.com/bakkot/61a9bddb1c88155297f4c6f0880189f6 [16:07:16.0525] ljharb: Justin Ridgewell shoot i missed your message before i didn't give consensus if it came before [16:07:32.0499] that diff is convincing enough for me, stage 2 sgtm, if ljharb wanna come back at end of today [16:07:41.0754] but not 2.7 yet because i think it probably needs to pass along ...arguments [16:09:18.0993] > <@jridgewell:matrix.org> shu: finally found the example that AMP hit: https://github.com/ampproject/amphtml/pull/15107 This one? yeah, huh... [16:09:32.0296] Justin Ridgewell: so wait actually now i'm reading MDN page for play() [16:09:40.0161] it says if it can't play(), a rejected Promise is returned [16:09:50.0163] was the sync throw a Chrome bug or is MDN wrong? [16:10:00.0012] If I remember correctly, `el.play()` used to sync return, then it was changed to return a promise, but it can still sync throw. [16:10:04.0134] > <@shuyuguo:matrix.org> that diff is convincing enough for me, stage 2 sgtm, if ljharb wanna come back at end of today awesome, thanks. i'll ask about that [16:10:10.0319] https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play says rejected Promise [16:10:22.0629] okay if the most compelling argument is "sometimes there are bugs and people do the bad thing", i guess that's fine with me [16:10:27.0909] the cost for this is pretty trivial [16:13:12.0142] shu: https://github.com/ampproject/amphtml/pull/6083#discussion_r87054018 [16:13:17.0452] I asked the exact same thing [16:14:47.0550] so `zip` is `product` on iterator (in the type-theory sense). `sum` doesn't really make sense on sync iterators (you can do zip+flat but there's not much reason) but on async iterators `sum` totally works, as `AsyncIterator.merge` or `race` or something like that. I will probably propose that at some point [16:16:03.0971] Justin Ridgewell: cursed that just changed it, thanks for the knowledge [16:16:11.0236] * Justin Ridgewell: cursed that they just changed it, thanks for the knowledge [16:18:37.0233] shu: https://github.com/tc39/proposal-promise-try/issues/9 btw for the passing arguments thing [16:19:28.0270] thanks [16:20:02.0292] > <@ljharb:matrix.org> shu: https://github.com/tc39/proposal-promise-try/issues/9 btw for the passing arguments thing ok wait if you're ok with arrows why not just use `(async () => fn())()` [16:20:17.0194] am I missing something about that [16:20:28.0351] i mean *i* am not personally ok with using syntax here [16:20:49.0196] sorry, that was re: your first comment in that thread [16:21:07.0235] `Promise.try(() => f(a, b, c))` [16:21:12.0962] > <@bakkot:matrix.org> ok wait if you're ok with arrows why not just use `(async () => fn())()` yeah i'm okay with that? [16:21:22.0327] but i mean i'm willing to take other people's words for what forms they want to type [16:21:24.0124] "wrapping in an arrow function" is how i spell "wrapping in a function" for people that can't ship that syntax :-p [16:21:26.0089] no deeper reason than that [16:21:33.0406] * "wrapping in an arrow function" is how i spell "wrapping in a function" for people that can't ship that syntax, like myself :-p [16:21:58.0006] i think the readability/confusion thing still applies for an AIIFE tho, arrow or no [16:22:09.0382] which tbf is an argument in favor of passing arguments [16:22:28.0069] what if we let prefix `^` be a shorter way to write `()=>`? Could make a lot of these arrows shorter. [but it wouldn't scale to the async case] [16:22:33.0106] however, this facility of setTimeout has proven very confusing for practitioners, so i'm not anxious to repeat it [16:23:21.0496] * however, this facility of setTimeout (passing args) has proven very confusing for practitioners, so i'm not anxious to repeat it [16:23:22.0283] > <@littledan:matrix.org> what if we let prefix `^` be a shorter way to write `()=>`? Could make a lot of these arrows shorter. [but it wouldn't scale to the async case] `& &1` in elixir is like `(a) => a` [16:23:57.0290] > <@ljharb:matrix.org> however, this facility of setTimeout (passing args) has proven very confusing for practitioners, so i'm not anxious to repeat it `setTimeout` is strange because it injects a timeout between the callback and the arguments. [16:23:57.0297] > <@ljharb:matrix.org> however, this facility of setTimeout (passing args) has proven very confusing for practitioners, so i'm not anxious to repeat it setTimeout is confusing because - it also accepts a string - it accepts not only the fn and the params, but also the time [16:24:37.0433] i think arrow functions and bind are both better solutions than making everything that takes a callback also accept arguments somewhere [16:24:42.0395] > <@devsnek:matrix.org> `& &1` in elixir is like `(a) => a` https://github.com/tc39/proposal-pipeline-operator/blob/main/README.md#tacit-unary-function-application-syntax would cover this and have `+> %` mean `x => x`. [16:24:42.0441] For setTimeout, there's a potentially noticeable difference between `setTimeout(f, 1000, a, b, c)` and `setTimeout(()=>f(a,b,c), 1000)`, which is that a/b/c are evaluated eagerly or late. [16:24:45.0873] accepting a string is the way PHP and god intended [16:24:54.0006] There's no such difference in Promise.try() [16:24:59.0208] > <@devsnek:matrix.org> `& &1` in elixir is like `(a) => a` * https://github.com/tc39/proposal-pipeline-operator/blob/main/README.md#tacit-unary-function-application-syntax would cover this and have `+> %` mean `x => x`. Er, meant to reply to littledan there. [16:25:07.0300] > <@devsnek:matrix.org> `& &1` in elixir is like `(a) => a` And we already have partial application at stage 1 if we want to make arrows shorter. [16:25:12.0815] what is going on with matrix [16:25:18.0186] i'm seeing like, decoherence [16:26:03.0261] Explici t support [16:26:18.0686] Can’t talk [16:26:32.0182] who was i talking to earlier about discord message logs [16:28:15.0364] > <@devsnek:matrix.org> i think arrow functions and bind are both better solutions than making everything that takes a callback also accept arguments somewhere What are your thoughts on https://github.com/tc39/proposal-partial-application? [16:28:37.0409] > <@rbuckton:matrix.org> What are your thoughts on https://github.com/tc39/proposal-partial-application? neutral to slightly negative [16:28:46.0443] i don't write javascript in a super fp heavy way [16:30:41.0881] That's fair. I'm still planning on coming back to that one at some point. I admit it paired far better with F#-style pipelines, but I still think it has value. [16:35:51.0192] Feedback, someone needs to turn off a mic [16:37:55.0248] Did I disappear from the queue? [16:38:11.0756] jschoi: refresh [16:38:21.0233] > <@jschoi:matrix.org> Did I disappear from the queue? I see you as the next topic on the queue [16:39:46.0998] isn't it typed differently because it's not representable as an integer? [16:40:05.0953] ye [16:40:52.0747] the best thing is in v8 there's a parameter you have to pass when converting where you explicitly opt into checking for -0 or not [16:41:03.0072] surely no bugs have ever come of this 😄 [16:41:14.0793] > <@littledan:matrix.org> isn't it typed differently because it's not representable as an integer? yeah that sounds right [16:41:32.0249] I understand the issue of -0, but I don't think it should be considered in Math.sum proposal. [16:42:12.0259] I'd need a stronger argument to convince me to return +0 when passed an empty input [16:42:20.0563] hax (HE Shi-Jun): in which direction? [16:42:25.0095] Michael Ficarra: well it's confusing! [16:42:38.0049] wait why wouldn't empty input produce NaN [16:42:54.0350] i'd want to hear from someone who knows how binary64 works on whether its problematic. if it isn't, we should do +0 [16:42:57.0824] shu: it toStrings as 0! [16:43:14.0564] > <@ljharb:matrix.org> wait why wouldn't empty input produce NaN So that `sum(...arr)` and `arr[0] + sum(..arr.splice(1))` do the same thing for non-empty arr :) [16:43:35.0831] they wouldn't anyways because of the current slide [16:43:38.0300] > <@nicolo-ribaudo:matrix.org> So that `sum(...arr)` and `arr[0] + sum(..arr.splice(1))` do the same thing for non-empty arr :) Oh actually, with Kevin's algorithm this isn't trye [16:43:39.0552] * they wouldn't anyways because of the current slide, right? [16:43:41.0841] > <@nicolo-ribaudo:matrix.org> So that `sum(...arr)` and `arr[0] + sum(..arr.splice(1))` do the same thing for non-empty arr :) * Oh actually, with Kevin's algorithm this isn't true [16:43:43.0753] `let getNegativeZero = () => Math.sum([])` please don't break my code [16:43:45.0052] Yeah good point [16:43:53.0251] * Yeah good point jordan [16:44:02.0933] this is IEEE floats, math and real numbers have nothing to do with anything. "the sum of nothing" can be whatever we want [16:44:18.0415] > <@ljharb:matrix.org> this is IEEE floats, math and real numbers have nothing to do with anything. "the sum of nothing" can be whatever we want `Math.sum([]) === 1` [16:44:26.0487] like is there maybe some implication if you do `Math.sum(Math.sum(x), y)`? [16:44:46.0532] > <@michaelficarra:matrix.org> I'd need a stronger argument to convince me to return +0 when passed an empty input i'm hearing you like exploits [16:44:46.0649] > <@nicolo-ribaudo:matrix.org> `Math.sum([]) === 1` i mean we can all point to dumb things in JS :-p doesn't mean we have to repeat the mistakes in `sumExact` [16:44:49.0721] or use it in other random places [16:45:41.0246] > <@shuyuguo:matrix.org> hax (HE Shi-Jun): in which direction? I mean I feel -0 issue is irrelevant. [16:45:43.0259] python also implicitly has ints in places tho [16:46:00.0789] > <@shuyuguo:matrix.org> i'm hearing you like exploits this doesn't prevent -0 from flowing to the wrong place *intentionally* [16:46:02.0221] hax (HE Shi-Jun): i have already said why it's not irrelevant to v8 [16:46:14.0417] > <@michaelficarra:matrix.org> this doesn't prevent -0 from flowing to the wrong place *intentionally* it's about minimizing surface, not eliminating surface [16:46:33.0275] yeah but that's no the surface [16:46:41.0656] * yeah but that's not the surface [16:46:52.0608] manual inlines in the JIT for builtins is a surface [16:47:28.0494] > <@shuyuguo:matrix.org> i'm hearing you like exploits I don't find this convincing here because -0 is already in the language, and returing it from a new function just adds more places to be careful by a limited number (in the places where you are inlining this built-in). And now we are explicitly aware about this -0, it could be even be explicitly called out in the spec by saying _why_ we return it so that implementers don't miss it. [16:47:41.0019] Otoh, Jordan's observation made me less storngly in favor of -0 [16:47:45.0999] Me too Kevin, me too :P [16:48:05.0431] > <@nicolo-ribaudo:matrix.org> I don't find this convincing here because -0 is already in the language, and returing it from a new function just adds more places to be careful by a limited number (in the places where you are inlining this built-in). > > And now we are explicitly aware about this -0, it could be even be explicitly called out in the spec by saying _why_ we return it so that implementers don't miss it. you don't find what i said about manual inlines convincing because we can be more vigilant? [16:48:17.0635] For additional reference, C#'s `Enumerable.Sum` also returns positive zero for an empty list. [16:48:18.0952] `parseInt('-0')` oh no exploits [16:48:24.0431] i mean can i hear a positive argument for why you want it to be -0 [16:48:30.0151] technically you *can* subtracft a list, its just not a thing [16:48:34.0825] * technically you _can_ subtract a list, its just not a thing [16:48:34.0879] i said the exploit thing tongue in cheek [16:49:08.0508] maybe ask Duncan MacGregor for pointers to the examples from other languages he was referring to? [16:49:14.0764] > <@shuyuguo:matrix.org> i mean can i hear a positive argument for why you want it to be -0 Well, because all the number combinators return their identity when called with 0 args [16:49:27.0140] is that property relied on [16:49:52.0916] like, for the use cases here [16:50:22.0722] if Python returns +0, i _know_ that ecosystem does a lot of numerical stuff and it doesn't bother them, that gives me one signal [16:50:33.0168] Duncan MacGregor said ruby experienced the opposite thing, i'd like to learn more about that [16:50:49.0875] > <@shuyuguo:matrix.org> if Python returns +0, i _know_ that ecosystem does a lot of numerical stuff and it doesn't bother them, that gives me one signal it doesn't return +0, it returns the integer 0. not a float! [16:51:07.0377] its `fsum` returns an integer? [16:51:15.0617] oh fsum probably does not [16:51:25.0674] is fsum a thing [16:51:28.0652] i'm specifically talking about fsum because that's what kevin was talking about (i thought) [16:51:29.0155] yes [16:51:32.0144] I've relied it for `.min`/`.max` when I get values some values initially and then other later, so I have an "intermediate min". As Jordan pointed out however, that doesn't work here so my main argument is "all the others do this, we should not diverge" [16:51:36.0416] * I've relied ib it for `.min`/`.max` when I get values some values initially and then other later, so I have an "intermediate min". As Jordan pointed out however, that doesn't work here so my main argument is "all the others do this, we should not diverge" [16:51:37.0096] ah math.fsum [16:51:55.0385] > <@nicolo-ribaudo:matrix.org> I've relied ib it for `.min`/`.max` when I get values some values initially and then other later, so I have an "intermediate min". > > As Jordan pointed out however, that doesn't work here so my main argument is "all the others do this, we should not diverge" but others do not do this, cf python! [16:52:01.0931] > <@nicolo-ribaudo:matrix.org> Well, because all the number combinators return their identity when called with 0 args Whether `+0` is not an identity of Math.sum depends on what equivalence relation you’re applying to that identity: `===` versus `Object.is`. In other words, the question here is which equivalence relation we think is most useful (or least risky) for general code that needs to use Math.sum. [16:52:37.0595] > <@jschoi:matrix.org> Whether `+0` is not an identity of Math.sum depends on what equivalence relation you’re applying to that identity: > `===` versus `Object.is`. > > In other words, the question here is which equivalence relation we think is most useful (or least risky) for general code that needs to use Math.sum. that's not my understanding at all, the identity is over `+` over floats [16:52:58.0269] how do `===` and `Object.is` figure into it? [16:53:24.0691] If there should only be one answer, we either need a reference implementation or comprehensive test cases to ensure all implements do arrive at the same answer. [16:53:25.0516] oh i see, you mean `x+id === x` or `Object.is(x+id, x)`? [16:53:31.0688] > <@shuyuguo:matrix.org> how do `===` and `Object.is` figure into it? Well, from JS you can only observe that +0 is not the identity if you use `Object.is` at some point, since it's not the identity only for the -0 vs +0 case [16:53:46.0730] yeah fair enough [16:53:54.0546] > <@shuyuguo:matrix.org> how do `===` and `Object.is` figure into it? Sorry, I mean whether `-0` and `+0` are considered “equivalent” or different is related to whether we consider *both* `-0` and `+0` to be identities on the `+` operation. [16:54:09.0188] Basically what Nicolo just said. [16:54:09.0813] is that an argument for one direction over the other? [16:54:26.0681] I think it’s reasonable to return `+0` and call it an “identity” (loosely). [16:54:41.0218] sgtm [16:54:53.0451] * I think it’s reasonable to return `+0` and call it an “identity” (loosely, based on `===`). [16:55:50.0282] > <@shuyuguo:matrix.org> Duncan MacGregor said ruby experienced the opposite thing, i'd like to learn more about that Not returning -0.0 has the weird effect that summing two arrays (1 empty) can give a different result from summing the concatenated array. [16:56:48.0552] Ruby's array summing is a bit of a disaster area in my experience, it has a load of gotchas depending on whether the whole array is floats or not, and other fun things. [16:58:19.0159] On the SQL and null note we couldn't return null because null is not the identity under addition in JS. null + null give 0. :-( [16:58:35.0781] NaN + NaN is NaN tho [16:58:42.0411] * NaN + NaN is NaN tho :-p [16:59:41.0224] > <@aardvark179:matrix.org> Not returning -0.0 has the weird effect that summing two arrays (1 empty) can give a different result from summing the concatenated array. sorry being slow, meaning if you do `sum([]) + sum([1])` vs `sum([].concat([1]))`? [16:59:46.0344] New topic: How come we don't have a table of Stage 2.7 proposals? Is it that none have landed into that bucket yet? https://github.com/tc39/proposals [16:59:52.0114] The engines nowadays would optimize `Math.sum([0, 1, 2])` such that the intermediate array doesn’t get allocated then GCed, right? [17:00:18.0965] > <@robpalme:matrix.org> New topic: How come we don't have a table of Stage 2.7 proposals? Is it that none have landed into that bucket yet? > > https://github.com/tc39/proposals yes, that's correct [17:00:26.0550] * yes, that's correct. i'll make a table for it once we have one [17:00:37.0938] even if we wrote down the full algorithm, we would still need to write somewhere that it was computing full precision summation because that is not immediately obvious from looking at 100 algorithm steps [17:00:47.0651] ljharb: Would you be satisfied with the spec pointing to documentation for an example known-good algorithm? [17:00:52.0503] why not put both? [17:01:04.0289] * why not put both? (to both the last two comments) [17:01:10.0992] as an implementor i don't think writing out an algorithm would be helpful [17:01:14.0030] shu: `Math.sum([-0])` what would you expect it to return? [17:01:23.0012] it would be helpful to me ¯\_(ツ)_/¯ [17:01:24.0830] * as an implementor i don't think writing out an algorithm would be helpful, it would just be noise [17:01:25.0957] * it would be helpful to me ¯\\\_(ツ)\_/¯ [17:01:40.0959] i think linking to an example is far better [17:02:05.0988] > <@ljharb:matrix.org> yes, that's correct. i'll make a table for it once we have one Does a prior “Stage 3 conditional on approval by reviewers” status retroactively count as “Stage 2.7”? Regarding proposal-array-from-async. [17:02:11.0839] > <@nicolo-ribaudo:matrix.org> shu: `Math.sum([-0])` what would you expect it to return? If this returns `+0`, I think it's ok to say "we always ignore -0". But if it can return -0, than you already have to be careful about it when implementing [17:02:13.0461] > <@nicolo-ribaudo:matrix.org> shu: `Math.sum([-0])` what would you expect it to return? i would expect it to return +0 i think? [17:02:24.0534] > <@nicolo-ribaudo:matrix.org> shu: `Math.sum([-0])` what would you expect it to return? * If this returns `+0`, I think it's ok to say "we always normalize -0". But if it can return -0, than you already have to be careful about it when implementing [17:02:32.0466] > <@shuyuguo:matrix.org> sorry being slow, meaning if you do `sum([]) + sum([1])` vs `sum([].concat([1]))`? So if you have [-0.0].sum + [].sum that would give a different result to ([-0.0] + []).sum. [17:02:33.0789] > <@nicolo-ribaudo:matrix.org> If this returns `+0`, I think it's ok to say "we always normalize -0". But if it can return -0, than you already have to be careful about it when implementing yes, that's a good point to call out [17:02:53.0210] On ruby those actually give the same answer because ruby starts with 0 and adds the elements... [17:02:53.0306] > <@michaelficarra:matrix.org> even if we wrote down the full algorithm, we would still need to write somewhere that it was computing full precision summation because that is not immediately obvious from looking at 100 algorithm steps Are there corner cases in arbitrary precision arithmetic that would be useful to point out in the specification? We do that in a number of places in the spec. [17:03:05.0507] > <@aardvark179:matrix.org> So if you have [-0.0].sum + [].sum that would give a different result to ([-0.0] + []).sum. what are the two sums? +0.0 for the former and -0.0 for the latter? [17:03:09.0269] Ok so my position is that `Math.sum([-0])` and `Math.sum([])` must return the same result. I would prefer both to return -0, but as long as they return the same value I'm fine [17:03:29.0210] > <@jschoi:matrix.org> Does a prior “Stage 3 conditional on approval by reviewers” status retroactively count as “Stage 2.7”? Regarding proposal-array-from-async. i believe we need explicit consensus on 2.7 in plenary for anything to go in the table [17:03:39.0192] > <@nicolo-ribaudo:matrix.org> Ok so my position is that `Math.sum([-0])` and `Math.sum([])` must return the same result. I would prefer both to return -0, but as long as they return the same value I'm fine that's pretty reasonable, i agree with that [17:03:46.0383] > <@shuyuguo:matrix.org> what are the two sums? +0.0 for the former and -0.0 for the latter? That's what they should be, if ruby didn't have the bug that [-0.0].sum gives +0.0 [17:04:12.0592] bakkot: mark me reviewed; altho i think the example should be a link and not "i have to google now" [17:04:15.0540] what i'm confused [17:04:19.0608] I did say Ruby's summation was a mess. :-) [17:07:36.0038] > <@rbuckton:matrix.org> Are there corner cases in arbitrary precision arithmetic that would be useful to point out in the specification? We do that in a number of places in the spec. there's cases with NaN/infinity/-0, which are handled explicitly; no other corner cases except overflow as long as inputs are finite (and it's hard to write down the overflow one) [22:26:01.0572] for the notes, which Justin offered explicit support to advance math.sum ? [22:26:23.0239] I _think_ it was JRL... ? [01:41:29.0020] Not me [01:41:50.0510] Too many Justins. [09:57:12.0015] Can someone in the room find someone from ServiceNow to pick us up from the reception? There is 10 of us stuck at reception here [10:14:45.0135] please add your name to the attendees list at the top of the meeting notes [10:20:09.0786] I disagree that "the syntax part of it would be the part slowing it down" [10:20:21.0629] the data model is just as likely to be problematic as the syntax [10:21:17.0399] > <@michaelficarra:matrix.org> the data model is just as likely to be problematic as the syntax Eemeli mentioned that this data model ends up working also with the other known formats thou [10:21:28.0981] > <@michaelficarra:matrix.org> the data model is just as likely to be problematic as the syntax * Eemeli mentioned that this data model ends up working also with the other known formats though [10:22:43.0038] FYI, the data model is at https://github.com/unicode-org/message-format-wg/tree/main/spec/data-model [10:27:44.0452] a Message is either a PatternMessage (with `declarations` and a `pattern`) or a SelectMessage (with `declarations` and `selectors` for indexing into `variants`, where each Variant is a list of `keys` to match and a `pattern`. And Pattern is an array in which each element is either a string or an Expression (representing e.g. a variable) or a Markup (representing something analogous to an HTML/XML start/end tag). [10:34:52.0446] Can we just version the syntax parser? Sorry, haven’t been able to listen to most of the proposal. [10:37:10.0389] If this is already going to be a spec at another standards body. [10:37:26.0752] it already is versioned: 2 [10:38:10.0900] shu: did not hear comments from you on intl.messageFormat; would you be ok with it going for stage 2 with just the data model and not the syntax? [10:40:18.0545] yes, that's fine with me [10:40:35.0932] my concerns need some systemic approach to address, and wouldn't be productive to ask individual proposals to deal with them [10:41:14.0209] to wit, concerns with how we distribute stdlib additions that won't benefit from independent implementations [10:45:45.0689] I wouldn't want to add all identity escapes to Unicode RegExps; that'd limit our evolution possibilities [10:46:42.0364] agreed but I wouldn't want to use any `\`+punctuator escapes for anything other than identity escapes, that would be very confusing [10:46:48.0693] so I don't think this actually meaningfully limits the languages [10:46:52.0147] * so I don't think this actually meaningfully limits the language evolution [10:47:28.0869] > <@bakkot:matrix.org> agreed but I wouldn't want to use any `\`+punctuator escapes for anything other than identity escapes, that would be very confusing yes, I agree with that as well [10:50:10.0115] ljharb: Didn't you intend to ask for stage 2.7? [10:50:12.0711] did I miss that? [10:50:53.0440] only if no changes were to be made [10:50:58.0876] > <@bakkot:matrix.org> agreed but I wouldn't want to use any `\`+punctuator escapes for anything other than identity escapes, that would be very confusing In general I agree that would be a bad idea, but I'd still rather not carve out syntax space across the board [10:51:02.0464] since everyone wanted the change, i'll ask for it at the next meeting instead [10:51:11.0695] right, ok [10:51:13.0946] * since nearly everyone wanted the change, i'll ask for it at the next meeting instead [10:51:30.0606] bakkot: I like Haskell's `\&` which terminates variable-length escapes that precede it [10:52:37.0746] oof, white on light blue is a very hard to read contrast :-/ [10:54:03.0265] this slide needs a bright red drop shadow on the text [10:54:07.0609] This transcriptionist is getting capitalization right even for terms not on the slides (SharedArrayBuffer) [10:54:08.0064] for readability :) [10:54:09.0594] I love them [10:54:34.0617] Time to audit Shu’s slides for WCAG compliance. [10:56:57.0061] yeah this transcriptionist seemed much better than usual [11:00:00.0655] > <@michaelficarra:matrix.org> it already is versioned: 2 But the concern was that it would change. Well, if it changes, give the new DSL a different parser version. [11:00:27.0949] Ie, split the parser from the format. [11:00:29.0376] uhhhh why is the meeting being recorded now [11:00:36.0833] did the presentation just say someone is recording [11:00:51.0140] I am fine with Shu being recorded if he wants that but I would prefer not to be recorded [11:00:56.0212] > <@nicolo-ribaudo:matrix.org> This transcriptionist is getting capitalization right even for terms not on the slides (SharedArrayBuffer) Aaand they just switched to somebody that puts newlines everywhere [11:02:02.0232] noooooooooo [11:09:03.0485] to reiterate: I accidentally triggered a kb shortcut that started the recording in zoom and immediately stopped it. I think it was recording for maybe... 1 second? [11:09:37.0927] why there is no confirmation for that, I have no idea [11:09:44.0953] zoom pops up a warning when it starts, but doesn't remove the recording when it stops, so i didn't realize it had stopped [11:10:42.0572] zoom would show it's recording near the top of the window IIRC [11:10:57.0480] in any case, def not recording, and apologies for the scare! [11:11:37.0522] Duncan MacGregor: Based on our conversations in the shared structs proposal, anything that could block would also have an async counterpart that could be used in the main thread (e.g., the "async locking" primitives discussed on one of the slides). [11:14:27.0304] Very much want non-blocking, concurrent collections for this case. [11:15:42.0797] Luca Casonato: do you have pointers where the move to remove the wasm handshake was discussed? I'd like to follow the developments, in particular regarding to this agent global syscall table it would likely introduce [11:18:13.0087] since danielrosenwasser's question wasn't asked verbally, it may be worthwhile to copy it into the notes for anyone reading afterwards [11:18:19.0272] > <@rbuckton:matrix.org> Duncan MacGregor: Based on our conversations in the shared structs proposal, anything that could block would also have an async counterpart that could be used in the main thread (e.g., the "async locking" primitives discussed on one of the slides). Thanks, I think an async API for condition varialbe might work, but my experience of writing concurrency libraries and reviewing concurrent code in general is that we should absolutely aim for higher level constructs because building them correctly from lower level ones is really hard and is not something we should generally be steering developers towards doing. [11:18:53.0673] > <@rbuckton:matrix.org> since danielrosenwasser's question wasn't asked verbally, it may be worthwhile to copy it into the notes for anyone reading afterwards Donw [11:19:05.0331] tokio is a good prior art for async concurrency primitives [11:19:08.0303] > <@rbuckton:matrix.org> since danielrosenwasser's question wasn't asked verbally, it may be worthwhile to copy it into the notes for anyone reading afterwards * Done [11:19:57.0612] > <@aardvark179:matrix.org> Thanks, I think an async API for condition varialbe might work, but my experience of writing concurrency libraries and reviewing concurrent code in general is that we should absolutely aim for higher level constructs because building them correctly from lower level ones is really hard and is not something we should generally be steering developers towards doing. In general, if you are depending on asynchrony to handle concurrency you can't expect performance if you are granular with locks in the main thread. In the browser, you're more likely to see Worker to Worker interactions with fine-grained locks, and more coarse-grained locks from UI thread to Workers. [11:21:46.0874] i think mark would say we should be building erlang instead of c++ [11:22:04.0102] > <@rbuckton:matrix.org> since danielrosenwasser's question wasn't asked verbally, it may be worthwhile to copy it into the notes for anyone reading afterwards apologies, didn't want to exhaust the timebox while I scrambled for the mic [11:22:49.0015] > <@danielrosenwasser:matrix.org> apologies, didn't want to exhaust the timebox while I scrambled for the mic Nah it's perfectly fine to not speak -- everybody sees TCQ anyway and the notes are manually edited for a reason :) [11:24:51.0808] can i get a timebox check? [11:26:01.0667] 10m [11:26:07.0955] 9 min [11:27:00.0748] 8 min [11:27:52.0438] we really need TCQ to display the time remaining [11:28:12.0835] 6 and three quarters [11:32:58.0568] 3 mins [11:34:06.0454] 1 min [11:34:15.0489] 55 seconds [11:34:19.0810] 50 [11:34:39.0037] what else are we even going to do in the remaining time before lunch though? [11:34:53.0922] > <@mhofman:matrix.org> Luca Casonato: do you have pointers where the move to remove the wasm handshake was discussed? I'd like to follow the developments, in particular regarding to this agent global syscall table it would likely introduce No. This is just what I understood from our initial call with Conrad. [11:34:55.0577] i am also curious of this kevin [11:38:13.0253] If WASM has shared structs and concurrency primitives, and JS doesn't, it will be almost no time between availability in WASM and the first `shared-structs` package on NPM that makes it available in JS with a poorer experience than we could provide. [11:38:59.0369] Improving the JS/Wasm API seems like a good thing to do independent of our decision here [11:39:02.0671] > <@bakkot:matrix.org> what else are we even going to do in the remaining time before lunch though? chairs asked me to do iterator chunking [11:39:08.0464] if we get wasm shared objects I'm immediately going to write a JS library which uses wasm and proxies to implement the shared structs proposal [11:39:21.0889] I think the JS proposal can be almost completely polyfilled based on the wasm one [11:39:35.0889] binaryen about to get a lot of npm downloads [11:40:04.0144] Is Ben Allen in this room? [11:40:13.0527] Yes [11:40:14.0049] > <@bakkot:matrix.org> I think the JS proposal can be almost completely polyfilled based on the wasm one Except syntax and the handshake complexity, and I'd really prefer we have actual syntax for this in JS. [11:40:50.0097] > <@rbuckton:matrix.org> Except syntax and the handshake complexity, and I'd really prefer we have actual syntax for this in JS. the current proposal has no syntax, does it? [11:40:54.0285] I've used the dev trial for shared structs, and syntax is so much better. [11:41:03.0832] > <@ljharb:matrix.org> the current proposal has no syntax, does it? The proposal intends to have syntax by stage 2. [11:41:09.0884] The dev trial does not [11:41:13.0232] ah :-/ [11:41:23.0448] > <@rbuckton:matrix.org> Except syntax and the handshake complexity, and I'd really prefer we have actual syntax for this in JS. handshake you can do if the library is run in the worker as well. for sure agreed that syntax would be good. this is mostly pointing out that erights' objection just does not make sense because we'll do it in JS anyway [11:41:24.0302] syntax, but the things produced are objects, not primitives? [11:41:44.0196] yes, objects [11:41:59.0468] > <@ljharb:matrix.org> syntax, but the things produced are objects, not primitives? the syntax is mostly just a special kind of `class` declaration [11:42:00.0434] seems strange to have syntax for that then [11:42:09.0987] oh ok, for declaration but not usage? [11:42:24.0676] yeah it's for declaring the "types" [11:42:25.0679] We cannot leverage `class` as is due to how fixed layout is determined, but the syntax is very close to `class` syntax. [11:42:44.0979] `class(shared)` [11:44:52.0887] The are a number of additional restrictions on shared structs that aren't compatible with `class` construction semantics, and one of our areas of exploration was how to handle thread-local prototypes and correlating struct definitions between two threads. [11:47:23.0612] but essentially the _syntax_ is the same as `class`. The `struct` keyword essentially indicates the difference in construction and layout. IIRC, syntax is also helpful for VMs that want to do static analysis and leverage the declaration to determine fixed layout. [11:50:50.0367] > <@bakkot:matrix.org> handshake you can do if the library is run in the worker as well. for sure agreed that syntax would be good. this is mostly pointing out that erights' objection just does not make sense because we'll do it in JS anyway I'd started experimenting with building this on top of a growable SharedArrayBuffer as well, though in that case you need to roll your own malloc and per-thread ref counting. And its not as fast due to all of the indirection and wrapping. [11:51:08.0908] and also serialization, presumably [11:51:13.0431] There's one possible world where this gets implemented in Wasm and then the syntax / polyfill is (at least initially) provided via build-time tooling. In particular, because Wasm functions don't close over nearly as much state as JS functions, shared behaviour seems strictly easier / cleaner to specify and implement in Wasm. [11:51:45.0663] There has been a lot of interest inside of Microsoft around the shared structs proposal. [11:53:29.0655] > <@iain:mozilla.org> There's one possible world where this gets implemented in Wasm and then the syntax / polyfill is (at least initially) provided via build-time tooling. In particular, because Wasm functions don't close over nearly as much state as JS functions, shared behaviour seems strictly easier / cleaner to specify and implement in Wasm. I've been very tempted to build `struct` syntax in TypeScript using the dev-trial implementation, even if only to test out the syntax. I'm not sure it is something we would ship if we never shipped syntax in JS. [11:55:34.0418] > <@iain:mozilla.org> There's one possible world where this gets implemented in Wasm and then the syntax / polyfill is (at least initially) provided via build-time tooling. In particular, because Wasm functions don't close over nearly as much state as JS functions, shared behaviour seems strictly easier / cleaner to specify and implement in Wasm. i think this is a misunderstanding -- wasm behavior easier _within wasm_. once it crosses the boundary you have the exact same problem [11:55:57.0953] another way to look at it is, the TLS syscall table _is_ solving the attaching behavior problem [11:56:19.0182] bakkot: it's much easier to write your own function for it yes, but it's still as ergonomic and readable as something built-in would be [11:56:24.0358] * bakkot: it's much easier to write your own function for it yes, but it's still not as ergonomic and readable as something built-in would be [11:58:08.0404] I think in Java, because it go for structural types but only nomitative ones, you woul chunk things in a stream by using a collector to build the objects that represent the chunks. [11:59:54.0051] shu: What do you mean by crossing the boundary? Suppose we improve Wasm-JS interop by (eg) adding a section to wasm that lists the exposed fields/methods, and expose those to JS. My understanding is that in that case, your shared wasm object would have a shared shape that points to shared methods, all of which live in the shared heap, and you don't have to worry about shared->unshared edges in the same way you do with thread-local shapes. [12:00:12.0431] The obvious downside is that the shared methods all have to be written in wasm [12:00:20.0332] iain: how do you call the shared methods? [12:00:51.0098] As a counterpoint to Mark's argument: `Worker` and `SharedArrayBuffer` already exist in JS and you can already get into trouble if you try to write multithreaded code and do so poorly, but that trouble often stems by JS not having adequate support for synchronization primitives and shared data, such that everyone needs to roll their own concurrency mechanism, and that's just plain worse. [12:02:54.0031] You can implement `Mutex` and `ConditionVariable` on top of SAB using Atomics today (and I have). You can implement a very limited shared structs on top of SAB today as well (and I have). What's missing is object references and GC support. [12:04:06.0916] shu: Hmm. You access the property, you get some sort of wrapper back that has a local->shared edge, and then you invoke it. Are you saying that the wrapper has the same problem? [12:04:58.0993] It seems like we could spec the wrapper as some sort of opaque immutable type where identity is unobservable, and then avoiding repeated allocations of the wrapper is an implementation detail [12:06:57.0046] I guess identity is observable via comparison [12:08:51.0891] Alternatively, couldn't the wrapper be a shared object itself? [12:58:14.0742] > <@iain:mozilla.org> shu: Hmm. You access the property, you get some sort of wrapper back that has a local->shared edge, and then you invoke it. Are you saying that the wrapper has the same problem? yep, exactly [12:58:39.0822] > <@iain:mozilla.org> Alternatively, couldn't the wrapper be a shared object itself? it _could_ be, but if it's a callable object, that basically means some weird, new exotic function [13:00:23.0161] That still seems preferable to the TLS ephemeron scheme [13:01:05.0437] i'm confused, how is this connected to the TLS ephemeron scheme? [13:01:08.0133] is this the same thing i wanted all those months ago [13:01:21.0703] I liked the idea of avoiding the wrapper using TLS... aren't these wrappers expensive? how would you avoid repeat allocation? [13:01:36.0612] i might be misunderstanding this doesn't seem connected to the TLS thing [13:01:47.0883] the TLS thing is needed for shared wasm to use unshared JS functions (web APIs) [13:01:58.0648] i thought iain was talking about the other direction: JS calling shared wasm function [13:02:09.0639] oh sorry for changing the subject; just catching up [13:02:21.0661] shu: I was talking about the local shape thing [13:02:31.0319] local shape? [13:02:43.0162] there are too many streams, sorry, might need to take it from the top at a later time [13:02:59.0556] shu: Thread-local prototypes [13:03:39.0639] iain: how do wrappers help there? [13:05:00.0433] My understanding of [this slide deck](https://docs.google.com/presentation/d/1iCuezMHZhTN560v9OuoLFIhKfjw5opV8LVilrZzOojw/edit#slide=id.g203f865f98c_0_373) is that we want to be able to attach behaviour to shared structs, but JS functions are necessarily not shared, so we need the TLS weakmap to assign thread-local prototypes. If wasm functions can be shared, then instead of thread-local prototypes, we can have shared prototypes, so we don't need the TLS weakmap or the ephemeron tracing. [13:05:51.0439] ah i see what you're saying [13:06:14.0037] I like the idea for sharing behavior by having this TLS point to an object which serves as the prototype of an object. This lets you have getters for fields. [13:06:49.0195] so then you need a way to allocate a Wasm GC object with a particular TLS field as a prototype [and presumably also a non-shared version, without using TLS] [13:06:55.0291] iain: i think that's morally equivalent to a new exotic callable that's sorta-kinda dynamically scoped. this was written off earlier in the design process because nobody i asked wanted new exotic callables [13:07:06.0411] i'm not deathly opposed to it but it's also a can of worms (i think) [13:07:11.0009] Not sure I understand where dynamic scoping comes in [13:08:20.0690] I was also under the impression that (aside from the question of how we expose it to JS) we got it mostly for free from the Wasm proposal, although I admit that I have been paying more attention to the JS side [13:09:08.0789] suppose the wasm function traps and needs to throw an exception. this exception needs to be materialized somehow. currently this is one of the ways in which functions are "deeply unshareable" in that you create Error instances from the _realm in which the function was created_ [13:09:21.0198] this is a question that JS wrappers of shared wasm functions still need to answer [13:09:30.0873] an easy answer is: the realm of the wrapper, the wrapper is unshared [13:09:44.0871] a harder answer is: maybe the caller realm (what i meant by dynamic scope), since it's a special exotic callable [13:10:48.0686] but i take the point this may be a promising avenue to explore again, in light of the wasm angle [13:11:17.0752] Ah, I see. And the wasm proposal doesn't have to deal with this because the Error instance doesn't exist in wasm [13:11:29.0282] It's just trapping and then the world ends? [13:11:38.0285] yep [13:11:53.0128] and it doesn't have a notion of like "this realm's Array constructor" or whatever either [13:12:06.0758] a lot of the "original sin" comes down imo to JS functions being _too_ first class [13:12:38.0381] ... I remember using "LiveScript" on the server around the same time it was introduced for the browser and became known as JavaScript ... [13:13:24.0174] in Netscape SuiteSpot Server, IIRC [13:13:24.0241] Are there implementation issues with a special exotic callable, or is the blocker there just the problem of specifying it? [13:13:42.0276] i haven't thought deeply about impl concerns [13:13:56.0895] IIRC it was more about language complexity [13:14:16.0212] From an implementation perspective I think I would prefer the exotic callable, but maybe there's something I'm missing [13:14:22.0350] (like, these special things have a different `.apply` or something? different `.bind`?) [13:16:47.0563] Let's go back to the wrapper idea for a second. Regular non-shared JS object, with the Function prototype for `.apply` and friends. Freeze it so that it's completely immutable. [13:17:36.0163] which realm's Function prototype? [13:18:12.0977] The current realm? Maybe there's a separate instance per-realm. [13:18:33.0395] then isn't that... TLS prototypes [13:19:12.0940] What I'm trying to think through is whether we can just keep it in a weak map that doesn't care about other threads, because if there's no local edge to it and you collect it, then you just create it again from scratch [13:19:41.0237] You won't have pointer identity, but that's unobservable because we've postulated that we could collect it, so there wasn't another copy of the pointer [13:19:43.0339] oh [13:19:57.0472] that's a different semantics that Luke Wagner brought up in a different context [13:20:04.0162] i didn't have time to get to it during the agenda item [13:20:35.0602] it's just kinda slow to have all these weak maps and wrappers, isn't it? [13:20:47.0957] yeah [13:20:57.0178] definitely needs to be validated [13:21:08.0850] leobalter: can you add your name to the notes document? [13:21:29.0857] i feel like there is too much nuance for us to ever come up with a more concrete process than what we currently have [13:22:39.0686] shu: SM is working on an architectural review of shared structs. Hoping to have it ready soon, although there's been enough new information today that it will take a little bit to digest it. [13:22:52.0074] Are there regular meetings for this proposal? Maybe I should be attending them [13:23:37.0184] > <@iain:mozilla.org> shu: SM is working on an architectural review of shared structs. Hoping to have it ready soon, although there's been enough new information today that it will take a little bit to digest it. there is a working call on the TC39 calendar, yeah [13:23:48.0107] and cool! looking forward to review [13:24:57.0799] that was a beautiful point Richard Gibson: "lone" objectors are possibly only alone because the people they represent aren't in the room [13:25:57.0977] or, are in the room but unwilling to speak up - not everyone has the same comfort level with dissent [13:26:20.0212] I'm not as sympathetic to that ljharb [13:26:32.0634] Shane (SFC) can you add your name to the notes document? [13:26:32.0639] dissenting typically implies responsibility for finding a solution as well [13:26:41.0480] * dissenting typically implies responsibility for finding a solution as well, its not something you always want to deal with [13:26:44.0861] > <@michaelficarra:matrix.org> I'm not as sympathetic to that ljharb i think sympathy to that should match 1:1 with sympathy to concerns about inhibiting newcomers [13:26:48.0738] while that's sometimes true, it's also often not true; some delegates work on things that no one else is really doing, or have concerns about language specification purity which are relevant only to consumers of the language specification, rather than to developers [13:27:07.0678] > <@devsnek:matrix.org> dissenting typically implies responsibility for finding a solution as well, its not something you always want to deal with sometimes yes. but there isn't always a solution to be had, and people often have trouble accepting that. [13:27:19.0436] > <@devsnek:matrix.org> dissenting typically implies responsibility for finding a solution as well, its not something you always want to deal with * sometimes yes. but there isn't always a solution to be had, and people often have trouble accepting it when there is none. [13:27:24.0588] diffusion of responsibility is often at play [13:30:28.0038] At the time that unanimity was established was when only VM implementers were present at the table and there was no point in making a standard that any one of them was unwilling to implement. [13:31:12.0110] I’m in favor of keeping the consensus by unanimity, even though we’re not living in that historical context. [13:31:26.0319] i very strongly agree with everything mark is saying right now [13:31:39.0153] Is there a list of "known phrases" that the bot knows about? [13:31:43.0891] * Is there a list of "known phrases" that the transcription bot knows about? [13:31:48.0259] danielrosenwasser: we have a human transcriptionist [13:31:56.0885] oh but for the transcribe bot? yes but it's very very short [13:32:10.0207] `EMCAScript` keeps getting put in the notes [13:32:12.0761] ``` const REPLACEMENTS = [ [/\bsho(?:e|ot?)\b/gi, 'Shu'], [/\b(, )?u(h|m),?\b/gi, ''], [/\bIntel\b/gi, 'Intl'], [/\bagalya\b/gi, 'Igalia'], [/\bregalia\b/gi, 'Igalia'], [/\bgalia\b/gi, 'Igalia'], ]; ``` [13:32:33.0223] I truly wonder if a decision regarding the consensus process requires TC consensus or actual member vote. [13:33:11.0395] the catch 22 which must not be named [13:33:14.0616] a member vote would suffice but that'd be a failure of the consensus process that we all currently agree to follow [13:34:48.0573] Consensus should be ideal, but it seems like a can of worms otherwise. We are using consensus to change what consensus means. It's not a simple process. [13:35:05.0435] > <@devsnek:matrix.org> i very strongly agree with everything mark is saying right now I disagree with the idea that "do nothing" is "fail safe". I particularly disagree with it in light of the previous conversation; I really wish it were better understood that failing to provide a good story for parallelism on the web means the experience of using the web is notably slower than it should be, and that is a cost which is measured in small fractions of billions people's lives every day [13:35:28.0438] I realize that is maybe dramatic but it's also true and we ought to care about that cost [13:35:35.0865] ps if it takes 2 member companies to veto, then that means it only costs $7000 to block anything. [13:35:44.0993] Too much that can be discussed as formality. We need this to evolve more to discuss the format [13:36:14.0265] > <@bakkot:matrix.org> I realize that is maybe dramatic but it's also true and we ought to care about that cost if persuasion and discussion are not effective at convincing objectors to care about that cost then i don't think the solution is silencing that objector's voice [13:36:15.0120] ecma is literally pay to participate though [13:36:20.0412] ljharb: that would be bad faith [13:36:27.0474] we would just ignore it [13:36:45.0717] > <@michaelficarra:matrix.org> ljharb: that would be bad faith absolutely it would. but it wouldn't be provable. [13:37:14.0572] i'm not saying it's a reasonable tactic, i'm just reinforcing that it's impossible to prevent weaponization [13:37:14.0750] > <@bakkot:matrix.org> I disagree with the idea that "do nothing" is "fail safe". I particularly disagree with it in light of the previous conversation; I really wish it were better understood that failing to provide a good story for parallelism on the web means the experience of using the web is notably slower than it should be, and that is a cost which is measured in small fractions of billions people's lives every day i agree that this is frustrating but i can't think of a process that strictly improves this problem in the general sense [13:37:18.0766] > <@ljharb:matrix.org> if persuasion and discussion are not effective at convincing objectors to care about that cost then i don't think the solution is silencing that objector's voice if the objector will not change their mind, then we weight the cost of overruling them against the cost of doing nothing, and I think in some cases - notably in the case of parallelism - the cost of doing nothing is _overwhelmingly_ higher [13:37:27.0136] > <@ljharb:matrix.org> if persuasion and discussion are not effective at convincing objectors to care about that cost then i don't think the solution is silencing that objector's voice * if the objector will not change their mind, then we weigh the cost of overruling them against the cost of doing nothing, and I think in some cases - notably in the case of parallelism - the cost of doing nothing is _overwhelmingly_ higher [13:37:29.0606] > <@ljharb:matrix.org> ps if it takes 2 member companies to veto, then that means it only costs $7000 to block anything. you can't just pay to block things. Hax tried this and it didn't work. [13:37:54.0078] right. so it didn't work despite our current process [13:38:04.0540] * right. so it didn't work despite our current process. so changing it won't stop it from working any further. [13:38:26.0304] * right. so it didn't work despite our current process. so changing our process won't stop it _more_ from working. [13:38:32.0398] it didn't work for one main reason, which is that he was part of the outgroup [13:38:46.0445] the weaponization msaboff alludes to is by members of the long-standing ingroup [13:40:29.0310] As we'll likely run out of time here, my thought: We should mitigate the negatives of a lone objector blocking process. One way to do that would be to automate the re-presentation of decisions with a lone objector at a near-future meeting, allowing and expecting discussion to happen in the interim. So effectively require _sustained_ objection to block a thing with a small minority. [13:40:29.0903] 😞 this was nowhere near enough time for this topic [13:40:54.0333] * As we'll likely run out of time here, my thought: We should mitigate the negatives of a lone objector blocking progress. One way to do that would be to automate the re-presentation of decisions with a lone objector at a near-future meeting, allowing and expecting discussion to happen in the interim. So effectively require _sustained_ objection to block a thing with a small minority. [13:41:50.0405] > <@eemeli:mozilla.org> As we'll likely run out of time here, my thought: We should mitigate the negatives of a lone objector blocking progress. One way to do that would be to automate the re-presentation of decisions with a lone objector at a near-future meeting, allowing and expecting discussion to happen in the interim. So effectively require _sustained_ objection to block a thing with a small minority. I think that would actually be _worse_ than the current process; I don't think anyone who lone-objects at one meeting under the current process would not also want to lone-object at the next meeting, so it would just be about whether they had the resources to attend the next meeting [13:42:01.0530] which is very much not the criteria we ought to use [13:42:21.0157] omg I agree so hard with Dan right now [13:42:37.0137] you also agreed hard with mark earlier [13:42:40.0042] confused [13:42:47.0071] not me [13:42:51.0500] ah, my bad [13:42:53.0060] i agreed with mark [13:43:10.0441] but yes i also agree with dan [13:44:17.0785] I should've also said: blocks are really really really discouraging and *do* stop progress, even if people don't mean it to [13:44:18.0765] i'm not against improving things, i just feel like we're playing with a very delicately balanced bomb [13:44:39.0758] I honestly just hope we end some paths for delegate burnout. This is a very sensitive topic and I'd love to keep the convo when time allows. [13:44:52.0238] Blocks definitely cause delegate burnout, this is unquestionable [13:45:15.0880] it has many knock on effects, delegate burnout the worst among them for individual well-being [13:45:17.0687] I also should've said: I'm really confident that everyone here just wants what's best for JS, and we're just trying to figure out the way to collect the data and judgements we're all bringing [13:45:50.0900] TC39 lost some considerate participations and I totally sympathize with the idea of trying to resolve this. I don't have an answer ready on how we do this. [13:45:54.0365] it encourages shop venue, and in the limit, it encourages erosion of the weight of tc39 itself [13:46:01.0752] * it encourages to shop venues, and in the limit, it encourages erosion of the weight of tc39 itself [13:50:58.0119] lol stop putting new things on the queue please, we're trying to drain it [13:51:01.0587] it would be an improvement if voices had the same weight. Right now, we weigh people higher if they have a propensity to veto [13:52:25.0624] i don't think voices should have the same weight [13:52:33.0611] but giving propensity to veto higher veto is much worse than equal weight [13:52:44.0772] * but giving propensity to veto higher weight is much worse than equal weight [13:53:10.0674] We should understand what different stakeholders represent, and make decisions with that in mind. But I think the committee currently has equality as a goal/mostly shared value, and I hope it stays that way, and that we can reinforce it more. [13:55:36.0636] I think I would put it this way: The veto process means that we say the risk of doing the wrong thing is _always_ more than the risk of doing nothing. And that's just not true. Some things, sugar especially, doing nothing is relatively costless; some things, new capabilities and APIs for performance, the cost of doing nothing is actually quite high. Our process should allow seriously weighing the costs of doing nothing, and not privilege the costs of doing the wrong thing as the ultimate determinant. [13:56:23.0598] msaboff: I highly encourage we continue discussing this. Thank you for bringing it up to TC39! [13:56:47.0986] * I think I would put it this way: The veto process means that we say the risk of doing the wrong thing is _always_ more than the risk of doing nothing. And that's just not true. Some things, sugar especially, doing nothing is relatively costless; some things, like new capabilities and APIs for performance, the cost of doing nothing is actually quite high. Our process should allow seriously weighing the costs of doing nothing, and not privilege the costs of doing the wrong thing as the ultimate determinant. [13:58:06.0632] does anyone remember which meeting shadowrealms was dropped to stage 2? [13:58:15.0069] Per what danielrosenwasser said, it would definitely help if lone dissenters became actively involved in the proposal to help address concerns. Vetoing a proposal and walking away when that proposal has otherwise broad support isn't helpful. [13:58:35.0822] > <@ljharb:matrix.org> does anyone remember which meeting shadowrealms was dropped to stage 2? sept 2023 iirc [13:58:38.0631] ("relatively costless" is the wrong way of putting it, since in every case blocking certainly has costs on delegates, which are quite real and I don't want to leave those out.) [13:58:56.0197] * ("relatively costless" is the wrong way of putting it, since in every case blocking certainly has costs on delegates, which are quite real and I don't want to leave those out. but the costs are of a different kind than the costs of the web being slower) [13:59:05.0152] To be clear, I am okay with people saying "this is just a matter of taste", but I am frustrated when the feedback is left as an exercise to the champion. [13:59:07.0130] * ("relatively costless" is the wrong way of putting it, since in every case blocking certainly has costs on delegates, which are quite real and I don't want to leave those out. but the costs are of a different kind than the costs of the web being slower or otherwise worse for users) [13:59:25.0045] * To be clear, I am *somewhat* okay with people saying "this is just a matter of taste", but I am frustrated when the feedback is left as an exercise to the champion. [13:59:30.0338] i am not okay with people saying it's a matter of taste when it's not a matter of taste though! [13:59:48.0036] chairs: queue needs advancing [13:59:50.0983] > <@bakkot:matrix.org> I think I would put it this way: > > The veto process means that we say the risk of doing the wrong thing is _always_ more than the risk of doing nothing. And that's just not true. Some things, sugar especially, doing nothing is relatively costless; some things, like new capabilities and APIs for performance, the cost of doing nothing is actually quite high. > > Our process should allow seriously weighing the costs of doing nothing, and not privilege the costs of doing the wrong thing as the ultimate determinant. i agree with this but its also a subjective judgement [13:59:56.0756] how do you come to agreement on it [14:00:03.0415] bakkot: That would seem to suggest that we would need different rules for consensus for different kinds of changes. Perhaps we can use consensus to weaken consensus selectively. [14:00:46.0440] but a person "abusing the process" could just... not agree to weaken it [14:01:34.0153] > <@kriskowal:matrix.org> bakkot: That would seem to suggest that we would need different rules for consensus for different kinds of changes. Perhaps we can use consensus to weaken consensus selectively. well, in some way we've already been cautiously starting to do this, with non-binding polls for choices that we all agree are aesthetic/unimportant. I think this is really positive and should continue! [14:03:57.0198] i agree - ad hoc consensus to allow a lower bar to agreement is a wonderful way to preserve the safety of complete consensus while reducing friction where it's not necessary [14:04:13.0529] if we can come up with a way to do that in general, as opposed to ad hoc, that would be great [14:04:21.0683] * if we can come up with a way to do that in general, as opposed to ad hoc, that would be great (for scenarios where it applies) [14:04:35.0493] > <@ljharb:matrix.org> i agree - ad hoc consensus to allow a lower bar to agreement is a wonderful way to preserve the safety of complete consensus while reducing friction where it's not necessary I think we need to solve this in abstract, since once somebody wants to block something concrete there is no reason for them to give consensus to ignore their consensus [14:04:40.0414] > <@ljharb:matrix.org> i agree - ad hoc consensus to allow a lower bar to agreement is a wonderful way to preserve the safety of complete consensus while reducing friction where it's not necessary * I think we need to solve this in abstract, since once somebody wants to block something concrete there is no reason for them to give consensus to ignore their non-consensus [14:04:46.0200] i agree with snek tho that it'll be difficult to come up with an objective rubric for that [14:05:05.0086] These sorts of consensual processes can definitely help us, but we still need some way of handling situations of contentious vetoes. [14:05:13.0340] > <@nicolo-ribaudo:matrix.org> I think we need to solve this in abstract, since once somebody wants to block something concrete there is no reason for them to give consensus to ignore their non-consensus i agree that solving it in general prevents that kind of potential conflict on an ad-hoc basis [14:05:22.0201] > <@ljharb:matrix.org> does anyone remember which meeting shadowrealms was dropped to stage 2? September 23 [14:05:43.0693] > <@littledan:matrix.org> well, in some way we've already been cautiously starting to do this, with non-binding polls for choices that we all agree are aesthetic/unimportant. I think this is really positive and should continue! yes.. voting on advancing a proposal is a very different kettle of fish compared to voting for bikeshedding-type decisions [14:06:16.0656] > <@bakkot:matrix.org> I think I would put it this way: > > The veto process means that we say the risk of doing the wrong thing is _always_ more than the risk of doing nothing. And that's just not true. Some things, sugar especially, doing nothing is relatively costless; some things, like new capabilities and APIs for performance, the cost of doing nothing is actually quite high. > > Our process should allow seriously weighing the costs of doing nothing, and not privilege the costs of doing the wrong thing as the ultimate determinant. this is a really important point [14:07:16.0598] > <@softwarechris:matrix.org> yes.. voting on advancing a proposal is a very different kettle of fish compared to voting for bikeshedding-type decisions one issue is, there isn't always a shared understanding about what's bikeshedding and what's very significant. I often find myself thinking that something is bikeshedding that others thing is very significant. [14:07:19.0932] it is probably a very small number of times it would come up but if there are decisions that need to be made in a timely manner, that could mean the need to vote. this is what the CSS WG does.. but again, ONLY if a decision must be made [14:07:45.0650] > <@littledan:matrix.org> one issue is, there isn't always a shared understanding about what's bikeshedding and what's very significant. I often find myself thinking that something is bikeshedding that others thing is very significant. sure, err on the side of caution in those cases then [14:07:57.0593] TIL [14:07:59.0431] i think that's exactly the problem - if we all agree it's bikeshedding the contention doesn't manifest [14:08:10.0556] makes you wonder where these phrases come from [14:08:13.0188] > However, if a decision is necessary for timely progress and consensus is not achieved after careful consideration of the range of views presented, the Chairs may call for a group vote and record a decision along with any objections. [14:08:13.0876] but when one person thinks something is critical and another thinks it's trivial, it often gets tense [14:08:19.0454] > <@softwarechris:matrix.org> > However, if a decision is necessary for timely progress and consensus is not achieved after careful consideration of the range of views presented, the Chairs may call for a group vote and record a decision along with any objections. from CSS WG charter [14:09:05.0168] maybe! I find that a lot of these cases are the ones where we make decisions by being held hostage, which can be suboptimal. [14:10:20.0930] what is timely progress [14:10:40.0822] chair discretion [14:11:02.0435] the chair is a very powerful role and I think we kind of take that for granted in this group [14:11:14.0587] they don't need to be this generous [14:11:18.0507] historically the chair has had zero power [14:11:20.0770] i think historically the TC39 chair is one of the weaker positions as far as standards body chairs go [14:11:29.0236] that power has been slowly increasing, in a good way [14:11:31.0064] our chairs are also delegates, we can't escalate decisions to them without conflict of interest [14:12:05.0245] our chairs reliably recuse themselves when there is a conflict [14:12:07.0323] historically also, the chair had no interest in the specifics of language changes. [14:13:26.0667] don't ever elect me as chair because I wouldn't hesitate to wield its power (thoughtfully) [14:13:33.0721] Thank you for noticing Michael. Each the chairs maintain a list of topics that we have an interest in to ensure that we do not chair those topics. But we don't really shout about this. [14:13:45.0805] * Thank you for noticing Michael. Each meeting the chairs maintain a list of topics in advance that we have an interest in to ensure that we do not chair those topics. But we don't really shout about this. [14:14:08.0443] I can tell you unequivocally that the chairs, as chairs, feel strongly about making absolutely no decisions for the committee, as much as possible, beyond purely administrative things and similar things where burdensome to committee [14:14:48.0935] I would also be fine with the chairs being a little more authoritative, especially during plenary [14:15:10.0847] honestly, if we did strongly decide to do something like this, I'd recommend this be done by the secretaries [14:15:21.0318] the less noticeable we are, the better [14:16:03.0262] > <@usharma:igalia.com> honestly, if we did strongly decide to do something like this, I'd recommend this be done by the secretaries do you mean by Samina, the TC39 secretary? [14:16:09.0828] > <@littledan:matrix.org> do you mean by Samina, the TC39 secretary? yes [14:16:10.0183] > <@usharma:igalia.com> honestly, if we did strongly decide to do something like this, I'd recommend this be done by the secretaries if we're worried about a conflict of interest, ecma receives more money from ordinary members than associates, so there may be a conflict there [14:16:10.0871] as pointed out above, chairing the meeting is an administrative role that allows us to facilitate while being delegates [14:16:29.0693] > <@usharma:igalia.com> honestly, if we did strongly decide to do something like this, I'd recommend this be done by the secretaries * if we're worried about a conflict of interest, ecma receives more money from ordinary members than associates, so there may be a potential conflict there (obv,. hopefully not) [14:16:31.0874] * as pointed out above, chairing the meeting is an administrative role that allows us to facilitate topics we are neutral about while being delegates [14:16:45.0261] > <@usharma:igalia.com> as pointed out above, chairing the meeting is an administrative role that allows us to facilitate topics we are neutral about while being delegates yeah it just sounds like too much work to do this and also mediate all conflicts... [14:17:51.0773] > <@softwarechris:matrix.org> the less noticeable we are, the better we used to have a chair that you could forget was even in the room (aside from the snoring), and I can assure you, I prefer the chairs to be more noticeable than that [14:18:26.0418] I mean, there's nuance, but I think you get what I mean 🙂 [14:18:27.0807] doesn't mean we want to overcorrect tho :-) [14:19:02.0126] > <@littledan:matrix.org> yeah it just sounds like too much work to do this and also mediate all conflicts... suddenly the role has a lot more responsibility and weight and I don't think any organization would be incentivized to allow delegates to be in this position [14:19:15.0712] I like the charis giving chocolate and hats to bribe delegates [14:19:21.0257] to put it simply, we don't want to be making decisions that are committee decisions [14:21:11.0997] right so I think we need a procedure for *delegates* to contest vetoes (after the meeting, since during the same meeting would be too fast/chaotic/unconsidered) [14:21:32.0527] rather than asking the chairs to constantly adjudicate by themselves on everything [14:23:58.0479] and we now have a Stage 2.7 section https://github.com/tc39/proposals?tab=readme-ov-file#stage-27 [14:24:57.0007] anyway more dispassionately i also think the lone veto thing actually is great for small groups (the older, smaller, closer-knit TC39) but doesn't scale [14:25:22.0992] like you don't want a family of 4 to vote on all decisions, that will be bad [14:26:47.0745] Spec invariants and subgroups would go a long way to making TC39 scale. I am eager to write a blank check to Intl. [14:27:21.0209] I am somewhat less eager to write a blank check to Intl [14:27:38.0692] Yeah, I don’t mean everyone. I mean me. [14:27:38.0979] I am fine leaving the decisions which are just internationalization to subgroups, but not overall questions of API design [14:27:51.0613] bakkot you'll need to sustain your objection to writing a blank check to intl [14:28:02.0231] A “I hereby waive my interest in a veto on Intl provided it maintains these here invariants.” [14:28:33.0090] > <@bakkot:matrix.org> I am fine leaving the decisions which are just internationalization to subgroups, but not overall questions of API design Not even if its a subgroup focused on general API design within JS? [14:28:58.0455] rbuckton: sorry, I was referring only to Intl specifically [14:29:15.0053] I am fine with subgroups in general but not taking the output of any subgroup wholesale into the language [14:29:38.0125] there are some questions best left to subgroups but most things involve some questions which are not of that kind [14:29:44.0474] * there are some questions best left to subgroups but most proposals involve some questions which are not of that kind [14:30:29.0988] The DOM as an API subgroup. [14:30:54.0961] my brother i'm pretty sure we are the subgroup [14:31:03.0486] i definitely think that establishing a thorough list of invariants will drastically reduce lone objections [14:32:22.0278] seems pretty obvious to me [14:33:15.0927] thinking about the lone objections I can remember I am not sure I can think of any which could have been handled by a list of invariants? except invariants like "no new unreachable intrinsics" or "no shared-state parallelism", neither of which would have gotten consensus to be on such a list [14:34:16.0461] I would like to see a thorough list of invariants be a high-priority goal regardless, but I agree with Kevin here [14:35:41.0526] the invariants project will need to contend with the fact that a lot of the invariants that people care about the most will be absent from the list of invariants which has committee consensus. For this reason, I think the first step should be to document all the concerns that some people are thinking about (as has already begun in how-we-work), rather than get consensus on it. [14:36:33.0937] i don't like the idea of consensus seeking on invariants [14:36:40.0181] invariants i think are particular reflections of goals [14:36:49.0109] i want some semblance of understanding of goals [14:36:52.0861] that's a fair point. having a list of invariants, some of which have consensus and many of which won't, would still be helpful [14:37:10.0972] * (re kevin and dan) that's a fair point. having a list of invariants, some of which have consensus and many of which won't, would still be helpful [14:37:12.0586] goals as scoped as possible, of course [14:37:17.0921] (re shu) also a good point [14:37:20.0395] i don't think "more better js" is a valid goal [14:43:43.0422] @shu would you mind taking a quick look at the conclusion/resolution for ShadowRealm? I want to make sure I'm not missing anything. [14:43:52.0413] * shu: would you mind taking a quick look at the conclusion/resolution for ShadowRealm? I want to make sure I'm not missing anything.e [14:45:22.0987] I kind of like the idea of markdown fences as an alternative to escaping `` ` `` and ` ${ ` and end-of-string `\`, but I don't have a strong preference. [14:46:40.0277] it might be nice to allow N backticks, paired, to change what needs to be escaped? [14:47:02.0145] ``` foo```` ``` is already legal, alas [14:47:02.0386] like with a single backtick, you have to escape backticks; but if you put, say, three, you'd only have to escape a set of triple backticks [14:47:03.0708] I thought that was in the proposal when I reviewed it last week. [14:47:05.0839] ah true [14:47:35.0509] > <@leobalter:matrix.org> shu: would you mind taking a quick look at the conclusion/resolution for ShadowRealm? I want to make sure I'm not missing anything.e done, lgtm [14:47:45.0489] > <@bakkot:matrix.org> ``` > foo```` > ``` > is already legal, alas legal and at least possibly sensible e.g. https://gist.github.com/michaelficarra/70ce798feb25fdc91508f387190053a1 [14:47:57.0709] that said, it might still be web-compat [14:48:08.0943] but changing existing parses is scary [14:48:33.0049] When I looked at it before, it was ```` @``` ````, with a n+3 backticks that must be matched, as long as its one more backtick than the number of contiguous backticks in the body. [14:49:31.0314] > <@bakkot:matrix.org> ``` > foo```` > ``` > is already legal, alas …Wait, what does this parse as, again? [14:49:41.0559] Syntax isn't a Stage 1 concern… [14:49:56.0476] Do we want to explore this? If so, we'll define syntax when we explore it. [14:50:16.0889] but markdown fences are tricky in that ``` `` ` `` ``` ignores the leading and trailing whitespace to avoid it being treated as a contiguous run of backticks [14:50:51.0245] > <@jschoi:matrix.org> …Wait, what does this parse as, again? ``` (foo``)`` ``` [14:50:58.0496] > <@jschoi:matrix.org> …Wait, what does this parse as, again? `````` foo```` `````` is the same as `````` (foo``)`` `````` [14:51:23.0144] should've added an early error on that [14:51:34.0127] or a lookahead [14:51:54.0466] yeah I tend to agree [14:51:55.0679] oh well [14:52:03.0949] where's the fun in that snek ? [14:52:13.0255] lol [14:52:20.0822] doubled punctuators being special is well-precedented [14:52:25.0552] it's JavaScript, you're supposed to be able to construct horrors [14:52:30.0568] lets use `r#""#` like rust [14:53:16.0650] > <@michaelficarra:matrix.org> it's JavaScript, you're supposed to be able to construct horrors ``` foo`` `` ``` is not... less horrible [14:53:47.0175] > <@jridgewell:matrix.org> Syntax isn't a Stage 1 concern… Meta: do people find it valuable to get constraints earlier even at proposal advancement meetings? I would think it is helpful. [14:53:59.0287] > <@devsnek:matrix.org> lets use `r#""#` like rust or just `r"" ""`, I don't think you need the `#`s? [14:54:10.0851] I really like the problem we are trying to resolve having used this feature within different languages ie Perl. Even thou, I don't know if I'd have the energy to pursue this string proposal considering it needs us to elect a token [14:54:20.0975] > <@jridgewell:matrix.org> Syntax isn't a Stage 1 concern… * Meta: do people find it valuable to get constraints for later stages, even at earlier proposal advancement meetings? I would think it is helpful. [14:54:29.0419] Sure, I think "desire for minimal syntax" is a good thing to bring up, but "I don't like `#" isn't [14:55:12.0521] yeah Mark's reaction was basically my reaction too [14:55:21.0583] I want a better `String.raw` and would consider that in scope for this proposal... [14:55:49.0756] https://github.com/tc39/proposal-string-cooked/issues/13 [14:56:21.0106] > <@danielrosenwasser:matrix.org> Meta: do people find it valuable to get constraints for later stages, even at earlier proposal advancement meetings? I would think it is helpful. for me personally, yes; although in the form of 'potential concerns', rather than 'constraints'; I believe it's premature to have dealbreakers for future stages at that point [14:57:29.0802] > <@bakkot:matrix.org> I want a better `String.raw` and would consider that in scope for this proposal... Isn't the point of this that you don't need `String.raw` with it? Why would that be in scope? [14:57:46.0917] > <@danielrosenwasser:matrix.org> Meta: do people find it valuable to get constraints for later stages, even at earlier proposal advancement meetings? I would think it is helpful. I would prefer to not always ask for consensus at the end of the timebox, but have some time _after_ getting stage 1 for "ok now, anything else I should consider?" [14:58:12.0265] > <@rbuckton:matrix.org> Isn't the point of this that you don't need `String.raw` with it? Why would that be in scope? part of the problem statement, which is the stage 1 thing, is that `String.raw` doesn't work [14:58:21.0570] Maybe "here documents for JS" [14:58:33.0198] hence if we could have a version of `String.raw` which had fewer edges, that would be in the direction of solving the problem [14:58:39.0895] * hence if we could have a version of `String.raw` which had fewer sharp edges, that would be in the direction of solving the problem [14:58:50.0300] Isn't that just a side-effect of special `\` escapes? [14:58:50.0381] what's the exact title? [14:59:00.0577] bakkot: Did you agree with my problem statement? Please feel free to edit it [14:59:15.0751] > <@ljharb:matrix.org> what's the exact title? "Improved escapes for template literals" I think? [14:59:32.0641] A better `String.raw` doesn't solve `` \` ``, `` \${ `` and end-of-string `\` [14:59:38.0307] > <@littledan:matrix.org> bakkot: Did you agree with my problem statement? Please feel free to edit it sgtm [14:59:54.0369] * A better `String.raw` doesn't solve `\${` and end-of-string `\` [15:00:19.0738] * A better `String.raw` doesn't solve `` \` ``, `\${`, and end-of-string `\` [15:00:45.0134] That is 100% a syntax issue, no amount of API support can fix it. [15:01:40.0883] Maybe there are improvements that could be made for `String.raw`, but that won't address the main concerns this proposal seeks to address. [15:02:29.0731] > <@bakkot:matrix.org> https://github.com/tc39/proposal-string-cooked/issues/13 `String.rare` does not really solve the problem, u still need to do many escaping, and it also make the escaping rule much complex. [15:04:07.0285] NB: topics have shuffled a bit on the schedule [15:06:15.0175] > <@rbuckton:matrix.org> When I looked at it before, it was ```` @``` ````, with a n+3 backticks that must be matched, as long as its one more backtick than the number of contiguous backticks in the body. This is the draft in repo, I use Swift-style in the slides because I thought the concrete syntax is not important in stage 1 meeting. Sorry for bring confusion. [15:06:18.0531] As a syntax, you don't need to limit yourself to `@` and `#` as there are other infix tokens that could be made into a prefix token. For example, you could use ```` \``` ... ``` ```` to mean "I've done all the escaping I need to do at the start and end of the string" [15:07:25.0093] Yeah, I understand there are many possibilities, I just use the syntax which already have precedents in other languages as example. [15:07:35.0331] It does cause problems for tagged templates though... [15:08:10.0611] * Infix tokens do cause problems for tagged templates, though ```` \``` ```` doesnt [15:08:13.0723] * Infix tokens do cause problems for tagged templates, though ````\``````` doesn't [15:08:30.0327] * Infix tokens do cause problems for tagged templates, though ```` \``` ```` doesn't [15:08:54.0243] > <@bradfordcsmith:matrix.org> Maybe "here documents for JS" But if "improved template literal" it very unlikely we could have "here doc" style solution. [15:16:49.0448] > <@rbuckton:matrix.org> Maybe there are improvements that could be made for `String.raw`, but that won't address the main concerns this proposal seeks to address. I think you just need to partially cook the `raw` string [15:17:05.0212] The same way dedent is (fully) cooking the dedented raw string [15:17:59.0546] You'll still need to escape the 3 cases, but those escape sequences won't appear in the rare output (all other escapes would) [15:18:50.0284] * You'll still need to escape the [3 cases](https://gist.github.com/jridgewell/2685608246f0a43cd1c3f3177eabb5ef), but those escape sequences won't appear in the rare output (all other escapes would) [15:20:04.0666] > <@haxjs:matrix.org> But if "improved template literal" it very unlikely we could have "here doc" style solution. ``` const myEmbeddedString = String.dedent( ``delimiter text`` Whatever I want to have here as long as this ends with ``delimiter text``); ``` [15:20:35.0429] I think the interesting thing about the proposal is that you don't need to escape anything, with the exception being `${`, but that could also be tied to the opening of the fenced string literal. The Explainer used n+1 `@` tokens, but could just as easily use n+1 `\` tokens, etc. [15:23:21.0910] > <@bradfordcsmith:matrix.org> ``` > const myEmbeddedString = String.dedent( > ``delimiter text`` > Whatever I want > to have here > as long as this ends with > ``delimiter text``); > ``` Not sure how it look like template string (except it use backticks :P ), a problem of here doc style is normally it only support defining end delimiter but we also need to deal with interpolation delimiter. [15:23:30.0144] > <@rbuckton:matrix.org> Maybe there are improvements that could be made for `String.raw`, but that won't address the main concerns this proposal seeks to address. A string tag that is like `String.raw` but it replaces `\` with `` and removes backslashes at the end of template parts [15:24:53.0230] That still requires escaping in the literal [15:25:38.0299] > <@haxjs:matrix.org> Not sure how it look like template string (except it use backticks :P ), a problem of here doc style is normally it only support defining end delimiter but we also need to deal with interpolation delimiter. Better: normal template literal but new substitution syntax. const myEmbeddedString = String.dedent(` Normal template content ${<> Whatever I want to have here as long as this ends with <>} `); [15:25:47.0325] yeah, my goal is to avoid escaping. which means, whatever text you have, u could just paste it to js source code , wrap it in a raw literal, without modifcations. [15:26:56.0140] > <@rbuckton:matrix.org> I think the interesting thing about the proposal is that you don't need to escape anything, with the exception being `${`, but that could also be tied to the opening of the fenced string literal. The Explainer used n+1 `@` tokens, but could just as easily use n+1 `\` tokens, etc. It still doesn't address `\` at the end of the template, so some escaping will be needed regardless. There was a thread in Google's internal TypeScript chat group about why this case wasn't working with `String.raw` [15:28:19.0063] > <@jridgewell:matrix.org> It still doesn't address `\` at the end of the template, so some escaping will be needed regardless. There was a thread in Google's internal TypeScript chat group about why this case wasn't working with `String.raw` it could. `\` should have no effect on parsing raw literal. [15:28:28.0041] If a raw literal syntax does no escaping, then a trailing `\` is just a `\`. the only thing it looks for is a balanced set of `` ` `` characters [15:29:15.0322] Yeah, we just need some mechanism to define the ending token and the interpolation token. [15:29:59.0557] ```` \```\``` ``` would be the string `\`. The only caveat, being a string consisting only of `` ` `` [15:30:14.0272] element or matrix did not like that... [15:30:21.0607] Even `\x20` isn't transformed? I need to pay better attention. [15:30:46.0535] This is why I use swift-style in the slide, because swift style only use number of `#` to define both token, which IMO the simplest solution. But I don't know how others think about "simple"... [15:31:11.0092] * ``` \```\``` ``` would be the string `\`. The only caveat, being a string consisting only of `` ` `` [15:31:29.0004] > <@jridgewell:matrix.org> Even `\x20` isn't transformed? I need to pay better attention. if Swift style, it allow u to reenable escaping by `\#x20` [15:31:50.0527] > <@haxjs:matrix.org> This is why I use swift-style in the slide, because swift style only use number of `#` to define both token, which IMO the simplest solution. But I don't know how others think about "simple"... If there are concerns about "wasting" `#`, you could consider using `@` since I don't think anybody would ever want to use it for anything other than decorators anyway [15:32:09.0720] > <@jridgewell:matrix.org> Even `\x20` isn't transformed? I need to pay better attention. I think that's correct, from my interpretation of the proposal repo [15:32:24.0685] > <@haxjs:matrix.org> if Swift style, it allow u to reenable escaping by `\#x20` How do you represent that inside a string, then? [15:32:56.0651] > <@jridgewell:matrix.org> How do you represent that inside a string, then? Increase the number of # [15:32:57.0970] More `#`? [15:33:00.0448] Yah [15:33:01.0246] Ok [15:34:00.0293] On the other side, C# raw strings use two symbols: the number of " for end token, the number of $ for interpolation token. [15:34:19.0605] The draft in the repo use C# style. [15:34:45.0270] Personally I feel Swift style is much "simple" :P [15:42:43.0801] > <@rbuckton:matrix.org> As a syntax, you don't need to limit yourself to `@` and `#` as there are other infix tokens that could be made into a prefix token. For example, you could use ```` \``` ... ``` ```` to mean "I've done all the escaping I need to do at the start and end of the string" One point is, if only use repeated ` (or any repeated single char) as end token, it significantly has more conflict probability than combinations like `` `#`` . [15:43:11.0345] > <@rbuckton:matrix.org> As a syntax, you don't need to limit yourself to `@` and `#` as there are other infix tokens that could be made into a prefix token. For example, you could use ```` \``` ... ``` ```` to mean "I've done all the escaping I need to do at the start and end of the string" * One point is, if only use repeated `` ` ``(or any repeated single char) as end token, it significantly has more conflict probability than combinations like `````#\`\` . [15:43:43.0553] * One point is, if only use repeated `` ` ``(or any repeated single char) as end token, it significantly has more conflict probability than combinations like `` `#``. [15:52:51.0612] The removal of the curly brackets dramatically helps me absorb the syntax here. [15:53:04.0244] > <@rbuckton:matrix.org> As a syntax, you don't need to limit yourself to `@` and `#` as there are other infix tokens that could be made into a prefix token. For example, you could use ```` \``` ... ``` ```` to mean "I've done all the escaping I need to do at the start and end of the string" With this syntax, how would you write a string that starts with a backtick? [15:53:26.0720] ^ Is this problem solvable in any way? [15:54:37.0620] nicolo-ribaudo: require that triple-backtick strings have a leading and trailing newline, and strip those from the output 2024-02-08 [16:07:33.0386] How do you return a named fields in `Foo({x, y})`? [16:07:49.0154] `[{ x, y }]` [16:07:55.0037] Ok [16:07:55.0580] * `return [{ x, y }]` [16:08:02.0216] was Mark asking, "is it important to have this capability outside of pattern matching"? [16:08:16.0683] So it always returns an array, or false on no match? [16:08:20.0646] > <@littledan:matrix.org> was Mark asking, "is it important to have this capability outside of pattern matching"? No, he was asking "does pattern matching need anything else?" [16:08:25.0895] he was asking if pattern matching combined with extractors could be more minimal than it in fact can be [16:08:27.0050] oh, I see [16:08:27.0793] > <@jridgewell:matrix.org> So it always returns an array, or false on no match? Yes exactly [16:08:57.0770] * he was asking if pattern matching combined with extractors could be more minimal than it in fact can be (the answer is no, extractors do not allow much simplification of pattern matching at all, but it composes nicely) [16:09:05.0800] i don't love the nesting but i'm more than willing to accept it in exchange for the insane usefulness of this proposal [16:10:10.0512] what is it about the nesting that you don't like? [16:10:34.0926] Is Pattern Matching doesn’t advance, can we get `if (Foo(x) = y)` support? [16:11:05.0733] no, that's already valid syntax [16:11:27.0091] In loose mode only [16:11:45.0208] lol what is loose mode [16:11:48.0213] the semantics would only be, in the case where it was going to throw, to take the else branch [16:12:02.0069] > <@jridgewell:matrix.org> In loose mode only we didn't actually spec that [16:12:05.0297] but yes [16:12:16.0874] https://github.com/tc39/ecma262/issues/257 [16:12:40.0545] > <@ljharb:matrix.org> lol what is loose mode My Babel name for “not strict” [16:13:14.0097] loose mode is about the transpilation tho, not about what the surface syntax can be, right? [16:13:21.0375] strict/sloppy would be the runtime pair [16:13:37.0181] Oh, we call it sloppy [16:13:47.0548] Same thing. 😛 [16:13:50.0262] Could implementation avoid most of the megamorphic cases by doing an instanceof test first? [16:13:57.0569] if we're ok with reusing syntax in strict mode then sure we can add it [16:14:06.0946] anyway we're hoping, for this proposal, that even in sloppy mode, we can replace the exception with helpful behavior [16:14:08.0205] i thought we weren't though [16:14:32.0719] i don't personally care to preserve it [16:14:39.0841] the syntax is always a runtime error so we could probably get away with changing its semantics [16:14:46.0686] * the syntax is always a runtime error (in web reality) so we could probably get away with changing its semantics [16:14:59.0273] yea that would be nice [16:15:02.0299] yes, the requirement for web reality was more about, it doesn't make a syntax error [16:15:14.0886] although it would break my future dream proposal where functions can return variable references [16:15:35.0193] `array.at(-1) = 5` [16:15:52.0315] * although it would break my future dream proposal where functions can return references [16:15:54.0681] > <@devsnek:matrix.org> although it would break my future dream proposal where functions can return references Ron as a refs proposal [16:15:59.0403] > <@devsnek:matrix.org> although it would break my future dream proposal where functions can return references * Ron has a refs proposal [16:16:29.0800] i implemented `return&` in engine262 once. there's probably a branch somewhere [16:16:39.0371] > <@devsnek:matrix.org> although it would break my future dream proposal where functions can return references good.jpg [16:17:30.0145] > <@nicolo-ribaudo:matrix.org> Ron has a refs proposal lgtm ship it [16:18:08.0995] i love pointers [16:19:31.0020] I like hints [16:19:40.0316] just do them as a bitfield instead of having to allocate [16:19:54.0427] works nicely with void bindings too [16:26:40.0430] i have a sidebar question about the general topic of "TC39 watching" for after this actual topic [16:26:49.0046] > <@jridgewell:matrix.org> Is Pattern Matching doesn’t advance, can we get `if (Foo(x) = y)` support? Since it's an expression, and an expression could be nested anywhere for any purpose, I'm not sure how likely that is. I certainly hope pattern matching advances because it has a solution for this. [16:27:04.0557] who is doing TC39 watching and interpreting what we do and speculating conclusions from them? is it a few thinkfluencers? [16:27:34.0401] littledan: ^ [16:28:18.0159] I’ve definitely seen hot takes on twitter about advancements/rejections [16:28:21.0491] tbc i believe in the importance of sending signals, but i've only been thinking about that in context of more direct stakeholders [16:28:24.0839] My impression is that lot of webdevs pay attention to TC39, but relatively few read the meeting notes. [16:28:33.0691] But I don’t think MessageFormat has a rabid following [16:28:43.0171] (there are 94 stage 1 proposals) [16:29:37.0881] > <@rbuckton:matrix.org> Since it's an expression, and an expression could be nested anywhere for any purpose, I'm not sure how likely that is. I certainly hope pattern matching advances because it has a solution for this. I should revise this to `if (const Foo(x) = y` [16:30:14.0050] I'm pretty sure I hated the `export v from "mod"` proposal but I can't remember ljharb [16:30:17.0506] I think that’d only be valid at top level, but now the sloppy nonsense. [16:30:44.0846] * I think that’d only be valid at top level, but still has the sloppy nonsense. [16:30:48.0478] ljharb: Is it worth distinguishing between “withdrawn” (actively withdrawn by the champions) proposals and “inactive” or “stale” (removed because champions are inactive) proposals? [16:30:51.0277] > <@michaelficarra:matrix.org> I'm pretty sure I hated the `export v from "mod"` proposal but I can't remember ljharb hated with a technical justification? or just a "i will grumble about it" [16:31:04.0334] > <@jschoi:matrix.org> ljharb: Is it worth distinguishing between “withdrawn” (actively withdrawn by the champions) proposals and “inactive” or “stale” (removed because champions are inactive) proposals? we distinguish that in the "reason" column of the "inactive proposals" table [16:31:14.0358] there was a technical problem with it, but I need to look at it again to remember [16:31:21.0027] as in it should not exist [16:31:29.0044] It was that it looks like you are getting `v` from `mod`? [16:31:43.0347] also that people hate barrel modules [16:32:08.0935] > <@devsnek:matrix.org> also that people hate barrel modules I have a proposal for that [16:32:14.0690] actually i guess thats `* as x from` [16:32:18.0738] > <@devsnek:matrix.org> also that people hate barrel modules * I have a proposal for that, I presented it one or two meetings ago [16:32:22.0080] this is `{default as x} from` [16:32:30.0722] > <@devsnek:matrix.org> actually i guess thats `* as x from` This is supported now [16:32:35.0831] oh yeah it's just short for `export { default as v } from "mod"` which we already have, right? [16:32:43.0146] > <@nicolo-ribaudo:matrix.org> This is supported now yea [16:32:47.0641] > <@michaelficarra:matrix.org> oh yeah it's just short for `export { default as v } from "mod"` which we already have, right? Yes [16:32:56.0501] yes then what point is there? [16:33:13.0130] it fills in an empty spot in a markdown table someone made [16:33:20.0921] yeah that's baaaad [16:33:38.0859] One recent point was that `import source` would only support that new form, and some delegates would thus also like to see it for normal exports [16:33:47.0157] the point is to have nicer syntax, and to provide for the conceptual mental model that defaults is not just another named export. [16:33:50.0843] also it looks at first glance like `export { v as v } from "mod"` [16:34:17.0647] why? I don't see how that follows [16:37:02.0337] do we have a formal process of cleaning up proposals that someone was championing when they are offboarded [16:38:35.0659] no [16:38:57.0066] `() =*> yield 0` is incredible actually [16:38:59.0710] we should just do that [16:39:05.0640] the formal process is, someone brings it up in plenary, and we agree [16:39:07.0242] * `() =*> (yield 0)` is incredible actually [16:39:14.0791] > <@bakkot:matrix.org> `() =*> (yield 0)` is incredible actually this exact sequence of tokens [16:39:20.0935] nothing else [16:40:06.0245] > <@bakkot:matrix.org> `() =*> (yield 0)` is incredible actually RSI hazard [16:40:06.0265] `=*>` is such a strange looking sigil [16:40:30.0056] > <@rbuckton:matrix.org> `=*>` is such a strange looking sigil clown operator [16:43:42.0983] `() <=> ...` [16:43:45.0239] i can only describe the vibe of `=*>` as sparkle [16:46:32.0500] ``` () => () function () =*> () generator function () =~> () async function () =~*> () async generator function ``` [16:47:05.0306] Proposals that were withdrawn due to inactivity can always be revived later, right? [16:47:11.0632] yeah [16:47:27.0682] > <@jschoi:matrix.org> Proposals that were withdrawn due to inactivity can always be revived later, right? yes definitely [16:51:25.0826] From Myles: https://x.com/MylesBorins/status/1754925725436567721 [16:51:30.0398] Myles says thanks: https://twitter.com/MylesBorins/status/1754925725436567721 [16:52:14.0535] > <@ljharb:matrix.org> the formal process is, someone brings it up in plenary, and we agree the principle here was, today we're just reviewing things and later we can take things up [16:54:35.0507] > <@shuyuguo:matrix.org> who is doing TC39 watching and interpreting what we do and speculating conclusions from them? is it a few thinkfluencers? In the case of MessageFormat: maybe the biggest audience is the organizations working together on this, and the Unicode Consortium. We want to communicate to them clearly that we're not rejecting their work. I hope that this will help people convince their employers to let them keep working on this and proceed with deployments, where they might have been waiting for our stage advancements first. [16:55:01.0202] ok, thanks [17:00:09.0990] > <@ljharb:matrix.org> (there are 94 stage 1 proposals) Yeah this is potentially a pretty long exercise, which we could spread over multiple meetings. I'd be interested in everyone's feedback on whether it's worth it to continue. [17:02:55.0422] is the list of attendees available somewhere? [17:03:01.0038] * is the list of attendees for historical meetings available somewhere? [17:03:53.0517] Ecma's filer has minutes going all the way back [17:04:02.0925] https://ecma-international.org/ecmascript-development-archive/ [17:04:16.0618] > <@littledan:matrix.org> Yeah this is potentially a pretty long exercise, which we could spread over multiple meetings. I'd be interested in everyone's feedback on whether it's worth it to continue. I think it’s worth it. The list of Stage-1 proposals is communication to the developer community about potential features that are getting activity. But I think that there maybe should be async outreach, before each meeting, to champions whose Stage-1 proposals are going to get evaluated for withdrawal. [17:04:37.0625] > <@littledan:matrix.org> Yeah this is potentially a pretty long exercise, which we could spread over multiple meetings. I'd be interested in everyone's feedback on whether it's worth it to continue. * I think it’s worth it. The list of Stage-1 proposals is communication to the developer community about potential features that are getting activity. Preventing it from getting excessively long helps with that community communication. But I think that there maybe should be async outreach, before each meeting, to champions whose Stage-1 proposals are going to get evaluated for withdrawal. [09:56:03.0612] please add your name to the attendees list at the top of the day 3 meeting notes [10:02:33.0823] where is the template for the notes doc [10:02:38.0654] i want to fix the tree alignment once and for all [10:02:53.0094] the template are the docs themselves... [10:03:09.0173] we just clear them out each time [10:24:05.0159] Gus, be the change you want to see! Create a template doc and align those trees. We'll use it in future. [10:55:06.0612] Good luck aligning the trees portably. Gonna need to bring ye some tab stops or a beefy table. [11:01:02.0308] I’m late to realize that this could be spelled `Error.throw(message)` and be inherited down the constructor prototype chain. I had assumed `Error.throw` or `Error.raise` implied code like `Error.throw(new SpecificError(message))` [11:01:44.0764] I don't think that observation is too late [11:02:42.0520] > <@kriskowal:matrix.org> I’m late to realize that this could be spelled `Error.throw(message)` and be inherited down the constructor prototype chain. I had assumed `Error.throw` or `Error.raise` implied code like `Error.throw(new SpecificError(message))` https://github.com/tc39/proposal-throw-expressions/issues/24 [11:04:47.0577] > <@kriskowal:matrix.org> I’m late to realize that this could be spelled `Error.throw(message)` and be inherited down the constructor prototype chain. I had assumed `Error.throw` or `Error.raise` implied code like `Error.throw(new SpecificError(message))` it has to be syntax or else it impacts the stack [11:04:49.0305] > This [special logic to discard the topmost frame] is not an option, both because stacks aren't in the spec and because making a specific function magic in this regard would be profoundly problematic. ljharb this is exactly how Reflect.apply works??? [11:04:58.0388] O.o [11:05:12.0589] This does not seem like a big downside. [11:05:26.0536] if Reflect.apply is omitted from stack traces that'd be surprising to me, but either way "ES6 has X kind of magic" is not a justification for adding magic in the future [11:05:42.0025] its not magic, its a tail call [11:06:00.0949] its also specified with spec steps, not prose [11:06:30.0152] Given that syntax is the deepest magic, I think I’d favor the lesser magic of either tolerating a useless frame or magically omitting the frame. [11:06:49.0309] since stacks aren't in the spec, there's no way we can mandate the latter [11:06:55.0136] * since stacks aren't in the spec, there's no way we can mandate the latter afaik [11:07:04.0096] * since stacks aren't in the spec, there's no way we can mandate the latter afaik. even with tail calls i'm not sure how we mandate that? [11:07:21.0925] but tail calls don't exist in terms of broad web reality. [11:07:24.0304] the stack is in the spec... we just don't ever say anywhere that it relates to the `stack` property because that doesn't exist [11:07:31.0125] bakkot: how complex is the lookahead restriction to implement? [11:07:43.0729] Reflect.apply is also implemented as a tail call even outside safari [11:07:49.0181] > <@ljharb:matrix.org> since stacks aren't in the spec, there's no way we can mandate the latter afaik. even with tail calls i'm not sure how we mandate that? nor can we prevent any implementation from omitting them as an obvious ergonomic decision [11:08:57.0561] either way if a helper function works than `(() => { throw x })()` isn't that much worse than `Error.throw(x)` so i'm not sure why we'd add anything in that case [11:09:08.0115] > <@shuyuguo:matrix.org> bakkot: how complex is the lookahead restriction to implement? in the spec? trivial. in a parser? uhhh pretty easy I expect [11:10:29.0748] in the parser i meant [11:11:05.0901] In the parser it would be "if the next token is in this list, throw an error and abort parsing" [11:11:19.0510] At the end of the function that parses throw expressions [11:11:21.0653] yeah, in the `parseThrowExpression` branch in your recursive descent parser you just do ``` eat('throw'); let rhs = parseUnaryExpression(); if (noLineTerminatorBeforeLookahead() && ['+', '?', /*etc*/].includes(lookahead()) { throw new SyntaxError } ``` [11:11:25.0589] but when parsing which productions [11:11:32.0109] ThrowExpression [11:11:35.0912] in non-recursive-descent parsers it might be harder but those don't exist [11:11:41.0247] * only ThrowExpression [11:11:54.0752] ThrowExpression is inside Expression in option 3? [11:12:18.0178] it's inside UnaryExpression I think? or around there anyway [11:12:31.0160] Yeah in UnaryExpression [11:12:43.0024] ok thanks [11:14:13.0967] it should be trivial in v8 [11:14:29.0419] I need to go check the notes on why Waldemar would be against option 1/2 but with only UnaryExpression, I only remember his concerns about lookahead [11:14:48.0294] it is an extra keyword check where there isn't [11:15:11.0039] if that check is very localized, probably not costly in runtime or maintenance burden [11:15:16.0510] but not clear to me yet which option is the cheapest [11:15:47.0121] 1 is probably the cheapest because the check is only in one more place [11:16:00.0197] 2 would make you check for the kw in like 3-4 places [11:17:28.0443] Is Mark in this room? (I would like to write that I believe all of those problems will be caught as soon as we implement them in a tool, but that he can obviousy propose to invite him) [11:17:52.0227] * Is Mark in this room? (I would like to write him that I believe all of those problems will be caught as soon as we implement them in a tool, but that he can obviousy propose to invite him) [11:18:00.0723] erights is here yes [11:18:07.0695] * Is Mark in this room? (I would like to write him that I believe all of those problems will be caught as soon as we implement them in a tool, but that he can propose to invite him) [11:18:21.0316] * Is Mark in this room? (I would like to write him that I believe all of those problems will be caught as soon as we implement them in a tool;s parser, but that he can propose to invite him) [11:18:26.0237] * Is Mark in this room? (I would like to write him that I believe all of those problems will be caught as soon as we implement them in a tool's parser, but that he can propose to invite him) [11:18:44.0824] Mark’s not monitoring this room, I’m sure. [11:27:30.0164] i heard a lot of discomfort around syntax for this, and the main counterarguments for syntax i heard were: - extra stack frame - throwing non-errors (which doesn't seem to be a counterargument? surely a helper method can take arbitrary values) [11:27:39.0426] can someone say more why the extra stack frame is a problem? [11:28:31.0916] It's only an extra stack frame in the debugger, right? [11:28:32.0148] I've not kept up with the history of X expressions for various X. They are all being pursued because they have some use, but would it be better to investigate some form of expression blocks as Java is doing in various contexts? [11:28:42.0590] I wish we could resolve issues without stage advancement [11:28:45.0358] > <@shuyuguo:matrix.org> can someone say more why the extra stack frame is a problem? there is concern about how to specify that engines shouldn't show the extra stack frame in strings/debuggin [11:28:52.0012] `thrower(new Error('foo'))` has the correct `err.stack` trace [11:28:58.0596] the helper function thing is prior to the question of precise syntax, and _we have had that discussion_ [11:29:02.0637] > <@shuyuguo:matrix.org> can someone say more why the extra stack frame is a problem? performance? also making it apparent that the code below it is unreachable? [11:29:06.0328] > <@shuyuguo:matrix.org> can someone say more why the extra stack frame is a problem? * there is concern about how to specify that engines shouldn't show the extra stack frame in strings/debugging [11:29:21.0431] > <@aardvark179:matrix.org> I've not kept up with the history of X expressions for various X. They are all being pursued because they have some use, but would it be better to investigate some form of expression blocks as Java is doing in various contexts? yes some of us would like that very much 😄 https://github.com/tc39/proposal-do-expressions [11:29:25.0288] > <@bakkot:matrix.org> the helper function thing is prior to the question of precise syntax, and _we have had that discussion_ Can someone refer to the prior notes where we reached that conclusion? [11:29:30.0626] extra stack frame seems like a total non-issue, cf. `Reflect.apply`: ``` $ eshost -se '(function main(){ return Reflect.apply(function inner(){ return new Error("message").stack.replace(/ *[(].*|/gm, "").replace(/\/tmp\/.*/g, "$file"); }, undefined, []); })()' #### engine262 Error: message at inner at main at :1:1022 #### JavaScriptCore inner@$file main@$file global code@$file #### Moddable XS Error: message at inner at apply at main at #### QuickJS at inner at apply at main at #### SpiderMonkey inner@$file main@$file @$file #### V8 Error: message at inner at main at $file ``` [11:29:40.0467] indeed a function that's just `x => { throw x; }` will have the right stack trace *iff* x is an error object [11:30:05.0395] * indeed a function that's just `x => { throw x; }` will have the right stack trace _iff_ x is an error object. if it's not one, it won't have a trace, but engines may still report the helper function as the throw site and not the helper function's call site as the throw site. [11:30:35.0625] its not a problem in real engines to ignore the frame when preparing presentation of the stack for strings/debug interfaces. they already do this a lot for their own internal stuff. [11:30:38.0437] > <@littledan:matrix.org> performance? also making it apparent that the code below it is unreachable? how is it a performance problem? [11:30:38.0734] node, in particular, has magic "show the throw site" behavior [11:30:43.0650] > <@pchimento:igalia.com> yes some of us would like that very much 😄 https://github.com/tc39/proposal-do-expressions Ah right, that how JS spells it. [11:31:12.0337] > <@shuyuguo:matrix.org> how is it a performance problem? a very small one? I'm not convinced this is a significant issue but it seemed that people were claiming that. [11:31:15.0248] > <@ljharb:matrix.org> indeed a function that's just `x => { throw x; }` will have the right stack trace _iff_ x is an error object. if it's not one, it won't have a trace, but engines may still report the helper function as the throw site and not the helper function's call site as the throw site. strongly agree with richard that we should not be designing this feature based on things that happen when throwing non-error objects [11:31:45.0739] > <@ljharb:matrix.org> node, in particular, has magic "show the throw site" behavior btw this only works if the error is terminal [11:31:47.0880] > <@littledan:matrix.org> a very small one? I'm not convinced this is a significant issue but it seemed that people were claiming that. i wasn't being flippant. what is "that"? i don't actually know [11:31:47.0881] sure i'm fine with that (as long as it allows throwing anything) but i'm talking about the throw site behavior conflicting with the stack [11:32:30.0394] > <@shuyuguo:matrix.org> i wasn't being flippant. what is "that"? i don't actually know (I was probably misunderstanding; don't worry) [11:32:38.0486] * sure i'm fine with that (as long as it _allows_ throwing anything) but i'm talking about the throw site behavior conflicting with the stack [11:33:09.0949] heck, even meta-function `throw.new(…)` would have better grammar characteristics [11:33:13.0340] at any rate i don't think a helper function that does nothing but rethrows its argument holds its weight to add to the language - syntax for this would (whether the benefits justify syntax is a separate topic) [11:33:18.0904] * at any rate i don't think a helper function that does nothing but throws its argument holds its weight to add to the language - syntax for this would (whether the benefits justify syntax is a separate topic) [11:33:38.0849] * at any rate i don't think a helper function that does nothing but throws its argument holds its weight to add to the language - syntax for this would (whether the benefits justify syntax is a separate topic) (a metafunction would be syntax) [11:33:41.0334] > <@ljharb:matrix.org> at any rate i don't think a helper function that does nothing but throws its argument holds its weight to add to the language - syntax for this would (whether the benefits justify syntax is a separate topic) what about an `Error.prototype.throw`? [11:33:56.0211] > <@bakkot:matrix.org> what about an `Error.prototype.throw`? "but I want to be able to throw a number!!!" [11:34:10.0610] > <@bakkot:matrix.org> what about an `Error.prototype.throw`? not that I am advocating this, just want to know what your position is [11:34:19.0783] that's certainly somewhat cleaner than a static helper function, but doesn't change my position [11:34:44.0088] in all srsness i throw strings in CLI programs *constantly*, the terminal output is way cleaner than throwing an error [11:35:13.0714] `console.error('msg'); process.exit(1)` [11:36:10.0681] that "works" but relies on two different mutable globals, and is two statements instead of one [11:40:28.0773] you should never throw things that aren't errors [11:40:55.0342] that is certainly an opinion many hold [11:40:57.0843] the only reason nodejs has support for a backtrace in this case is so you can find the broken code thats doing it and fix it [11:41:59.0739] since nobody throws non-errors, and i don't throw fully dynamic things, turns out it's really really easy to grep for places that throw primitives :-p [11:42:06.0530] `throw.something()` or `keyword.throw()` should strongly be considered as one of the possible designs. [11:42:07.0189] * since nobody throws non-errors, and i don't throw fully dynamic things, turns out it's really really easy to grep for places that statically throw primitives :-p [11:51:40.0492] I would want us to still investigate whether this _can_ be written without lookahead, and then once we know that it can indeed be expressed with "normal" grammar write the spec in the way that is editorially preferred [11:52:07.0818] We cannot just completely ignore what was discussed last time the restriction was presented [11:52:18.0538] Even though Option 3 would indeed be my preferred [11:55:04.0116] can we fit tail calls into 8 minutes [11:55:27.0464] > <@nicolo-ribaudo:matrix.org> I would want us to still investigate whether this _can_ be written without lookahead, and then once we know that it can indeed be expressed with "normal" grammar write the spec in the way that is editorially preferred I think it can, though I need feedback from the editors on a few points. The grammar is far more complex than the lookahead, however: https://gist.github.com/rbuckton/d26f0e04bd693324a87c3da3835d87f2 [11:55:39.0299] > <@devsnek:matrix.org> can we fit tail calls into 8 minutes pls no [11:55:59.0760] Thanks, I'll take a look at it [11:57:56.0394] > <@jschoi:matrix.org> `throw.something()` or `keyword.throw()` should strongly be considered as one of the possible designs. So long as `do` expressions is still active, I do not think `throw.something()` or `keyword.throw()` is an improvement over `do { throw ex }`. `throw` expressions have the upshot of being far simpler to specify and more tightly focused than `do`. [11:59:53.0242] i.e., if we already had `do {}`, there would be no benefit for `throw.somthing()`. In fact, if we had `throw.something()`, its likely it would be abandoned if `do {}` reached stage 4, which would be a waste. `throw` expressions, on the other hand, are unlikely to be abandoned due to the fewer characters and lower cognitive burden that `do {}` requires. [12:02:14.0214] The biggest benefit of `throw` is the improved developer experience. `(throw ex)` reduces that benefit, `do { throw ex }` even more so, and `throw.something(ex)` is considerably worse. [12:03:48.0215] `Error.throw` has a similar reduced DX, and the only user benefit I see is you could pass it as a callback, which I do not consider to be a valuable benefit. [12:04:25.0922] I think this is reasonable, but, as long as we’re imagining a future in which do expressions finally get added to the language, do expressions would weaken the case for throw expressions as much as they would for the case for a throw pseudo-function. [12:05:24.0111] * I think this is reasonable, but, as long as we’re imagining a future in which do expressions finally get added to the language, do expressions would weaken the case for throw expressions as much as they would weaken the case for a throw pseudo-function. [12:05:38.0271] We had that discussion in both the July and September plenaries, and the sentiment I heard was that `throw` is valuable even in the presence of `do {}`. [12:06:15.0769] * We had that discussion in both the July and September plenaries, and the sentiment I heard was that `throw` would be valuable even in the presence of `do {}`. [12:07:27.0718] * We had that discussion in both the July and September 2023 plenaries, and the sentiment I heard was that `throw` would be valuable even in the presence of `do {}`. [12:10:43.0959] Sorry that we’re relitigating already-covered ground. Though I don’t recall a throw pseudo-function (what do we call `import()`, again?) being considered back in those plenaries as one of the options. I do still wonder how much less value it would give than throw expressions, in the presence of do expressions. [12:10:48.0977] I am not confident that `do {}` will advance, and I don't think a `throw.something()` meta-property would align with Kris Kowal 's suggestion, nor do I think it would be an improvement to the syntactic budget that `throw` already consumes. [12:12:25.0279] IIRC, we did discuss `throw()` in plenary in September, though it may have only been in matrix. `throw(ex)` does not work as a function as it still suffers from precedence issues, i.e. ```js throw (a) + b; // throws `a + b` (throw(a) + b); // throws `a` ``` [12:12:40.0851] * IIRC, we did discuss `throw()` in plenary in September, though it may have only been in matrix. `throw(ex)` does not work as a call-like syntax as it still suffers from precedence issues, i.e. ```js throw (a) + b; // throws `a + b` (throw(a) + b); // throws `a` ``` [12:15:48.0178] Yeah, it would be a throw pseudo-method, I guess. `throw.something()` or `keyword.throw()`. I don’t feel strongly about this solution, except that it should be thoroughly considered if it hasn’t yet been. [12:18:33.0782] * Yeah, it would be a throw pseudo-method, I guess. throw.something() or keyword.throw(). I don’t feel strongly about this solution, except that it should be thoroughly considered if it hasn’t yet been. It’s syntactically lightweight and lets developers throw errors within expressions. If do expressions never advance, then that makes *both* throw expressions and a throw pseudo-method that much stronger. [12:19:35.0048] * Yeah, it would be a throw pseudo-method, I guess. `throw.something()` or `keyword.throw()`. I don’t feel strongly about these pseudo-method solutions, except that they should be thoroughly considered if it hasn’t yet been. It’s syntactically lightweight and lets developers throw errors within expressions.
If do expressions never end up advancing, then that makes the case for *both* throw expressions and a throw pseudo-method that much stronger. [12:27:50.0854] IMO, if we going to have syntax, I would rather have `(throw ex)` than `throw.something(ex)`. There is no benefit to a meta-method here, and if we were going to use meta-properties related to exceptions I'd strongly prefer `catch.foo` over `throw.foo`. [12:28:13.0349] does anyone actually have major problems with (non-async) do expressions at this point [12:28:27.0034] it just need some spec formalization and validation right [12:30:10.0430] > <@rbuckton:matrix.org> IMO, if we going to have syntax, I would rather have `(throw ex)` than `throw.something(ex)`. There is no benefit to a meta-method here, and if we were going to use meta-properties related to exceptions I'd strongly prefer `catch.foo` over `throw.foo`. Why not `throw (ex)` (parentheses around the value required)? I think that is a possibility, right? [12:31:28.0413] No, see [my comment](https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$FMG2VHaRTqqQjTpTkF8F_rOVMRwa1gBzY_6TKq7VZlM?via=matrix.org&via=mozilla.org&via=igalia.com) just above this. It has the same precedence issue that bakkot objected to [12:32:01.0665] rbuckton: Is the desire to have TS recognize throws within expressions during static analysis a primary reason for wanting throw expressions in the first place? [12:33:02.0499] > <@bradfordcsmith:matrix.org> rbuckton: Is the desire to have TS recognize throws within expressions during static analysis a primary reason for wanting throw expressions in the first place? No, that is a side benefit but was never a major motivation. [12:35:49.0931] I don't particularly care whether throw expressions become a thing or not, but I don't understand how they could bring enough benefit to be worth even the amount of effort we've spent discussing them so far. I just checked the explainer, and I don't see any explanation of motivation. [12:40:20.0135] > <@rbuckton:matrix.org> We had that discussion in both the July and September 2023 plenaries, and the sentiment I heard was that `throw` would be valuable even in the presence of `do {}`. yes, but only subject to lack of grammar issues (which we clearly do have) [12:40:24.0644] It is a bit disheartening to have reached stage 2 with consensus in 2017, and reached near-unanimous agreement to advance to stage 3 in 2018 barring a lone objector whose two objections were `do` and the precedence issue we're discussing today. The `do` objection was finally retracted in July 2023, so my impression was that we'd already reached consensus on all of the other points of the proposal and the precedence concern was the only remaining obstacle. I hate to check a box on TC39 bingo, it it feels like I'm relitigating points that had already had broad agreement. [12:42:10.0380] bakkot's only remaining concern was avoiding a footgun of accidental use of tokens like `+` or `,` following the unary expression. IMO, that's something a linter could warn you about, but bakkot preferred baking that restriction into the language, much like we did for the precedence concern around `||` and `??`. [12:48:33.0455] There is a definite benefit to users to be able to throw exceptions in-situ in an expression. Existing mechanisms like `const __throw = ex => { throw ex; }` suffer drawbacks around the debugging experience. `Error.throw` is a possibility, but we don't generally bake distinctions around stack frames and debugging into the specification, but it's also far less ergonomic than `throw`. `throw` expressions also have prior art in multiple other languages, so it is not a net-new concept. [12:48:52.0749] * There is a definite benefit to users to be able to throw exceptions in-situ in an expression. Existing mechanisms like `const __throw = ex => { throw ex; }` suffer drawbacks around the debugging experience. `Error.throw` is a possibility, but we don't generally bake distinctions around stack frames and debugging into the specification, and it's also far less ergonomic than `throw`. `throw` expressions also have prior art in multiple other languages, so it is not a net-new concept. [12:51:29.0224] * It is a bit disheartening to have reached stage 2 with consensus in 2017, and reached near-unanimous agreement to advance to stage 3 in 2018 barring a lone objector whose two objections were `do` and the precedence issue we're discussing today. The `do` objection was finally retracted in July 2023, so my impression was that we'd already reached consensus on all of the other points of the proposal and the precedence concern was the only remaining obstacle. I hate to check a box on TC39 bingo, but it does feel like I'm relitigating points that had already had broad agreement. [13:13:48.0040] this slide would be a lot more convincing if there were examples of the alternative and the alternative syntax were bad, but none of them seem to be? [13:14:10.0443] like instead of `@app.route('/') function index(){}` it would be `const index = app.route('/', function (){})` [13:14:14.0351] those are... almost identical [13:14:21.0671] I do not understand what the point of syntax is here [13:14:49.0794] can someone who wants decorators explain if I am missing something? littledan ? [13:15:28.0754] "decorator decorators" is just... function composition? [13:15:39.0694] yes... what's wrong with that? it's a simple feature [13:15:56.0326] to be fair we don't have pipeline yet to make function composition more ergonomic [13:16:00.0562] I just don't see why we need another, specialized kind of function invocation, I guess? [13:16:30.0384] there should be a pretty high bar for adding a new way of doing an existing thing [13:16:32.0624] in general, because `a(b(c(d)))` sucks and is backwards [13:16:34.0353] * there should be a pretty high bar for adding a new syntax way of doing an existing thing [13:16:37.0134] I think it is a bit different in terms of mental model [13:16:43.0172] all syntax needs to be learned by all learners of the language, so that's a high cost [13:16:46.0131] * in general, because `a(b(c(d)))` sucks and is backwards (not trying to say that supports any specific proposal) [13:16:55.0778] * in general, because `a(b(c(d)))` sucks and is backwards (not trying to say that that supports any specific proposal, including this one) [13:17:02.0851] this is a really natural extension of class decorators [13:17:05.0985] it's not backwards if you read right-to-left [13:17:06.0132] > <@littledan:matrix.org> yes... what's wrong with that? it's a simple feature It's a new syntax, that looks declarative (but it's really runtime magic), and breaks hoisting [13:17:36.0493] ok but in that case everything _else_ is backwards [13:17:55.0423] > <@bakkot:matrix.org> like instead of `@app.route('/') function index(){}` it would be `const index = app.route('/', function (){})` you can add more decorators. `@app.route('/') @authorized @originCheck @rateLimit(...) function index() {}` [13:18:09.0874] not really, you already need to read inside-out which is usually right-to-left [13:18:21.0303] I have to admit: although I really like the no-hoisting semantics, when we reviewed this proposal internally, there was a significant contingent of "this is bad" [and IMO not being OK with no-hoisting puts this in a very difficult space] [13:18:22.0392] `a().b().c().d`? [13:18:44.0866] I think this proposal is a "make it pretty" without adding real new functionality [13:19:16.0080] > <@devsnek:matrix.org> you can add more decorators. `@app.route('/') @authorized @originCheck @rateLimit(...) function index() {}` you can call multiple functions too [13:19:19.0060] yes its not making it possible to add authorization your routes [13:19:25.0253] And it makes me think of Java's BS, I hate the annotations on annotations on annotations that I have to do get pass Google's corp style [13:19:27.0497] my feedback to parameter decorators previously was "we should maybe do function decorators first". If we reject this, we should go back and consider parameter decorators IMO. [13:19:35.0405] its just taking a very popular pattern from other languages [13:19:46.0920] > <@littledan:matrix.org> my feedback to parameter decorators previously was "we should maybe do function decorators first". If we reject this, we should go back and consider parameter decorators IMO. I feel very strongly that we should not do parameter decorators regardless of the outcome of this discussion [13:19:54.0160] well, OK [13:20:01.0902] I have trouble understanding this negativity [13:20:05.0603] i would really like to have function decorators. i don't care about any other decorators [13:20:05.0672] > <@devsnek:matrix.org> its just taking a very popular pattern from other languages "common" I will grant. "popular" I will not grant. [13:20:17.0672] > <@devsnek:matrix.org> i would really like to have function decorators. i don't care about any other decorators this is commonly held among JS programmers [13:21:07.0105] the difference between decorators and metadata-only annotations is whether you want it to rely on some outside "runner" to read the metadata and take the appropriate actions. IMO supporting self-starting behavior is more JavaScripty. [13:21:15.0336] have JS programmers never seen HoFs? [13:21:18.0208] > <@littledan:matrix.org> I have trouble understanding this negativity the default is not adding new syntax, there needs to be a *good*, *strong* reason to add new syntax. and... there does not appear to be any such reason, here [13:21:19.0028] with either function or param decorators it'd make it much easier for me to have proper runtime argument validation that's palatable to lots of JS devs [13:21:31.0063] it's just a slightly different kind of function application with weird interaction with hoisting [13:21:34.0254] > <@michaelficarra:matrix.org> have JS programmers never seen HoFs? lol i've been rejected from an interview in the past because i "used too many HoFs" [13:21:47.0367] > <@ljharb:matrix.org> with either function or param decorators it'd make it much easier for me to have proper runtime argument validation that's palatable to lots of JS devs Extractors are also a possibility here, but yes I agree. [13:21:54.0750] > <@michaelficarra:matrix.org> have JS programmers never seen HoFs? i don't understand why you would want to write `route(authorized(originCheck(rateLimited(5, 1, function index() {}))))` [13:21:57.0878] well best to find out early that it's not a good place to work [13:22:16.0770] or `combine(authorized, originCheck, rateLimited(5, 1), function index() {})` [13:22:17.0002] why is that meaningfully worse than the @ version? [13:22:18.0620] maybe you overran their stack [13:22:23.0437] lol fair, but also, i think that's an almost universal attitude among JS devs [13:22:29.0334] how is that... any different from the `@` version [13:22:38.0400] functional programming is loved, Functional Programming is reviled [13:22:53.0001] weird [13:22:55.0225] the left-to-right order and the lack of needing nesting parens [13:23:08.0696] * the left-to-right order and the lack of needing nesting parens (which other proposals can also solve) [13:23:14.0053] decorators don't change the order vs function applications, but the nesting part is important [13:23:19.0300] ok so that is also the exact stated motivation for pipeline [13:23:20.0741] pipeline is the wrong order for this kind of thing IMO [13:23:21.0368] > <@devsnek:matrix.org> i don't understand why you would want to write `route(authorized(originCheck(rateLimited(5, 1, function index() {}))))` ``` const index = (route (authorized (originCheck (rateLimited(5, 1) (function (...) { }))))) ``` just use `(` for decorators instead of `@` :) [13:23:32.0802] we can't have _more than one_ new way of function calls to avoid nesting [13:23:35.0375] > <@devsnek:matrix.org> i don't understand why you would want to write `route(authorized(originCheck(rateLimited(5, 1, function index() {}))))` * ``` const index = (route (authorized (originCheck (rateLimited(5, 1) (function (...) { / body }))))) ``` just use `(` for decorators instead of `@` :) [13:23:36.0431] i think this is a common enough pattern that we shouldn't make people use weird ugly nesting/helpers/etc [13:23:40.0423] I don't think we even need one, but we definitely can't have _more than one_ [13:23:50.0975] functional programming in the large, imperative programming in the small [13:23:53.0047] Call functions, not too many, mostly lower-order [13:23:53.0672] this is the only way [13:24:38.0249] but, these are for very different-feeling things [13:24:47.0263] you decorate declarations, and you put data through a pipeline [13:24:56.0609] > <@nicolo-ribaudo:matrix.org> ``` > const index = > (route > (authorized > (originCheck > (rateLimited(5, 1) > (function (...) { > / body > }))))) > ``` > > just use `(` for decorators instead of `@` :) > introducing the (a) operator [13:25:07.0040] * ***Introducing the (a) operator*** [13:25:18.0883] > <@littledan:matrix.org> you decorate declarations, and you put data through a pipeline how are those... different things [13:25:35.0893] functions aren't thought of as data [13:25:44.0044] bakkot: I remind you that we have both yield and await for no good reason [13:25:50.0352] but... decorators are... transformations of functions... [13:25:55.0637] > <@bakkot:matrix.org> how are those... different things yeah, I dunno how to put it... maybe stop thinking so much? [13:26:05.0774] i do actually think of functions as data. BUT i do think its not productive to have a conversation where the premise "everyone must think in pure fp" [13:26:18.0291] I am not particularly a FP person [13:26:35.0694] pure fp is not my reading of bakkot's position [13:26:36.0812] JavaScript is an FP language because functions are first-class data [13:26:53.0202] * JavaScript is an FP language because functions are first-class data [13:27:13.0012] non-sarcastically, i often say JS is functional programming, not Functional Programming [13:27:24.0154] these are literally function transformations, that's a fact of the proposal. ron admits that this is not new expressivity. [13:27:45.0816] the disagreement i see is the motivation is thus ergonomics, which comes down to feelings, which we disagree on [13:29:45.0941] the most realistic usage i can imagine in the real world is something like `app.route('/', {extensions: [rateLimit()]}, function index() {})` [13:29:53.0120] but that requires your http framework to support it [13:29:55.0385] which is silly [13:30:04.0435] * the most realistic non-decorator usage i can imagine in the real world is something like `app.route('/', {extensions: [rateLimit()]}, function index() {})` [13:30:08.0825] this is why postfix languages are better [13:30:15.0555] Well your HTTP frameworks would need to support decorators [13:30:22.0122] why [13:30:25.0454] it generalizes pipelining to multiple parameters! [13:30:28.0752] To know what `@app.route("/")` means [13:30:30.0935] app.route just calls f with (req, res) [13:30:36.0716] Oh I see [13:30:42.0883] certainly such a decorator would need to support the framework [13:31:41.0339] There is an example of this "in the wild" : https://www.npmjs.com/package/fastify-decorators [13:31:47.0129] well, this is part of the beauty of decorators work, where they have a "main thing" which is the first argument to the decorator [13:32:01.0914] and the return value is interpreted as, what the main thing is replaced with [13:32:16.0893] so a lot of things "just work" [13:36:19.0597] Can someone let me back in the Zoom meeting? [13:36:38.0236] done [13:36:40.0570] Thank you! [13:37:08.0630] > <@jschoi:matrix.org> Thank you! of course, apologies for not keeping an eye, the pop up on zoom is _tiny_ [13:37:15.0890] It's hard for me to understand the strength of this opposition. Shouldn't we have skipped class decorators with these arguments? this is really the same thing as those. [13:38:38.0313] we should probably have not included class decorators, yes; at one point they had additional expressivity and so I was ok with that on those grounds [13:38:51.0367] we ought to have revisted them when that stopped being true [13:39:27.0691] yeah, they have been *not* more expressive for the whole time we were reviewing the current version of the proposal, which was more than a year IIRC. [13:39:38.0241] * yeah, they have been _not_ more expressive for the whole time we were reviewing the current version of the proposal, which was more than a year IIRC before Stage 3. [13:40:34.0849] > <@devsnek:matrix.org> i don't understand why you would want to write `route(authorized(originCheck(rateLimited(5, 1, function index() {}))))` `function index() {} |> rateLimited(5, 1, ^^) |> originCheck(^^) |> authorized(^^) |> route(^^)` 🥹 [13:40:38.0095] the discussion of decorators was much longer than a year [13:41:03.0431] > <@jschoi:matrix.org> `function index() {} |> rateLimited(5, 1, ^^) |> originCheck(^^) |> authorized(^^) |> route(^^)` 🥹 yikes [13:41:32.0946] It looks better on multiple lines, I swear. [13:43:34.0382] Reverse pipes: ``` const index = route(^^) <| authorized(^^) <| originCheck(^^) <| rateLimited(5, 1, ^^) <| function() {} ``` [13:43:38.0820] > <@littledan:matrix.org> It's hard for me to understand the strength of this opposition. Shouldn't we have skipped class decorators with these arguments? this is really the same thing as those. actually yes [13:44:44.0752] pipelining is backwards for this use case; you want the decorator at the beginning [13:47:18.0635] i don't know how to argue against the idea that new behavior should be rejected based on how mechanically similar it is to other things. that just leave you with lisp [13:47:29.0171] i don't think that's the argument [13:47:29.0921] I actually like this seriously [13:47:54.0702] the argument is, absent new expressivity, the remaining argument here is whether you think this is good for ergonomics [13:48:07.0367] and if there is disagreement, how do you resolve that if it's a disagreement in taste? [13:48:16.0411] If there is no function decorator, people will just use decorator on static method to workaround 🙄 [13:48:38.0781] is that something you're seeing in practice? could i see an example [13:48:49.0572] by "that leaves you with lisp" I think you mean that leaves you with a small number of language features that are incredibly generically applicable instead of tons of special-purpose stuff, which seems like a good design direction [13:48:58.0924] i suppose `@extract @a @b @c class { [extract]() {…} }` would work [13:49:04.0870] * i suppose something like `@extract @a @b @c class { [extract]() {…} }` would work [13:49:30.0223] then let them [13:49:30.0799] * i suppose something like `@a @b @c @extract class { [extract]() {…} }` would work [13:49:33.0282] * i suppose something like `@a @b @c @extract class { [extract]() {…} }` would work [13:49:36.0389] that doesn't bother me [13:49:42.0101] and people would do that because they don't want to type c(b(a(() => {}))) ? [13:49:48.0166] this is entirely about ergonomics, and if they think that's ergonomic, good for them [13:50:00.0117] i mean i don't think i'd do that. but the readability benefit to me is indeed abc vs cba [13:50:03.0988] * i mean i don't think _i'd_ do that. but the readability benefit to me is indeed abc vs cba [13:50:04.0285] > <@shuyuguo:matrix.org> and people would do that because they don't want to type c(b(a(() => {}))) ? It's very different. syntax matters. [13:50:32.0375] * i mean i don't think _i'd_ do that. but the readability benefit to me is indeed abc vs cba (the parens too but that's trivial) [13:51:00.0309] i've heard this assertion a few times, both here and in other arguments. how do i actually get a better handle on the size of the dev population that feels this way? [13:51:01.0031] > <@shuyuguo:matrix.org> and people would do that because they don't want to type c(b(a(() => {}))) ? Yes. [nit: we're talking about `a(b(c(...)))`] [13:51:13.0984] here's some code of mystery origin, i'm really curious how people would recommend writing this in javascript today. https://gist.github.com/devsnek/8785765310d10f1d36d380e8f3e55a50 [13:51:19.0083] oh the application order ist he same? [13:51:21.0431] > <@shuyuguo:matrix.org> i've heard this assertion a few times, both here and in other arguments. how do i actually get a better handle on the size of the dev population that feels this way? yes this is the kind of thing we should be working on [13:51:28.0391] I feel the exact opposite here, for what it’s worth [13:51:50.0002] > <@shuyuguo:matrix.org> oh the application order ist he same? yes, that's my understanding [13:52:03.0786] > <@shuyuguo:matrix.org> oh the application order ist he same? * that's my understanding at least [13:52:04.0127] Annotations feel like magic, and obfuscating. But I realize others don’t feel that way [13:52:08.0474] if the order is the same then what's the understandability issue with a(b(c(...))) ? [13:52:13.0565] * that's my understanding at least. decorators run inner-to-outer [13:52:38.0049] > <@shuyuguo:matrix.org> if the order is the same then what's the understandability issue with a(b(c(...))) ? i would expect to get that order with `@c @b @a …` [13:52:39.0661] The indentation pyramid of doom, probably. [13:52:51.0816] * > what's the understandability issue with a(b(c(...))) The indentation pyramid of doom, probably. [13:52:57.0113] decorators aren't only annotations tho. i don't personally find annotations valuable or helpful [13:53:00.0159] Can class element decorators affect placement? I thought they couldn't. [13:53:06.0818] that was the whole "static shape" thing [13:53:11.0932] No they cannot [13:53:12.0911] there's just `accessor` [13:53:22.0522] I actually like https://matrix.to/#/!WgJwmjBNZEXhJnXHXw:matrix.org/$L6qy_Funltwcu-I87xDP2Ptgqx7t-XHFrlBUDyGve_M?via=matrix.org&via=mozilla.org&via=igalia.com [13:53:28.0569] Sorry, I use those terms interchangeably, which is not helpful [13:53:47.0935] bakkot: class method decorators are exactly as much powerful as function decorators would be [13:53:52.0448] Everything else has been removed [13:53:58.0563] there's `addInitializer` though [13:54:06.0033] I’ve just never felt excited about any use of decorators [13:54:17.0684] > <@nicolo-ribaudo:matrix.org> bakkot: class method decorators are exactly as much powerful as function decorators would be sorry, not "affect", but "be given informatino about" [13:54:35.0380] I’ve developed in many languages, and have suffered more where they are common (Java, Scala) [13:54:37.0051] good point, initializers seems bad to me for function declarations [13:54:40.0928] > <@nicolo-ribaudo:matrix.org> bakkot: class method decorators are exactly as much powerful as function decorators would be * sorry, not "affect", but "be given information about" [13:55:00.0391] certainly i'm not a fan of the idioms in java :-) [13:55:27.0663] initializers for methods/functions just run once; it ends up being a pretty common need when writing decorators (we used to call them "finishers" in the original decorators proposal) [13:55:38.0513] And I guess I’m worried that at some point, we’ll have so much syntax in the language such that a snippet may be confused with any c-derived language [13:56:02.0724] tbf that's already the case for lots of snippets [13:56:14.0122] how would you write this code in javascript? https://gist.github.com/devsnek/8785765310d10f1d36d380e8f3e55a50 [13:56:17.0733] And so much cognitive overhead for new developers [13:56:33.0070] Java decorators are more magic because they only attach metadata that another system then searches the class loader for. So more spooky action at a distance. Can't step through with a debugger [13:56:54.0158] I like that JS decorators are programmatic, can step through what they are doing [13:56:54.0933] Maybe I’ve been red pilled by writing a lot of Go, but sometimes you should pave EVERY cow path [13:57:13.0761] > <@aclaymore:matrix.org> I like that JS decorators are programmatic, can step through what they are doing That is an improvement [13:57:14.0384] exactly how you think I would [13:57:20.0750] > <@anthonybullard:matrix.org> Maybe I’ve been red pilled by writing a lot of Go, but sometimes you should pave EVERY cow path Do you mean to say shouldn't? [13:57:29.0305] * Maybe I’ve been red pilled by writing a lot of Go, but sometimes you should NOT pave EVERY cow path [13:57:35.0790] in case we don't get to the Angular queue item, here's what i've been told in discussing with angular people internally - some folks in angular at least consider the current state with its parameter decorator use to be rife with footguns (e.g., param decorators would cause parameter names to be retained at runtime) - @inject decorators actively on way out - angular has no plans AFAIK to ever move to standard decorators [13:57:39.0564] > <@littledan:matrix.org> Do you mean to say shouldn't? Edited 😉 [13:58:03.0286] > (e.g., param decorators would cause parameter names to be retained at runtime) [13:58:04.0430] parameter names should be retained at runtime anyways for debugging, minifiers that remove them are annoying [13:58:10.0421] I would hope we would use indexes instead of names [13:58:19.0432] so angular shouldn't be cited as a customer for this work, it won't be. not saying there aren't others, but angular isn't one [13:58:20.0788] * I would hope we would use indexes instead of names if we do param decorators [13:59:15.0820] like this? ```js [13:59:20.0517] * like this? ```js pipeline( blueprint.routes( 'POST', '/interactions///callback', { auth: AuthOptions(required = False), visibility: ApiVisibility.PUBLIC, name: 'create_interaction_response', } ), blueprint.rate_unlimited(), logout_required(), validate_body(INTERACTION_CALLBACK_REQUEST_TYPE, { defer_validation: True }), validate_kwargs({ 'interaction_id': skema.SnowflakeType(), 'interaction_token': skema.StringType({ max_length: skema.UNSPECIFIED_MAX_LENGTH_PLEASE_FIX }), }), non_discord_origin_check, validate_response({ NO_CONTENT: skema.response.EmptyResponse }), function interaction_callback(interaction_id, interaction_token, validator) {}) ``` [13:59:34.0138] use a source map my dude [13:59:57.0464] true, that helps :-) [14:00:12.0507] yes, or with just function application using 😱 parentheses [14:00:40.0670] like if you were laying out an application [14:00:46.0857] and you wanted to combine these functionalities [14:00:53.0607] you would choose function application [14:00:55.0993] * you would *choose* function application [14:01:06.0065] What other JS library makes use of decorators? Stencil is the only one I can think of [14:01:18.0080] yes, I think code that uses functions is readable [14:01:18.0664] I am confused by the notion of function application being this weird thing [14:01:32.0299] function application is like... most code [14:01:38.0610] it is a very normal thing to do [14:01:51.0928] i feel like we have very different definitions of "most code" [14:02:08.0474] I don’t think even a company like Google , who are fans of decorators, have a JS library that uses them [14:02:18.0974] At least I don’t remember them in Whiz [14:02:24.0791] ember [14:02:26.0587] > <@anthonybullard:matrix.org> What other JS library makes use of decorators? Stencil is the only one I can think of Decorators were developed by a bunch of frameworks working together, with Angular mostly not participating in that group [14:02:42.0238] the code you linked has an average of almost one function application per line, _in addition_ to the decorator application [14:02:48.0972] lit-element, MobX, Aurelia, .... [14:03:02.0749] I forgot about kit [14:03:05.0054] sorry i meant, nested [14:03:11.0526] * I forgot about Lit [14:03:27.0212] > <@littledan:matrix.org> lit-element, MobX, Aurelia, .... (I actually do use Lit and look forward to using decorators to register my custom elements.) [14:03:57.0984] > <@shuyuguo:matrix.org> i've heard this assertion a few times, both here and in other arguments. how do i actually get a better handle on the size of the dev population that feels this way? Are you asking if "syntax matters" or whether "function decorators" are needed? Regarding the latter, I have encountered some inquiries from colleagues and other developers as to why there are class decorators but no function decorators. [14:04:07.0102] We have a web component framework, and have never had isssues with people calling the register function… [14:04:22.0708] Anthony Bullard: sorry who's "we"? [14:04:23.0262] +1 to Luca's and Ron's consistency argument [14:04:29.0678] The current trascriptioner injects newlines everywhere and worse, they capitalize every words at the beginning of the line [14:04:29.0720] like this is not readable code ``` blueprint.routes( 'POST', '/interactions///callback', { auth: AuthOptions(required = False), visibility: ApiVisibility.PUBLIC, name: 'create_interaction_response', } blueprint.rate_unlimited(logout_required(), validate_body(INTERACTION_CALLBACK_REQUEST_TYPE, { defer_validation: True }) validate_kwargs({ 'interaction_id': skema.SnowflakeType(), 'interaction_token': skema.StringType({ max_length: skema.UNSPECIFIED_MAX_LENGTH_PLEASE_FIX }), }, non_discord_origin_check(validate_response({ NO_CONTENT: skema.response.EmptyResponse }, function interaction_callback(interaction_id, interaction_token, validator) {})), ))), ) ``` [14:04:42.0116] * The current trascriptioner injects newlines everywhere and worse, they capitalize every word at the beginning of the line [14:04:48.0675] i'm actually not sure i even nested that correctly [14:04:48.0797] shu: ServiceNow [14:04:51.0155] decorating object literals is particularly nice because you can define enumerability/writability/configurability inline in a way you can't rn [14:04:52.0785] cuz how do you even read it [14:05:03.0028] > <@haxjs:matrix.org> Are you asking if "syntax matters" or whether "function decorators" are needed? Regarding the latter, I have encountered some inquiries from colleagues and other developers as to why there are class decorators but no function decorators. the latter [14:05:40.0618] > <@ljharb:matrix.org> decorating object literals is particularly nice because you can define enumerability/writability/configurability inline in a way you can't rn That sounds like a different problem that we could solve with no net new concepts or syntax [14:05:47.0299] > <@ljharb:matrix.org> decorating object literals is particularly nice because you can define enumerability/writability/configurability inline in a way you can't rn the obvious way to define these would unfortunately not expose that capability, which would presumably violate the "static shape" goal. We removed this capability from class decorators, didn't we? [14:05:48.0548] would you be happy to use pipeline to linearise it? [14:05:50.0417] i mean tbf i don't find the original code you posted readable either [14:05:56.0625] all i've heard are anecdotes like yours ("i know some people who want it") or assertions ("developers want this"). i'm saying that is not enough signal for me to make a judgment [14:06:17.0364] right, it's [citation needed] content [14:06:18.0078] i would not write this code in js today [14:06:26.0546] > <@anthonybullard:matrix.org> That sounds like a different problem that we could solve with no net new concepts or syntax i'm not sure how; engines would insist on syntax so they could statically know the shape of the object [14:06:28.0968] that's why its in python [14:06:29.0750] Stage-1 exploration can and should solicit better usage data than anecdotes. [14:06:37.0593] * Stage-1 exploration can and should solicit better usage/demand data than anecdotes. [14:06:48.0207] like i think you simply cannot structure large applications [14:07:09.0320] littledan: I’d be interested in seeing a minimal example of this to understand the problem [14:08:04.0597] > <@ljharb:matrix.org> i'm not sure how; engines would insist on syntax so they could statically know the shape of the object I don't see how decorators would provide a solution to this either [14:08:19.0431] empirically you can structure large applications in javascript [14:08:42.0826] * @ljharb I’d be interested in seeing a minimal example of this to understand the problem [14:08:47.0353] > <@littledan:matrix.org> I don't see how decorators would provide a solution to this either yeah they may not, i hadn't throught that through [14:09:23.0928] > <@nicolo-ribaudo:matrix.org> The current trascriptioner injects newlines everywhere and worse, they capitalize every word at the beginning of the line We passed this feedback to the transcription service yesterday. I will relay it again. Can you say which time period it applies to? (They swap people around) [14:09:37.0229] > <@robpalme:matrix.org> We passed this feedback to the transcription service yesterday. I will relay it again. Can you say which time period it applies to? (They swap people around) Since 15 minutes ago [14:09:44.0236] From 13:55 [14:09:49.0007] > <@robpalme:matrix.org> We passed this feedback to the transcription service yesterday. I will relay it again. Can you say which time period it applies to? (They swap people around) also, double spacing after periods :-( [14:10:03.0480] > <@robpalme:matrix.org> From 13:55 I think the autocapitalization is done by google forms though, so the only problem is the newlines [14:10:05.0057] > <@robpalme:matrix.org> We passed this feedback to the transcription service yesterday. I will relay it again. Can you say which time period it applies to? (They swap people around) * also, double spacing after periods :-( (as long as you're giving feedback) [14:10:06.0253] well for some definition of structure. my meaning is that they are all enormous messes or they rely on typescript decorators [14:10:08.0788] > <@robpalme:matrix.org> From 13:55 * I think the autocapitalization is done by google docs though, so the only problem is the newlines [14:10:15.0277] ljharb: that was correct when I was in High Scool [14:10:22.0856] I mean that's just good manners ;-) [14:10:48.0803] (but yes, in our patterns single space is consistent) [14:10:59.0629] it's correct for typewriters or non-proportional-width fonts. since the invention of the computer, it's no longer correct, but teacher dogma makes it persist. [14:11:17.0436] it also makes readability worse [14:11:31.0478] > <@nicolo-ribaudo:matrix.org> I think the autocapitalization is done by google docs though, so the only problem is the newlines I’m probably alone in this, but do we really need Google Docs, wouldn’t a plain text format be more accessible and machine process able? [14:11:32.0592] * it also makes readability worse, based on a few studies [14:11:55.0803] we need the realtime collaboration google docs provides, and hackmd can't handle that many people at once iirc [14:11:58.0285] Yeah it took me 10-15 years to stop [14:12:14.0744] > <@anthonybullard:matrix.org> I’m probably alone in this, but do we really need Google Docs, wouldn’t a plain text format be more accessible and machine process able? Don't the Google Docs use Markdown anyway? The rich formatting seems to be for convenience. [14:12:15.0529] when using a typewriter, certainly :-p [14:12:21.0583] also really want headings [14:12:55.0661] if we can configure gdocs to be in markdown instead, like hackmd, that'd be amazing [14:13:04.0244] * if we can configure gdocs to be in markdown instead, like hackmd, that'd be amazing (or find an alternative that scales as well) [14:13:10.0878] bakkot: # There you go [14:13:32.0824] I can research [14:13:32.0842] Time to build our own [14:13:36.0044] TCNotes [14:13:44.0651] Or maybe even build something [14:13:50.0982] I think it's hilarious that Discord added markdown headings [14:13:55.0584] (fwiw the "decorators before `export`" decision explicitly acknowledged that export decorators could never happen, is what i recall) [14:14:06.0963] * I think it's hilarious that Discord added markdown headings; basically just allows you to shout stuff [14:14:12.0850] > <@ljharb:matrix.org> (fwiw the "decorators before `export`" decision explicitly acknowledged that export decorators could never happen, is what i recall) I thought decorators are after export now [14:14:13.0635] nicolo-ribaudo: I’m on it [14:14:17.0126] * (fwiw the "decorators before `export`" decision explicitly acknowledged that export decorators could never happen, is what i recall - and import decorators imo don't make sense because of eval order) [14:14:17.0234] > <@rkirsling:matrix.org> I think it's hilarious that Discord added markdown headings; basically just allows you to shout stuff we were ordered to by the CTO [14:14:33.0158] > <@nicolo-ribaudo:matrix.org> I thought decorators are after export now they were gonna be, but then TS pushed and now both forms are allowed [14:14:41.0241] (but not on the same clas) [14:14:41.0874] Oh right [14:14:43.0433] * (but not on the same class) [14:14:55.0734] It feels like that was years ago [14:14:57.0624] > <@devsnek:matrix.org> we were ordered to by the CTO It seems every chat client does that now, just support inline markdown and tables! [14:14:57.0908] also i think it omits them from toString if they're before the export? [14:15:10.0451] > <@anthonybullard:matrix.org> It seems every chat client does that now, just support inline markdown and tables! tables don't work well on mobile [14:15:34.0211] sorry this is offtopic a bit heh [14:15:35.0709] > <@devsnek:matrix.org> tables don't work well on mobile Mattermost does it pretty well, wraps it in a scroll container [14:16:25.0264] Anyway, I can research a better transcription solution for minutes [14:16:34.0329] And present my findings [14:16:36.0997] but why [14:16:40.0181] what is the problem with docs? [14:16:55.0373] Whoa, do/did you work at Discord? [14:17:08.0898] ye [14:17:09.0755] Its opinionated on style in unhelpful ways for quickly entered text [14:17:16.0510] current employer [14:17:26.0025] Nice. [14:17:48.0746] I have transcribed a lot and it’s very frustrating [14:18:13.0791] At this point I've given out on formatting and I'm just fixing typos [14:18:19.0643] part of it was the transcriptionists' software and part of it was docs, i had thought the capitalization was fixed [14:18:45.0607] > <@shuyuguo:matrix.org> part of it was the transcriptionists' software and part of it was docs, i had thought the capitalization was fixed It seems like they do newline, word, space, and it gets capitalized [14:18:58.0632] If minutes were done solely by a third party, I’d say let them figure it out [14:19:03.0472] And it seems to be google docs (it also happens if I try doing it( [14:19:09.0451] * And it seems to be google docs (it also happens if I try doing it), not their software [14:19:25.0263] But delegates are, and it’s painful and prevents them from even absorbing the conversation [14:19:59.0874] Maybe shu can put in a CL to fix it 😂 [14:20:10.0631] heh i do not work in that part of google [14:20:29.0846] > <@shuyuguo:matrix.org> heh i do not work in that part of google Can you add `if url === google.docs { do something }` in V8 directly [14:20:42.0260] i believe i will be fired [14:21:07.0890] better to die a hero [14:21:16.0074] haha no [14:21:19.0263] that's a stupid thing to say [14:21:20.0165] No one wants that. If another open source option exists and works, I think evaluating it makes sense [14:21:21.0325] it's better to not die [14:21:42.0711] indeed it's nicer to live on the hill [14:21:47.0272] * indeed, it's nicer to live on that hill [14:21:48.0234] But I’m new around here, so I won’t die on that hill [14:21:56.0843] on the bones of those who died on the hill [14:22:03.0033] we used to use etherpad [14:22:18.0402] RIP [14:23:27.0014] I'm very struggling to focus and my notes-fixing quality is getting close to zero btw [14:23:31.0263] Help appreciated [14:23:49.0457] At least for the interactive discussion [14:24:01.0185] (there is already a second person working on it, but I'm doing very little) [14:25:05.0952] the newlines from the current transcriptionist are really going to be annoying to fix in post [14:25:06.0107] > <@shuyuguo:matrix.org> all i've heard are anecdotes like yours ("i know some people who want it") or assertions ("developers want this"). i'm saying that is not enough signal for me to make a judgment I understand that it should be approached with caution. However, given the size and diversity of the community, in reality, no one can assert how many of the 20 million JS developers worldwide want a specific feature. Even if there are some surveys, we can't even be sure if what developers understand aligns with what the committee might actually do. This is indeed a difficult problem, and I don't know how to solve it; I hope someone on the committee does. [14:25:44.0381] > <@bakkot:matrix.org> the newlines from the current transcriptionist are really going to be annoying to fix in post I can make sure to ad double newlines when we would want one [14:25:50.0861] So than we can try regexping it away [14:26:07.0621] it's mostly the capitalization I'm worried about [14:26:19.0682] I guess if they consistently add end-of-sentence punctuation we can regexp that away too [14:26:34.0962] > <@haxjs:matrix.org> I understand that it should be approached with caution. However, given the size and diversity of the community, in reality, no one can assert how many of the 20 million JS developers worldwide want a specific feature. Even if there are some surveys, we can't even be sure if what developers understand aligns with what the committee might actually do. This is indeed a difficult problem, and I don't know how to solve it; I hope someone on the committee does. right, no one can assert. surveys is maybe the best we have [14:27:25.0523] Case studies from real codebases are useful too. [14:27:40.0949] /me glances at gzemnid [14:27:47.0305] Also Anonymous Cheetah, can you move your cursor to not overlap with the transcriptionist otherwise I cannot read the previous line [14:27:50.0399] we should charter a TG to explore this [14:28:50.0648] hax (HE Shi-Jun): being new , I’ve always wondered what our principle is in adding a feature or syntax. Is it just corpus analysis/paving the most heavily trafficked cow paths? Or is there another set of principles that guides the language design. If there is, I’ve never seen it. [14:29:55.0035] there isn't really one, everybody brings their own [14:30:13.0537] there is no agreed-upon set of principles, that's why things get heated [14:30:57.0520] ljharb: interesting. I think that could be good, but also very bad. It’s good context to hear from you vets [14:31:18.0966] indeed it's both at the same time, which is why we haven't been able to come up with a better system :-) [14:31:22.0408] * indeed it's both at the same time, which is probably why we haven't been able to come up with a better system :-) [14:31:23.0966] it's just taste, in every language [14:31:32.0332] yeah pretty much [14:31:49.0494] that said there are some north star principles that often trump others [14:31:52.0679] lately i've been trying to approach this in a "don't yuck someone's yum" sort of way [14:31:59.0219] oh boy [14:32:04.0054] I do not think that is a good path to a good language [14:32:13.0173] the language is already not good [14:32:14.0753] bakkot: I think languages where the creator is involved in the language design process have at least some principle [14:32:24.0628] > <@devsnek:matrix.org> the language is already not good ok but like... we could avoid making it worse. [14:32:26.0248] everyone has to read other people's code [14:32:36.0525] yucking someone's yum is a big part of the primary job of any software maintainer imo [14:32:48.0014] It's worse [14:32:49.0578] * yucking someone's yum is a big part of the primary job of any software maintainer imo - in the "no is temporary, yes is permanent" mindset [14:32:52.0295] Now newlines are every 40 chars or so [14:32:58.0391] But at least there is no auto capitaliztion [14:33:03.0155] Let's keep it like this actually [14:33:12.0957] > <@shuyuguo:matrix.org> right, no one can assert. surveys is maybe the best we have As I mentioned, surveys can't ensure a consistent understanding either. My personal approach is to understand why people need it. In the case of function decorators, my impression is that as soon as developers have used class/method decorators, they almost inevitably end up asking why there aren't function decorators (currently, I tell them it's because hoisting is an unresolved issue). [14:33:17.0008] * yucking someone's yum is a big part of the primary job of any software or standard maintainer imo - in the "no is temporary, yes is permanent" mindset [14:33:31.0126] bakkot: this. I’m really worried about where we could go. ES today is basically the Raku to the JS of 9 years ago’s Perl 4 [14:33:52.0611] Oh man, a Perl 6 reference. [14:34:00.0831] > <@haxjs:matrix.org> As I mentioned, surveys can't ensure a consistent understanding either. My personal approach is to understand why people need it. In the case of function decorators, my impression is that as soon as developers have used class/method decorators, they almost inevitably end up asking why there aren't function decorators (currently, I tell them it's because hoisting is an unresolved issue). "best-attempt solutions are imperfect" is not an argument for "anecdotes and assertions are sufficient" [14:34:01.0666] I’m being transported back to childhood. [14:34:33.0234] Synopses, Apocalypses, Exegeses. Parrot. [14:34:35.0155] javascript is so tiny right now, i just cannot bring myself to worry about it having too much stuff [14:34:49.0389] > <@anthonybullard:matrix.org> bakkot: this. I’m really worried about where we could go. ES today is basically the Raku to the JS of 9 years ago’s Perl 4 say more? [14:35:01.0545] > <@devsnek:matrix.org> javascript is so tiny right now, i just cannot bring myself to worry about it having too much stuff javascript has quite a lot of syntax [14:35:03.0731] tiny stdlib [14:35:06.0100] lot of syntax [14:35:26.0982] yeah, I'm not sure in world JS is syntactically tiny [14:35:29.0407] and more all the time [14:35:31.0600] We live in a world where 70% of active websites are written in IE6 compliant JQuery or similar, but where most modern software is written in a wildly different ESNext [14:35:32.0547] * yeah, I'm not sure in what world JS is syntactically tiny [14:35:57.0860] > <@anthonybullard:matrix.org> hax (HE Shi-Jun): being new , I’ve always wondered what our principle is in adding a feature or syntax. Is it just corpus analysis/paving the most heavily trafficked cow paths? Or is there another set of principles that guides the language design. If there is, I’ve never seen it. I also have same feeling from beginning. I have to say, it's very shocked that Dan said TC39 do not have roadmap in one meeting I attended. [14:36:26.0215] It’s tough, but I can definitely understand a Go program written 2009, and might write that same code today [14:36:30.0576] > <@anthonybullard:matrix.org> We live in a world where 70% of active websites are written in IE6 compliant JQuery or similar, but where most modern software is written in a wildly different ESNext sir, please. this is my emotional support jQuery [14:36:38.0825] whoops, this isn't tdz [14:37:02.0277] And I’m one who wishes selfishly for records, tuples , and pattern matching [14:37:04.0584] OT: How do I get into TDZ? [14:37:12.0159] #temporaldeadzone:matrix.org [14:37:18.0201] i think the current language has an average amount of syntax [14:37:28.0731] there's definitely a lot of syntax proposals rn [14:37:37.0921] I find it useful to think about JS as an accidentally general purpose programming language designed to be the primary scripting language for the web; as the web platform evolves, so should we. [14:38:03.0886] I wish we could spend more time on stdlib stuff than syntax is what I’m trying to say 😂 [14:38:18.0329] +1 for 3, hoisting is bad anyways and it conceptually can't work ¯\_(ツ)_/¯ [14:38:20.0387] * +1 for 3, hoisting is bad anyways and it conceptually can't work ¯\\\_(ツ)\_/¯ [14:38:46.0584] * +1 for 3, hoisting is bad anyways and it conceptually can't work for decorators ¯\\\_(ツ)\_/¯ [14:38:50.0807] > <@anthonybullard:matrix.org> It’s tough, but I can definitely understand a Go program written 2009, and might write that same code today ah so the worry is "it's changing too fast"? [14:39:25.0836] shu: that a developer in his career is likely to encounter both, in their job and in their learning [14:39:40.0946] yet they have not joined Ecma. curious. `/s` [14:39:51.0289] "both" meaning modern JS and pre-modern JS? [14:39:58.0900] And much of the ecosystem has the same problem [14:40:05.0278] > <@haxjs:matrix.org> I also have same feeling from beginning. I have to say, it's very shocked that Dan said TC39 do not have roadmap in one meeting I attended. TC39 is a politico-technical miracle, the miracle being cooperation between a bunch of mutually competing organizations and stakeholders, each with their own vision, without a strong center of power like a BDFL. The one roadmap, as far as I know, is to Not Break the Web and to improve interoperability between existing implementations. I wonder if we could come to a consensus on overall vision for future language features. I suspect that it’s not possible. [14:40:06.0806] shu: yes [14:40:31.0966] jschoi: it’s be exciting to try [14:40:48.0600] > <@jschoi:matrix.org> TC39 is a politico-technical miracle, the miracle being cooperation between a bunch of mutually competing organizations and stakeholders, each with their own vision, without a strong center of power like a BDFL. The one roadmap, as far as I know, is to Not Break the Web and to improve interoperability between existing implementations. > I wonder if we could come to a consensus on overall vision for future language features. I suspect that it’s not possible. not only that, I don't believe it's necessary! development via game theory 🔥 [14:41:09.0960] I think if we had a stronger stdlib that helped solve web scripting problems, we’d have a different ecosystem [14:41:17.0022] something something prisoner's dilemma [14:41:33.0053] Anthony Bullard: does the 100% back compat not help understanding in practice? [14:41:44.0905] we've presented vision talks in the past, and Mark was suggesting yesterday that we start that process again [14:41:45.0982] like, are the feature sets that are used disjoint? [14:41:47.0954] > <@rkirsling:matrix.org> something something prisoner's dilemma perhaps, or perhaps the lack of authority and a singular vision allows us to be more dynamic and adaptable than most others [14:42:14.0245] lets just take a small gamble. give me six months of total control over ecmascript, we'll see how it goes. if its bad, we can just revert it :^) [14:42:21.0789] shu: no because the patterns change. I have coworkers who don’t recognize var, or using the function keyword [14:42:45.0276] i mean on some level that's an education problem [14:42:56.0813] > <@anthonybullard:matrix.org> shu: no because the patterns change. I have coworkers who don’t recognize var, or using the function keyword where do you think the division of responsibilities ought to be between education (in the broad sense) and the language? [14:43:02.0572] otherwise that logic would mean we can never provide a replacement/improved pattern for anything [14:43:03.0010] ah jordan asked my question [14:43:10.0811] Or understand prototypal inheritance, because we hid it behind classes which don’t really exist [14:43:12.0507] you did it more eloquently :-) [14:43:34.0100] i think the language is 100% responsible for education and javascript is super hard failing [14:43:38.0075] > <@anthonybullard:matrix.org> Or understand prototypal inheritance, because we hid it behind classes which don’t really exist i mean part of that is resolved by much of the ecosystem preferring to avoid inheritance entirely. [14:43:40.0256] but i also recognize why this is the case [14:43:57.0313] what does it mean for a language to be responsible for education? [14:44:00.0073] like, this committee? [14:44:03.0848] look at rust [14:44:17.0183] rust is a singular software project [14:44:26.0205] we are disparate software projects that come together for interop [14:44:28.0824] yeah, i realize its hard to translate to this. [14:44:36.0999] shu: I think education has definitely failed here. No doubt. [14:44:41.0139] but that doesn't change the final outcome, which is that learning js kinda sucks [14:44:47.0774] actually in TG2 we have MDN docs as a hard Stage 3 requirement, that's pretty easy to implement across committee IMO [14:44:50.0170] snek: you mean because they have a book? we have books [14:44:55.0867] it's not much but it's a start [14:44:56.0975] I am preparing [a guide for our transcriptionist](https://docs.google.com/document/d/1DOB2dGRVHv4kD3iyLixIBEUNw0iVefwMm_pzZiKQydo/edit). Please edit this doc as you see fit so we can convey our desired standards. Then we will send it to the transcription service. [14:45:10.0755] > <@michaelficarra:matrix.org> snek: you mean because they have a book? we have books some of them probably don't mention `var` [14:45:41.0875] some of them definitely do though [14:45:54.0414] so read 2 books? [14:46:00.0381] 🤷 [14:46:07.0293] its impossible to say [14:46:10.0418] Excellent summary/conclusion [14:46:48.0905] Sorry everyone, I didn’t mean to start an existential discussion. Just trying to kind of understand our mandate and our process [14:46:54.0143] > <@shuyuguo:matrix.org> "best-attempt solutions are imperfect" is not an argument for "anecdotes and assertions are sufficient" It's certainly good to have a survey. For me, communicating with others is like conducting a survey, albeit with a limited sample size. If possible, I try to understand the sources of their thoughts. At least to me, they are not merely "anecdotes." [14:47:00.0638] asking questions is good! [14:48:08.0800] > <@devsnek:matrix.org> look at rust I’m imagining a world with: • The JavaScript Programming Language, a book by TC39 • The JavaScriptonomicon: The Dark Arts of Unsafe JavaScript, a book by TC39 • JavaScript by Example, a book by TC39 • JavaScriptlings, a course for beginners by TC39 [14:48:15.0653] snek: too bad I couldn’t be in SD to have this convo in person [14:48:28.0687] > <@anthonybullard:matrix.org> Sorry everyone, I didn’t mean to start an existential discussion. Just trying to kind of understand our mandate and our process i interpret the mandate to bottom out at "ensuring interop across JS platforms, mostly web browsers" [14:48:36.0875] > <@jschoi:matrix.org> I’m imagining a world with: > • The JavaScript Programming Language, a book by TC39 > • The JavaScriptonomicon: The Dark Arts of Unsafe JavaScript, a book by TC39 > • JavaScript by Example, a book by TC39 > • JavaScriptlings, a course for beginners by TC39 Well "JavaScript the good parts" is a terrible book but it was written by a delegate [14:48:37.0328] jschoi: I see what you did there [14:48:51.0547] over the years it has evolved to "stewardship of JS", but i don't think that's actually the core mandate [14:49:29.0664] nicolo-ribaudo: that was my favorite JS book for at least 5 years. And how I learned JS to do actual programming [14:50:31.0434] > <@usharma:igalia.com> actually in TG2 we have MDN docs as a hard Stage 3 requirement, that's pretty easy to implement across committee IMO Continued and stronger collaboration between TC39 and MDN is indeed high-impact and low-hanging fruit. [14:50:31.0645] a rather controversial figure in committee actually wrote a whole set of books that went quite deep into the language and released them on the internet [14:50:45.0268] they were quite helpful when I first started learning JS [14:50:55.0761] > <@usharma:igalia.com> actually in TG2 we have MDN docs as a hard Stage 3 requirement, that's pretty easy to implement across committee IMO * Continued and stronger collaboration between TC39 and MDN is indeed high-impact and low-hanging fruit. Probably the biggest method of general community documentation and outreach. [14:50:59.0173] > <@shuyuguo:matrix.org> over the years it has evolved to "stewardship of JS", but i don't think that's actually the core mandate Who decides what the core mandate actually is? [14:51:05.0007] Link? [14:51:07.0310] it helped that I _didn't_ actually know JS [14:51:09.0081] > <@usharma:igalia.com> a rather controversial figure in committee actually wrote a whole set of books that went quite deep into the language and released them on the internet You don't know js? [14:51:21.0995] > <@nicolo-ribaudo:matrix.org> You don't know js? I probably don't, still, yeah 😛 [14:51:23.0443] littledan: I thought you did 😉 [14:51:45.0148] our official scope says, > Standardization of the general purpose, cross platform, vendor-neutral programming language ECMAScript® (JavaScriptTM). This includes the language syntax, semantics, and libraries and complementary technologies that support the language. [14:51:47.0235] > <@littledan:matrix.org> Who decides what the core mandate actually is? the equilibrium of participants' reasons i guess? [14:51:56.0904] surely we have a nominal mandate in the TC charter [14:52:00.0294] > <@jschoi:matrix.org> Continued and stronger collaboration between TC39 and MDN is indeed high-impact and low-hanging fruit. Probably the biggest method of general community documentation and outreach. 100%. We already have systems in place and people who are motivated towards this on both sides. [14:52:13.0772] I wonder what it'll take for the committee to make an official effort in this direction [14:52:44.0823] lol @ ljharb [14:52:45.0183] yeah i'm pretty sure what it'll take is always money [14:52:46.0207] 🙅 [14:52:55.0656] > <@usharma:igalia.com> I wonder what it'll take for the committee to make an official effort in this direction It starts with somebody putting it on the agenda [14:53:01.0959] > <@usharma:igalia.com> lol @ ljharb 100% serious [14:53:11.0880] dunno, maybe if we all collectively decided to make it part of the staging process it could just change the dynamic [14:53:20.0328] Let MF be your hero and be the process change you want to be [14:53:21.0743] please, read Dave Herman's book instead [14:53:27.0588] if the staging process can make payments, then sure, that'd work [14:53:42.0942] > <@nicolo-ribaudo:matrix.org> Let MF be your hero and be the process change you want to be why are you singling out Michael Ficarra /s [14:53:49.0445] ljharb: so now we require payment to advance stages? [14:53:52.0736] the staging process requires tests to be written first and almost the only people who write or review tests are the ones paid to do so [14:54:06.0167] > <@usharma:igalia.com> why are you singling out Michael Ficarra /s Well he just put a lot of effort in a process change! :) [14:54:08.0263] but jokes apart, yes, I guess I could make a quick short spiel at the Helsinki meeting about it [14:54:17.0088] > <@anthonybullard:matrix.org> ljharb: so now we require payment to advance stages? lol we would be doing precisely that, if we added a bunch of otherwise unpaid work as a requirement. [14:55:19.0457] Okay. Gotta finish this Go book and I will [14:56:00.0005] > <@bakkot:matrix.org> I feel very strongly that we should not do parameter decorators regardless of the outcome of this discussion I need to set aside some time to discuss this with you further. How they are implemented in TS today for legacy decorators is as a far more convenient way to write: ```js class C { @C @__param(0, A) @__param(1, B) method(a, b) {} } ``` as ```js class C { @C method(@A a, @B b) {} } ``` TypeScript parameter decorators only give you ordinal position, but actual native parameter decorators could be far more useful. Parameter decorators aren't actually net new capabilities, but are far more convenient than having to manually maintain order in the context of refactors (i.e., adding new parameters, reordering parameters, etc.). They reduce repetition and boilerplate to potentially provide better reflective capabilities, such as parameter names, whether the parameter is a rest parameter, etc. [14:58:25.0438] What are @A and @B doing here? Not to mention @C? It’s hard to evaluate this without context on the problem we are solving [14:58:55.0601] > <@bakkot:matrix.org> all syntax needs to be learned by all learners of the language, so that's a high cost As stated elsewhere, that cost is already paid with decorators in general. IMO, its a higher cost to only be able to apply decorators inconsistently. [14:59:44.0151] > <@rbuckton:matrix.org> As stated elsewhere, that cost is already paid with decorators in general. IMO, its a higher cost to only be able to apply decorators inconsistently. Knowing the syntax exists is one thing. It’s another to understand what it’s doing and when to use it and how [15:00:29.0832] Yes, which is why I've argued for maintaining consistency in all aspects and guides my preference related to hoisting. [15:00:31.0859] How do I find the definition of a decorator? Might not be obvious (though better in JS than Java) [15:00:47.0601] rbuckton: [15:01:09.0557] Can you clarify what you mean by "definition of a decorator"? [15:01:37.0854] The implementation. Im speaking as a learner of JS or novice [15:01:55.0104] As in, for a given decorator, where is is it declared? [15:02:41.0476] Yes. I know the answer knowadays is come+click/gd [15:02:50.0139] * Yes. I know the answer knowadays is cmd +click/gd [15:03:33.0543] But a decorator is a new concept, whereas a function is a part of every programming language of the past 50 years [15:04:29.0302] That is essentially the answer. A decorator is just a regular function, its just that the runtime will invoke it on your behalf with contextual information about the decorated declaration. [15:05:16.0871] And how simple will it be to understand what a decorator does in its implementation to that declaration? [15:05:38.0763] From a logical point of view, there are many languages with similar capabilities. C# has attributes, Java has annotations, Python has decorators, C++ has templates [15:05:45.0322] Is it more complicated or simpler to understand than how you would accomplish the same task with existing concepts? [15:06:36.0587] rbuckton: and those are either highly misunderstood or despised (templates) features of the language [15:06:44.0209] I'll need to come back to this, sory [15:06:45.0633] * I'll need to come back to this, sorry [15:06:52.0104] rbuckton: no worries [15:07:02.0379] Probably should be in a thread anyway [15:07:07.0164] Sorry for the spam [15:07:52.0411] a newcomer will just command-click anything they don't understand, no? [15:08:24.0095] https://matrix.to/#/!WgJwmjBNZEXhJnXHXw%3Amatrix.org/%24-6WE2sDlOYmSmPR_QB6JOp6rGroz3yUP3ZMeCwnmyYs [15:09:34.0340] right but i mean, even for any new concept [15:09:45.0160] that solution is now a universal answer to literally anything that looks like an identifier [15:09:46.0676] > <@rbuckton:matrix.org> From a logical point of view, there are many languages with similar capabilities. C# has attributes, Java has annotations, Python has decorators, C++ has templates C++ Templates aren't quite analogous to decorators, but my coworker Dan Katz is proposing that "custom attributes" be introspectable via C++ Reflection. [15:09:48.0092] * that solution is now a universal answer to literally anything that looks like an identifier/property name [15:10:26.0449] > <@anthonybullard:matrix.org> Probably should be in a thread anyway nothing should be in a thread, threads in matrix are awful [15:10:37.0701] death to threads!! [15:11:15.0702] death to matrix [15:11:20.0839] bakkot: oh, element handles them fine (I think 😬) [15:11:21.0021] oh i thought you meant in programming [15:12:14.0283] > <@rbuckton:matrix.org> As stated elsewhere, that cost is already paid with decorators in general. IMO, its a higher cost to only be able to apply decorators inconsistently. I agree when it comes to adding decorators to object fields. I don't agree when it comes to adding decorators to functions. [15:12:16.0811] https://www.sqlite.org/faq.html#q6 [15:12:18.0647] > <@anthonybullard:matrix.org> bakkot: oh, element handles them fine (I think 😬) it does not [15:14:46.0151] > <@shuyuguo:matrix.org> yeah i'm pretty sure what it'll take is always money With respect to TC39 and MDN: The Open Web Docs project exists to fill gaps in MDN, and if there are TC39-related gaps, I bet they would like to hear from us. https://github.com/openwebdocs/project/issues . We could also have Ecma sponsor Open Web Docs to ensure there is good coverage of TC39 work (something which has been discussed previously, endorsed by this committee, but somehow didn't make it into a past Ecma budget) [15:15:50.0123] > <@shuyuguo:matrix.org> yeah i'm pretty sure what it'll take is always money * With respect to TC39 and MDN: The Open Web Docs project exists to fill gaps in MDN, and if there are TC39-related gaps, I bet they would like to hear from us. https://github.com/mdn/content/issues https://github.com/openwebdocs/project/issues . We could also have Ecma sponsor Open Web Docs to ensure there is good coverage of TC39 work (something which has been discussed previously, endorsed by this committee, but somehow didn't make it into a past Ecma budget) [15:16:08.0038] * With respect to TC39 and MDN: The Open Web Docs project exists to pay people fill gaps in MDN, and if there are TC39-related gaps, I bet they would like to hear from us. https://github.com/mdn/content/issues https://github.com/openwebdocs/project/issues . We could also have Ecma sponsor Open Web Docs to ensure there is good coverage of TC39 work (something which has been discussed previously, endorsed by this committee, but somehow didn't make it into a past Ecma budget) [15:16:12.0314] * With respect to TC39 and MDN: The Open Web Docs project exists to pay people to fill gaps in MDN, and if there are TC39-related gaps, I bet they would like to hear from us. https://github.com/mdn/content/issues https://github.com/openwebdocs/project/issues . We could also have Ecma sponsor Open Web Docs to ensure there is good coverage of TC39 work (something which has been discussed previously, endorsed by this committee, but somehow didn't make it into a past Ecma budget) [15:17:21.0674] Yes https://ecma-international.org/technical-committees/tc39/ [15:18:12.0596] Probably the first step would be for people to articulate more clearly what's missing in MDN, so we can ask OWD if they're going to do it, and if they're not going to, then figure out how else to solve the problem. [15:21:11.0569] I recall that this topic has been proposed before and can't reach stage 1, but I forgot why. [15:21:55.0279] what was proposed before was elision in function argument lists [15:22:00.0671] like `function (a, , c) {` [15:22:12.0490] * what was proposed before was elision in function argument lists, iirc [15:23:06.0892] I remember there were other options, `void` was also listed. [15:25:34.0002] https://github.com/devsnek/proposal-unused-function-parameters [15:26:06.0589] man i can't believe i wrote that [15:26:25.0592] Could we just use hackmd? [15:26:26.0907] weird how we change over time [15:26:49.0297] like i'm not against it i just can't believe i cared about it so much to write up a proposal [15:26:51.0616] p sure no, hackmd can't handle our scale [15:27:07.0888] When you were young and had energy for life [15:28:11.0137] FYI, Zoom is acting up for me and I am disconnected. I have no need to speak in my queue item. [15:29:59.0438] I found the array ellision discussion confusing. Is anyone actually proposing that we enable `[1, void, 2]` in expression position? [15:30:16.0907] is that not proposed [15:30:21.0925] i thought it was but i am not a fan [15:30:32.0133] i thought that was a motivating example actually [15:30:34.0040] > <@littledan:matrix.org> I found the array ellision discussion confusing. Is anyone actually proposing that we enable `[1, void, 2]` in expression position? ron's slide says he's weakly recommending supporting that, for consistency [15:30:40.0882] as contrasted against `[1, , ]` which iterates twice not thrice [15:30:42.0611] but it doesn't have to be included if the room doesn't like it [15:30:45.0226] in the RHS? [15:30:51.0461] * but it doesn't have to be included if the room doesn't like it (in array literals) [15:30:53.0125] oh in the RHS [15:31:01.0210] what does that mean in the RHS [15:31:02.0209] but for array destructuring yes [15:31:13.0794] > <@shuyuguo:matrix.org> what does that mean in the RHS elision [15:31:16.0015] (not just LHS because you can destructure in function arg lists) [15:31:16.0572] in the RHS = as an expression, rather than a restructuring pattern [15:31:27.0085] in the RHS of an array literal it would mean elision, yes [15:31:27.0087] * in the RHS = as an expression, rather than a destructuring pattern [15:31:52.0341] > <@ljharb:matrix.org> in the RHS of an array literal it would mean elision, yes right so is that proposed for inclusion here? [15:32:01.0743] weakly, yes [15:32:03.0063] or was it just, "if we were to support it, it should mean array hole"? [15:32:05.0415] * weakly, yes (per the slide) [15:32:10.0103] * weakly, yes (per the slide) but could be excluded [15:32:19.0865] it was both i think? [15:32:31.0556] "we can support it or not, but if we do, it must mean a hole" [15:32:37.0589] I am against void in expressions and interested in void only being in Arguments/LHS. [15:32:43.0108] * I am against void in array expressions and interested in void only being in Arguments/LHS. [15:32:45.0355] * "we can support it or not, i weakly suggest we do for consistency, and if we do, it must mean a hole" [15:32:51.0390] * "we can support it or not, i weakly suggest we do for consistency, and if we do, it must mean a hole" was my reading of the slide [15:32:52.0717] > <@ljharb:matrix.org> "we can support it or not, i weakly suggest we do for consistency, and if we do, it must mean a hole" right, this discussion was confusing since I don't see any demand for this feature [15:33:28.0529] i think perhaps the slides went more in depth than necessary with exploring potential consistency applications of support. [15:33:33.0590] * i think perhaps the slides went more in depth than necessary with exploring potential consistency applications of where to support it. [15:35:45.0854] nicolo-ribaudo: i've stated many times that repurposing a valid identifier should always be a nonstarter, fwiw [15:35:59.0119] ljharb: say more about why? [15:36:03.0396] * nicolo-ribaudo: i've stated many times that repurposing a valid identifier should always be a nonstarter, fwiw (re `_`) [15:36:16.0931] > <@ljharb:matrix.org> nicolo-ribaudo: i've stated many times that repurposing a valid identifier should always be a nonstarter, fwiw (re `_`) `x |> f(it)` [15:36:23.0540] because it would be confusing, and `_` is used as a normal identifier in many codebases [15:36:36.0725] > <@jschoi:matrix.org> `x |> f(it)` yes, i've rejected/blocked that too for the same reason [15:36:56.0199] `void` is the same weight as a identifier in my editor [15:36:57.0184] * because it would be confusing, and `_` is used as a normal identifier in many codebases (lodash/underscore alone, let alone other code) [15:37:07.0268] It **cannot** be `void` [15:37:09.0830] What does it mean to say that something is a non-starter? Is this implying something about consensus/blocking? [15:37:26.0133] yes [15:37:39.0908] we've discussed the possibility of hackmd. and I have been told it can handle our scale, with it having been stated that others have used it with more concurrent users than we have [15:37:59.0823] I support this proposal. But I don't know why in that time, it was rejected (As the notes, unused param proposal was rejected by MM and YSV.), if today it is accepted, I am happy. But also it shows some randomness. [15:38:05.0381] we ended up with: maybe we can try it for a single topic some time [15:38:08.0969] making a previously valid identifier magic at this point is far more harm than any benefit any proposal could provide, and i'm aware of `await`. [15:38:13.0556] what about like `..` [15:38:16.0922] * `void` is the same weight/color as a identifier in my editor [15:38:18.0308] > <@jridgewell:matrix.org> `void` is the same weight as a identifier in my editor what editor is that? [15:38:23.0327] why does it not colorize keywords differently? [15:38:24.0137] `array.map((.., i) => i)` [15:38:25.0577] > <@jridgewell:matrix.org> `void` is the same weight as a identifier in my editor having trouble understanding this. all keywords look like idents but behave very differently? is the argument you eyeball them both the same and that's okay? [15:38:30.0342] probably too confusing with `...` [15:38:38.0101] > <@ljharb:matrix.org> because it would be confusing, and `_` is used as a normal identifier in many codebases (lodash/underscore alone, let alone other code) Indeed, I am still in agreement about this principle. Makes moving code less contextually fragile. [15:39:00.0813] > <@ljharb:matrix.org> because it would be confusing, and `_` is used as a normal identifier in many codebases (lodash/underscore alone, let alone other code) * Indeed regarding the pipe topic, I am still in agreement about this principle. Makes moving code less contextually fragile. [15:39:20.0791] Vim with Solarized theme and `vim-polyglot` syntax highlighting [15:39:57.0204] > <@jridgewell:matrix.org> sent an image. Is this the same color for yield and await? [15:40:13.0649] If not, seems like a bug with the theme. [15:40:25.0176] > <@shuyuguo:matrix.org> having trouble understanding this. all keywords look like idents but behave very differently? is the argument you eyeball them both the same and that's okay? `void` isn't a common keyword, so it hasn't mattered that it's exactly the same as an identifier. [15:40:48.0804] but like, now it will be? [15:41:00.0615] i agree that it seems like an editor/theme issue [15:41:03.0148] the very very commonly used TS no-floating-promises rule uses `void` as a way to mark a promise as not-needing-to-be-awaited, so it's not super rare [15:41:10.0388] Normal keywords are styled [15:41:23.0970] also, why make some keywords second-class? Seems like a bug in the syntax highlighting [15:41:35.0650] theme issue [15:41:45.0965] But even if it were styled differently, it would still standout when the whole point is for it to disappear [15:41:48.0562] justin i'm not sure what you're saying here. your editor colors `void` the same as other identifiers? [15:42:25.0779] it should stand ouit [15:42:27.0548] * it should stand out [15:42:32.0009] it's discarding something [15:42:39.0832] my claim is, whatever we choose here, unless egregiously bad, people will get used to it [15:43:17.0214] i think void is the last bad option i've seen so far [15:43:22.0518] * i think void is the least bad option i've seen so far [15:43:30.0606] duplicate bindings is an error in strict mode [15:43:35.0060] ljharb: ^ [15:43:59.0750] ah thanks [15:44:08.0270] > <@ljharb:matrix.org> it's discarding something Completely disagree. The reason `function foo(_) {}` is so nice is because it disappears. [15:44:10.0658] is it actually true that people use `_` that often? it's been a long time since I saw that; even with lodash people just pull in the specific named helpers or pull it in as `lodash`, most of the time [15:44:17.0068] i gotta say i'm not excited to find out if `_` is compatible [15:44:22.0446] like it certainly _used_ to be a thing [15:44:29.0543] i have nothing against it [15:44:35.0565] Does your editor theme make `_` more muted? [15:44:48.0260] It's been years since I've seen `_` be the underscore library. [15:44:50.0004] I think _ is the most acceptable valid identifier to become a new piece of syntax [15:45:01.0442] If not for underscore [15:45:06.0314] > <@shuyuguo:matrix.org> i gotta say i'm not excited to find out if `_` is compatible I think it can be done without changing semantics of any currently legal program [15:45:20.0348] > <@shuyuguo:matrix.org> i gotta say i'm not excited to find out if `_` is compatible What I propose is only to relax some errors. Declaring to `_` twice would become always valid, but in case where it currently throws than you still wouldn't be able to _read_ it [15:45:26.0839] it just lets you redeclare it, and if redeclared then you can't refer to it [15:45:28.0412] > <@bakkot:matrix.org> I think it can be done without changing semantics of any currently legal program then sgtm [15:45:34.0705] do transpilers not emit `_` as a variable [15:45:41.0975] * do transpilers not emit `_` as an identifier [15:45:44.0551] * do minifiers not emit `_` as an identifier [15:45:50.0545] nicolo-ribaudo: snek they do [15:45:55.0607] > <@devsnek:matrix.org> do minifiers not emit `_` as an identifier Not Babel, but again we wouldn't be changing existing code [15:46:00.0521] > <@nicolo-ribaudo:matrix.org> What I propose is only to relax some errors. Declaring to `_` twice would become always valid, but in case where it currently throws than you still wouldn't be able to _read_ it then no longer sgtm! sounds like special case proliferation in many parts of the frontend [15:46:15.0088] > <@devsnek:matrix.org> do minifiers not emit `_` as an identifier not usually; you start with like `e s t f` etc, for better compressibility [15:46:26.0846] > <@jridgewell:matrix.org> Completely disagree. The reason `function foo(_) {}` is so nice is because it disappears. i don't know what you mean by that. the function syntax is something that always pops out to me, and my syntax highlighting reenforces that (but it pops out to me even without highlights) [15:46:59.0743] clearly it's something subjective tho [15:47:02.0613] > <@shuyuguo:matrix.org> then no longer sgtm! sounds like special case proliferation in many parts of the frontend It would be in the parser only, but also we could instead go with "last declaration wins" semantics that sloppy var ahs [15:47:14.0048] > <@jridgewell:matrix.org> sent an image. your identifiers are red, the highest contrasting thing in that screenshot [15:47:58.0971] > <@nicolo-ribaudo:matrix.org> It would be in the parser only, but also we could instead go with "last declaration wins" semantics that sloppy var ahs eh, not convinced [15:48:09.0761] msaboff bindings are basically the only place where this proposal applies, and `undefined` can become one already [15:48:16.0981] But I'm not confused whether `_` is something I care about, vs `void` looking exactly like a binding name. [15:48:25.0151] Trying to rejoin Zoom on my phone, need to be let in again, sorry. [15:48:51.0346] jschoi it doesn't show you in the lobby [15:49:35.0758] > <@jridgewell:matrix.org> But I'm not confused whether `_` is something I care about, vs `void` looking exactly like a binding name. you had to learn the convention of `_` being something to ignore tho [15:49:48.0792] > <@usharma:igalia.com> jschoi it doesn't show you in the lobby Sorry, try again now? [15:50:27.0463] jschoi nothing ☹️ [15:50:41.0891] maybe I lost host status when I reconnected? [15:50:42.0667] sec [15:50:48.0295] I'll ask the other chairs [15:50:53.0971] > <@ljharb:matrix.org> you had to learn the convention of `_` being something to ignore tho It is visibly small, making it very easy [15:51:09.0650] Thanks! [15:51:32.0713] right. but what i'm suggesting is that "easy to disappear" is strongly undesirable, because discarding something should be highly visible and jarring [15:52:01.0693] We have very different goals, then. [15:53:05.0366] I want it to be clear to the reader that I've intentionally ignored this binding, but not confuse them whether this is a real biding. [15:53:05.0731] yeah no it definitely should not be [15:53:06.0742] I think it’s not a big ask to ask JavaScript developers to be aware of the permanent set of permanent keywords in the language. It’s not like void was ever a binding name, and I was always aware of it from when I first learned the language and the set of legal identifiers. Is the concern with its appearance to developers during rapid visual scanning? [15:53:18.0924] languages with `_` are widespread and the feature is widely loved [15:53:43.0041] `function foo(_, foo, bar) {}` vs `function foo(_, bar baz {}` [15:54:00.0625] * `function foo(void, foo, bar) {}` vs `function foo(_, bar baz {}` [15:56:17.0055] while everyone's here, if you would like to think about async iterators, I have written up the two major open questions in my mind, namely: - do you enforce promises settle in order? if so, you can't do rust-style `bufferUnordered`, but if not, you can observe otherwise-impossible sequences. - how do you get concurrency for helpers like `.find`? https://gist.github.com/bakkot/ad58565b203cd845524ac702c3f289f0 [15:56:28.0476] and now I need to catch up on matrix conversations... [15:59:06.0373] > <@nicolo-ribaudo:matrix.org> ``` > const index = > (route > (authorized > (originCheck > (rateLimited(5, 1) > (function (...) { > / body > }))))) > ``` > > just use `(` for decorators instead of `@` :) This is certainly not more readable, and breaks assigned names (i.e., the function won't have the name `"index"`). Decorators would be able to preserve the assigned name on the innermost function as well as pass that to decorators via `context` in the event one decorator in the chain wraps a function and does not copy over the name. 2024-02-09 [16:01:16.0283] > <@shuyuguo:matrix.org> the disagreement i see is the motivation is thus ergonomics, which comes down to feelings, which we disagree on there are more benefits than ergonomics, but that is one of the benefits. [16:02:15.0454] > <@rbuckton:matrix.org> there are more benefits than ergonomics, but that is one of the benefits. my universe of benefits is either a new capability, or an ergonomic improvement. that may be a broader brush than what you think of as "ergonomics"? [16:02:20.0589] or am i misunderstanding [16:02:39.0176] there's performance but i thought we discarded that one [16:02:49.0910] > <@rbuckton:matrix.org> there are more benefits than ergonomics, but that is one of the benefits. * my universe of benefits for that proposal is either a new capability, or an ergonomic improvement. that may be a broader brush than what you think of as "ergonomics"? [16:03:34.0914] > <@shuyuguo:matrix.org> my universe of benefits for that proposal is either a new capability, or an ergonomic improvement. that may be a broader brush than what you think of as "ergonomics"? what is Temporal? [16:03:57.0859] Temporal is a mix of new capabilities and ergonomics improvements [16:04:13.0480] i consider Temporal to be like 80% ergonomics [16:04:29.0839] 20% performance in the "we are going to take over distribution" sense [16:05:26.0839] Does “reducing ecosystem fragmentation” fall under ergonomics? [16:05:54.0806] * Re: Temporal, does “reducing ecosystem fragmentation” fall under ergonomics? Just wondering. [16:05:58.0549] > <@jschoi:matrix.org> Does “reducing ecosystem fragmentation” fall under ergonomics? How is the ecosystem currently fragmented for function decorators? [16:06:12.0133] > <@bakkot:matrix.org> we should probably have not included class decorators, yes; at one point they had additional expressivity and so I was ok with that on those grounds This presumes class decorators have no value aside from somehow aggregating class element decorators, but that isn't the case. The registration semantics are critical for use cases like custom elements and packages like `lit`. There are also useful cases like `@Callable`, amongst others. Manual function application is terribly unergonomic for class declarations, and I think its terribly unergonomic for functions as well. Libraries like material-ui use function "decorators" in this way, and it makes the code far harder to reason over and pick apart. [16:06:12.0292] Sorry, was talking about Temporal. [16:07:19.0876] > <@rbuckton:matrix.org> This presumes class decorators have no value aside from somehow aggregating class element decorators, but that isn't the case. The registration semantics are critical for use cases like custom elements and packages like `lit`. There are also useful cases like `@Callable`, amongst others. Manual function application is terribly unergonomic for class declarations, and I think its terribly unergonomic for functions as well. Libraries like material-ui use function "decorators" in this way, and it makes the code far harder to reason over and pick apart. it does not presume they have no value. the claim is that the benefits are not worth the cost. [16:10:38.0654] I like reverse pipes, and they were suggested as an area of exploration back in the early pipeline days. That said, I don't think that is readable in the more common cases, as examples like these often function on unary functions, but that's rarely the predominant use case. What you would actually see is something like: ```js const index = route("/api/foo")(^^) <| authorized("Administrator")(^^) <| originCheck(^^) <| rateLimited(5, 1)(^^) <| function () {}; ``` You most likely need to use double invocation here if you want to reuse existing decorators (despite those decorators needing to be even more defensive around the missing 2nd argument). [16:10:57.0626] * I like reverse pipes, and they were suggested as an area of exploration back in the early pipeline days. That said, I don't think that is readable in the more common cases, as examples like these often focus on unary functions, but that's rarely the predominant use case. What you would actually see is something like: ```js const index = route("/api/foo")(^^) <| authorized("Administrator")(^^) <| originCheck(^^) <| rateLimited(5, 1)(^^) <| function () {}; ``` You most likely need to use double invocation here if you want to reuse existing decorators (despite those decorators needing to be even more defensive around the missing 2nd argument). [16:11:21.0485] And I do not find that more readable in the slightest. [16:17:07.0279] > <@nicolo-ribaudo:matrix.org> I would hope we would use indexes instead of names if we do param decorators This is what we currently do in TS. Parameter names seem like a nice to have capability that is worth exploring as its useful for diagnostics purposes. for example, if your decorator performs some kind of route binding or validation and if that fails it throws an error. It's far more convenient to diagnose `"The provided value is not supported on parameter 'foo'"` than `"The provided value is not supported on parameter 6"`. Whether we support parameter names is definitely a topic for discussion at stage 1. [16:19:30.0781] Didn’t we agree that closed over unary-returning functions are the devil in the pipelines proposal? [16:19:38.0129] > <@shuyuguo:matrix.org> my universe of benefits for that proposal is either a new capability, or an ergonomic improvement. that may be a broader brush than what you think of as "ergonomics"? It provides both ergonomics benefits (decorator reuse, language consistency), and new capabilities (post decorate registration, function name reflection for diagnostics, metadata). [16:22:10.0099] Sorry, me being cheeky isn’t needed here. [17:19:55.0253] It depends on what capabilities we give to parameter decorators. In TypeScript, such a parameter decorator can only be used for recording metadata. It can't perform method replacement or run code on a per-invocation basis. [17:21:42.0550] For constructor parameters, this is a convenient way to associate metadata for dependency injection containers, which is the predominant use case in projects like https://github.com/microsoft/vscode. For method parameters, this is a convenient way to bind HTTP route parameters for RESTful APIs. [17:24:49.0001] The parameter decorators proposal described a large number of areas of exploration beyond what TypeScript's version supported, but not all of those capabilities are critical to an MVP version of the proposal. An MVP version I would be comfortable advancing would at a minimum have the same capabilities that such decorators in TS have: parameter index, method name and placement, and the ability to record metadata. [17:25:31.0731] Thanks for the response. I’ll think about this. My initial thoughts are that syntactic constructs should meet an incredibly high bar for inclusion in a language. Basically they need to enable a new language construct that wasn’t possible without it [17:25:43.0734] There are a large number of examples on the explainer at https://github.com/tc39/proposal-class-method-parameter-decorators [17:26:02.0665] That’s my personal opinion anyway [17:27:57.0013] Parameter decorators were added to TypeScript as a way to parallel what Java annotations or C# attributes can do, which is far more limited than a normal decorator. Even with that limitation, they saw a considerable amount of use in the TS ecosystem. [17:29:33.0268] A number of the nice-to-haves were based on feedback from the TS community over the years. We don't allow method replacement, so TS parameter decorators couldn't be used for parameter validation without pairing them with a method decorator. [17:32:12.0590] That was seen as a wart in the design, which prompted the proposed adoption of returning a callback that could intercept the bound argument. That turns out to be a very powerful capability, but is perhaps a power we may not want to grant. [17:34:35.0843] having to manually number a series of pseudo-parameter decorators that are far detached from the actual code they represent is extremely unergonomic. Having the runtime provide the parameter index for you, and keeping the declarations physically adjacent to the parameter improves readability and is extremely convenient for refactors. [18:02:23.0575] > <@bakkot:matrix.org> while everyone's here, if you would like to think about async iterators, I have written up the two major open questions in my mind, namely: > > - do you enforce promises settle in order? if so, you can't do rust-style `bufferUnordered`, but if not, you can observe otherwise-impossible sequences. > - how do you get concurrency for helpers like `.find`? > > https://gist.github.com/bakkot/ad58565b203cd845524ac702c3f289f0 Reading through this, I’m a little surprised that we’re considering making async iterables support unordered buffering. But it’s an exciting capability. I feel that the *default* behavior of AsyncIterators, including AsyncIterators created from arrays of promises, should wait for each promise sequentially, like how `for await` (and Array.fromAsync) already do. The contract of async iterators implies stable sequentiality to me. I don’t know how strongly I feel about this. I think that using a Rust-like `bufferUnordered` method is a good idea. It would make developers *opt into* unordered buffering. (I also slightly prefer `bufferUnordered` to `buffered` to clearly indicate the lack of stable order.) I don’t know how I feel about `forEachConcurrent` and `findConcurrent`. Would `bufferUnordered` return an AsyncIterator that is indistinguishable from other AsyncIterators? Or would it return a new async-iterable type, like Rust’s BufferUnordered class? [18:05:36.0709] * Reading through this, I’m a little surprised that we’re considering making async iterables support unordered buffering. But it’s an exciting capability. It might be especially useful when combining WHATWG Streams. I feel that the _default_ behavior of AsyncIterators, including AsyncIterators created from arrays of promises, should wait for each promise sequentially, like how `for await` (and Array.fromAsync) already do. The contract of async iterators implies stable sequentiality to me. I don’t know how strongly I feel about this. I think that using a Rust-like `bufferUnordered` method is a good idea. It would make developers _opt into_ unordered buffering. (I also slightly prefer `bufferUnordered` to `buffered` to clearly indicate the lack of stable order.) I don’t know how I feel about `forEachConcurrent` and `findConcurrent`. Would `bufferUnordered` return an AsyncIterator that is indistinguishable from other AsyncIterators? Or would it return a new async-iterable type, like Rust’s BufferUnordered class? [18:06:25.0614] A quick note regarding reusing a punctuator in place of `void` for discards. There are very few of these that are viable due to compound assignment: ```js // these are all already legal: using *= f(); using /= f(); using %= f(); using += f(); using -= f(); using &= f(); using ^= f(); using |= f(); ``` [18:11:51.0739] Congrats to libjs for passing the most tests and being faster than V8/SM :) [18:19:57.0411] congrats to engine262 for being the slowest [18:31:35.0719] just talked to canadahonk about this, apparently some of the V8/SM experimental flags have changed so slightly inaccurate :P [18:33:33.0128] both rhino and nashorn take many hours to complete, check again in a few hours 😅 [18:55:01.0235] jschoi: re: > I feel that the _default_ behavior of AsyncIterators, including AsyncIterators created from arrays of promises, should wait for each promise sequentially So, an async iterator doesn't actually do anything itself. It doesn't really make sense to compare the behavior of async iterators to the behavior of `for await`, because the iterator doesn't have any behavior on its own (`buffer` excepted). Instead of talking about the behavior of an async iterator itself, we can talk about the behavior observed by consumers of an async iterator. A consumer like `for await` will see the same thing in all worlds discussed here (unless one is using the new buffering helpers), because `for await` waits for each promise to settle before pulling the next one, and so could not possibly observe promises settling out of order. The "can things settle out of order" question does not affect such consumers at all. If we allow settling out of order, that would only be observable to consumers which do multiple calls of `.next()`. There's nothing in the language that does that right now, but you could do it yourself, in principle. Or, as proposed, you could do it with `buffer` or `bufferUnordered` (which would do multiple calls to `.next()` under the hood). With `buffer`, if you pull from it the way `for await` does, you would never see things happening out of order. So the only places this "settling out of order" behavior would be observable would be when manually calling `.next()` multiple times, or when using `bufferUnordered`. > Would `bufferUnordered` return an AsyncIterator that is indistinguishable from other AsyncIterators? Or would it return a new async-iterable type, like Rust’s BufferUnordered class? First thing. The return value of all helpers would just be instances of AsyncIteratorHelper. [19:04:24.0941] On the topic of parameter decorators, I wonder if other people have looked through the examples in the readme of the proposal, and if so what their reactions are: https://github.com/tc39/proposal-class-method-parameter-decorators#ecmascript [19:05:34.0041] it looks incredibly foreign to me [19:09:03.0032] I have little experience with decorators in any language, but I'm at least used to the idea that they sit atop a method or function or whatever [19:22:28.0117] Does eshost do as good a job as the engines’ own test262 runners at filling in all of the hooks and such? [19:36:31.0252] pretty much, yep! [19:37:09.0413] > <@bakkot:matrix.org> jschoi: re: > > > I feel that the _default_ behavior of AsyncIterators, including AsyncIterators created from arrays of promises, should wait for each promise sequentially > > So, an async iterator doesn't actually do anything itself. It doesn't really make sense to compare the behavior of async iterators to the behavior of `for await`, because the iterator doesn't have any behavior on its own (`buffer` excepted). > > Instead of talking about the behavior of an async iterator itself, we can talk about the behavior observed by consumers of an async iterator. A consumer like `for await` will see the same thing in all worlds discussed here (unless one is using the new buffering helpers), because `for await` waits for each promise to settle before pulling the next one, and so could not possibly observe promises settling out of order. The "can things settle out of order" question does not affect such consumers at all. > > If we allow settling out of order, that would only be observable to consumers which do multiple calls of `.next()`. There's nothing in the language that does that right now, but you could do it yourself, in principle. Or, as proposed, you could do it with `buffer` or `bufferUnordered` (which would do multiple calls to `.next()` under the hood). With `buffer`, if you pull from it the way `for await` does, you would never see things happening out of order. So the only places this "settling out of order" behavior would be observable would be when manually calling `.next()` multiple times, or when using `bufferUnordered`. > > > Would `bufferUnordered` return an AsyncIterator that is indistinguishable from other AsyncIterators? Or would it return a new async-iterable type, like Rust’s BufferUnordered class? > > First thing. The return value of all helpers would just be instances of AsyncIteratorHelper. The framing here makes sense. Promises’ settling out of order is unobservable by default to “higher-level” consumers like `for await` or AsyncIterator methods (higher-level = “do not directly call `.next()`). I think it’d be good to put something like the explanation here into your Gist or your future explainer. [19:37:32.0398] * The framing here, from the perspective of the AsyncIterator consumer, makes sense. Promises’ settling out of order is unobservable by default to “higher-level” consumers like `for await` or AsyncIterator methods (higher-level = “do not directly call `.next()`). I think it’d be good to put something like the explanation here into your Gist or your future explainer. [19:37:41.0763] the main advantage of writing a custom runner is that spawning 100k processes is slow (~50k tests each running in sloppy and strict mode) [11:19:18.0494] it takes like 4 minutes to run engine262 on test262 with its runner, but eshost apparently takes 2 hours lol 2024-02-12 [19:58:32.0230] @bakkot: It looks like the matrix log bot died? [19:58:40.0546] * bakkot: : It looks like the matrix log bot died? [19:58:43.0968] * bakkot: It looks like the matrix log bot died? [19:59:15.0513] Newest updates are from 2024-02-06, missing the plenary [19:59:28.0000] ugh, let me kick it [19:59:48.0399] it hangs sometimes and I haven't tracked down why [20:00:41.0232] and the monitoring I have only detects outright crashes [20:02:29.0078] Justin Ridgewell: ok, back up to date [07:36:47.0750] > <@bakkot:matrix.org> On the topic of parameter decorators, I wonder if other people have looked through the examples in the readme of the proposal, and if so what their reactions are: https://github.com/tc39/proposal-class-method-parameter-decorators#ecmascript My reaction is that I want it. We have a use case similar to the FFI marshalling & parameters validators. Sure you could put all that on a method / function decorator, but that'd require "redeclaring" the parameter list in the method / function decorator itself, risking getting out of sync with the actual parameters. [11:33:06.0467] the thing is, you kinda could do this with extractors, but I agree it would be better to apply parameter decorators, semantically [11:34:12.0958] how, with extractors? [11:45:18.0511] For validators, serializers, casts, etc, you can do `function f(x(a), y(b)) { }` instead of `function f(@x a, @y b) { }` just by having x and y have custom matchers. But IMO if it's not logically undoing what x and y do, it's not quite semantically appropriate. [11:45:40.0805] note that this doesn't work for metadata [11:52:34.0651] Some FFI marshaling scenarios require up-front knowledge of the function parameters incl. data types, string decoding behaviors, etc., that makes extractors a poor fit. 2024-02-13 [18:19:24.0277] Yeah we need the metadata. Another param decorator we would have is an `@Awaited`, which would have to be coupled with a `@Async` (name to be bikeshed) method decorator since the param decorator cannot replace the method itself (like how method decorators cannot replace the class itself) [04:54:03.0135] > <@rbuckton:matrix.org> Some FFI marshaling scenarios require up-front knowledge of the function parameters incl. data types, string decoding behaviors, etc., that makes extractors a poor fit. Could you elaborate on this? [05:13:11.0163] See the example at https://github.com/tc39/proposal-class-method-parameter-decorators?tab=readme-ov-file#foreign-function-interfaces. If you are passing a JS function as a callback to a native API that will use it as a function pointer, it may need to know the expected data types (e.g., integer widths) ahead of time when marshalling from native to JS. 2024-02-14 [18:21:24.0458] I just ran across a strange case while writing additional tests for RegExp Modifiers. I've found exactly two cases where `/\b/u` and `/\b/ui` disagree for the same character: - U+017f - ſ LATIN SMALL LETTER LONG S - U+212a - K KELVIN SIGN A quick test of the same patterns and inputs in C# shows no disagreement, so its not clear to me if this is expected or possibly a bug in `\b`. [18:31:22.0602] possibly having to do with how Unicode case folding for those characters produces an ASCII character. It just seems strange to have something that is not considered a word character when preserving case, but is considered a word character when ignoring case. [18:39:22.0495] the original sin here is that `\b` and `\w` are not unicode-aware even in `u` mode [18:40:17.0275] this behavior follows immediately from that: `U+017f` is not an ascii word character, but it case-folds to `s`, which is, and `i` means that the regex operates on case-folded characters [18:40:42.0023] the decision to make `\b` and `\w` not unicode-aware predates me, unfortunately, so I cannot tell you why this is. it does seem... bad. [18:40:55.0278] (`\d` too but that one matters a lot less.) [19:19:09.0538] Time to introduce a `w` flag for very very unicode? [19:20:16.0554] * Time to introduce a `w` flag for very very unicode mode? [19:27:44.0670] we actually did specifically discuss and reject the possibility of making `\b` etc unicode-aware in `v`-mode https://github.com/tc39/notes/blob/2fccc7f7a38201354a007394ab867ec7b245b464/meetings/2021-08/aug-31.md#regexp-set-notation--properties-of-strings [20:59:01.0840] > JRL: Also voicing support, I would not change these shorthands. I do not remember this [21:31:49.0083] I think waldemar's concern at the time was that changing `\b`, `\w`, and `\d` shouldn't be tied to the mode that adds set notation. We'd need to opt in either with a new mode or a `{u}` suffix. Either are fine so long as the new mode could be included in the modifiers list, i.e., `\b{u}` or `(?w:\b)` (or whatever flag we'd use) would work for those cases. [21:38:22.0870] Oh, I guess I mentioned modifiers during that discussion as well. [07:40:46.0747] > <@bakkot:matrix.org> the decision to make `\b` and `\w` not unicode-aware predates me, unfortunately, so I cannot tell you why this is. it does seem... bad. https://github.com/tc39/proposal-regexp-unicode-property-escapes/issues/22#issuecomment-279930140 > There was a pre-ES6 [proposal to change the meaning of `\w`, `\d`, and `\b` in Unicode mode](https://github.com/mathiasbynens/es-regexp-unicode-character-class-escapes/blob/master/d-w-b.md). It was ultimately rejected out of fear it would hurt adoption of the `u` flag. (https://github.com/tc39/proposal-regexp-unicode-property-escapes/issues/22 is the [failed] attempt to make those escapes Unicode-aware under the `v` flag) [07:57:14.0180] who can add new members to the tc39 organization on GH? [07:57:50.0991] i'd like to add a V8 bot account for the purposes of test262 2-way sync. i can add the account to the right teams but first it has to be part of the tc39 organization, apparently [08:07:01.0231] done. 2024-02-15 [16:45:40.0535] Apropos of this, Agoric uses a variant of XS that can start from a heap snapshot and it would be neat for us to be able to take advantage of that with a test262 runner. [16:50:22.0576] this bug is genuinely cursed: https://github.com/bjrjk/CVE-2022-4262/blob/main/FA/FA.md it relies on - the thing where you need to re-parse arrows when you encoutner the `=>` - computed property name syntax - class bodies are strict mode - you can put arbitrary expressions in arrow parameters - direct eval depends on strictness of surrounding context good example of a real-life security issue arising as a direct consequence of making the language so complicated. [01:51:01.0128] wow that is a doozy [05:32:02.0830] ES6 broke a lot of assumptions that engines could previously make in their parser/bytecode generator, eg around scoping and what can occur in an expression position. Fortunately we haven’t touched that area very much since ES6. Maybe the most significant thing we have done is private fields/methods (which involve scoping), the biggest Stage 3 one is decorators (which add evaluation into new places), and the biggest future thing is do expressions (which I expect to be nontrivial to implement for this reason in some engines, even if they omit break/continue/return, but those certainly make this surface much bigger) [05:32:56.0589] There were lots of other bugs in the process that just got caught sooner somehow or other [07:39:22.0122] class fields and class static blocks probably fall into the category of new expression positions that could cause these kinds of implementation errors, too [07:47:32.0431] agreed. something notable is that we did a lot of these changes in ES6, and then subsequent ones are fewer and farther between, somehow. [09:07:18.0969] > Fortunately we haven’t touched that area very much since ES6. do expression is coming~ [14:18:32.0643] private fields have the super weird heritage position scope [14:18:39.0259] that's separate than the lexical scope [14:18:48.0878] i wouldn't be surprised there's a CVE in there somewhere [14:18:55.0417] * i wouldn't be surprised if there's a CVE in there somewhere 2024-02-16 [17:33:52.0813] I feel like we are being given clues towards collecting a bounty. 2024-02-20 [14:48:38.0280] Do we define what "present" means when it comes to AO params? Eg, I want to call https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-createbuiltinfunction and pass `prefix`, but don't want to pass `realm` or `prototype`. [14:48:56.0159] Can I pass `empty`, and have these not be "present" [14:50:08.0079] I don't think we have spec syntax for that, but it seems like it'll just be two lines of copy pasta to hack through it... [14:50:26.0201] it's defined, and no [14:50:57.0633] in `Foo(_a_)` vs `Foo(_a_, _b_)`, b is not present in the first call. you have to branch and do two different invocations to the AO if you want to trigger "not present". [14:54:33.0896] Where? [14:54:39.0691] * Where is it defined? [14:56:54.0263] It's not in https://tc39.es/ecma262/multipage/notational-conventions.html#sec-notational-conventions, where I expected it [15:08:51.0113] AO parameter lists are described in the second paragraph of https://tc39.es/ecma262/multipage/notational-conventions.html#sec-algorithm-conventions [15:10:44.0658] we don't expand on the phrasing "is present" or "is not present", though we could if people find that confusing [15:10:52.0377] personally, I think it's pretty self-explanatory [15:11:07.0338] also, you can ask these kinds of questions in #tc39-editors:matrix.org [15:11:56.0564] if we add a `` for it, then all the usages throughout the spec will link [15:13:04.0319] note that this phrasing is used both for positional AO parameter lists and optional terms in SDO grammar productions [15:13:34.0090] > <@michaelficarra:matrix.org> also, you can ask these kinds of questions in #tc39-editors:matrix.org "You do not have permission to post to this room" [15:13:43.0465] oh nooo [15:13:48.0540] :sad trombone: [15:14:11.0055] 🤔 I thought everyone who could post here could also post there [15:17:09.0697] > as in you'd prefer to do the manual List creation at the callsites > https://matrix.to/#/!nSLHQtIRJQxUJbEuGt:matrix.org/$l72R7TLaZX7Azd1F2whqM8jwErqy6Grx0tHr4PUaPDw?via=matrix.org&via=igalia.com How do I reference an abstract closures dynamic arguments list? [15:17:51.0140] > do we have any use cases in 262 rn that could take advantage of that? if not, i'd assume the only reason not to so far was "it hasn't come up" > https://matrix.to/#/!nSLHQtIRJQxUJbEuGt:matrix.org/$v9_1LOpt83mI-ksAomfZUvYeaA9lxJg1TyUheVCuWm0?via=matrix.org&via=igalia.com Both `AsyncContext` and `String.dedent` proposals want this [15:23:22.0202] yeah it sounds like the whole editor group is on board with using ellipsis in AC parameter lists, and if you want to use them in CBF, you just need to update the prose in CBF to support it [15:24:52.0902] What's CBF? [15:25:05.0590] CreateBuiltinFunction [15:25:20.0080] sorry I have no idea how much context you have from the editor channel lol [15:27:14.0443] How does modifying CBF's prose help with the AC parameter list? [15:28:08.0895] Isn't this an issue with ecmarkup's linting? [15:41:49.0715] at the moment, AC parameter lists are, as specified, technically compatible with the ellipsis notation, but we've never used it so we didn't notice that ecmarkup doesn't support it [15:43:16.0775] but if you wanted to pass such an AC to CBF (which I'm assuming is what you meant by "Both `AsyncContext` and `String.dedent` proposals want this"), then you will need to modify the CBF prose to support ACs with that kind of parameter list 2024-02-22 [09:14:35.0943] reminder to review/update notes from plenary. technically publish date is tomorrow, but we are extending to next week as we failed to send a reminder 2024-02-26 [14:12:51.0607] can we make it a code of conduct violation to post AI-generated bullshit without properly labelling it as such? [14:19:23.0800] that's already a CoC violation. context? [14:24:57.0315] which part? [14:25:32.0442] can you link to the AI-generated bullshit? [14:26:21.0345] > <@michaelficarra:matrix.org> which part? I would argue at the very least: 1. be respectful, 2. be considerate, 3. be careful in words [14:27:03.0393] "AI-generated bullshit" does not sound respectful, considerate, nor being careful with words [14:27:59.0620] sorry, AI-generated... meaningless babbling? [14:31:04.0057] oh [14:31:05.0876] in that case... [14:31:10.0695] "AI-generated meaningless babbling" does not sound respectful, considerate, nor being careful with words [14:31:13.0057] the description for https://github.com/tc39/ecma262/pull/3287 was very clearly written by chatGPT; plausibly also the text included in the PR itself since it sounds coherent but is meaningless [14:31:38.0515] MF: apologies for any confusion there -- I am not saying what _you_ said is not respectful [14:43:42.0746] i don't think it's a CoC violation simply to have used an LLM, but it's a dick move, and imo due to copyright uncertainties means we're flatly unable to accept the contribution anyways [14:44:17.0120] perhaps we should update the contribution guidelines to be clear about that tho [14:44:19.0059] Yes, this is definitely something we should discourage and unceremoniously shut down, I agree. [14:44:22.0023] * perhaps we should update the contribution guidelines to be clear about not using LLMs tho [14:54:03.0569] to be clear, I don't mind it being used or being quoted in part, but I mind *considerably* when it is being passed off as a human [14:54:58.0073] because I have a default level of deference for something someone took the time to write themselves, and it is exhausting to be at the level for something that someone possibly didn't even care enough to review themselves [14:55:16.0439] * because I have a default level of deference for something someone took the time to write themselves, and it is exhausting to be at that level for something that someone possibly didn't even care enough to review themselves [14:55:24.0544] seems like it's a legit PR that the author only used an LLM for because english isn't their native language [15:00:46.0229] I think we should be explicit that using an LLM for any portion of an issue or PR, including just translation, is disallowed. I would much prefer to get a contribution in a language I don't understand and translate it myself than to get a contribution which an LLM translated. (Also here they clearly did more than just ask one to translate; chatgpt's translations don't have this distinctive manner of speech) [15:01:06.0469] * I think we should be explicit that using an LLM for any portion of an issue or PR, including just translation, is disallowed. I would much prefer to get a contribution in a language I don't understand and translate it myself than to get a contribution which an LLM already translated. (Also here they clearly did more than just ask one to translate; chatgpt's translations don't have this distinctive manner of speech) [15:02:00.0815] Well, disallowed if not disclosed, anyway. Don't care nearly as much if disclosed. [15:15:59.0136] Yeah I just care about disclosure. [15:48:29.0410] that's fair 2024-02-27 [21:13:34.0783] (It gets murky with translation IMO; some people use Google Translate as part of their workflow but don’t have it write the whole thing. I would prefer not making an explicit statement about translation but leave it sort of up to interpretation. But I am very in favor of saying, don’t use LLMs to generate your communication with us. [22:01:25.0768] That works for me 2024-02-28 [12:32:17.0582] https://github.com/tc39/Reflector/issues/520 [12:32:31.0024] ☝️ gentle reminder to review/update notes from plenary before the end of the week 2024-02-29 [07:52:50.0965] question that came up internally recently: does anyone have any idea why in https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.hypot, the infinite special case takes precedence NaN special case? [08:56:29.0090] shu: seems like it may have been a precision concern? - https://github.com/tc39/notes/blob/970d84b7d0f9c455757870a3892ea78e7bee2cfd/meetings/2013-11/nov-20.md?plain=1#L441 - https://github.com/tc39/notes/blob/970d84b7d0f9c455757870a3892ea78e7bee2cfd/meetings/2013-09/sept-17.md?plain=1#L340C13-L340C18 [08:56:44.0825] * shu: seems like it may have been a precision concern? (the november 2013 notes in particular) - https://github.com/tc39/notes/blob/970d84b7d0f9c455757870a3892ea78e7bee2cfd/meetings/2013-11/nov-20.md?plain=1#L441 - https://github.com/tc39/notes/blob/970d84b7d0f9c455757870a3892ea78e7bee2cfd/meetings/2013-09/sept-17.md?plain=1#L340C13-L340C18 [10:03:25.0155] hm i don't follow the precision argument for infinity vs nan precedence [10:03:28.0691] thanks for digging those up [10:03:32.0769] i see a nan mention in the sept-17 one [10:13:15.0452] yeah it's not clear to me from the notes either [10:13:17.0705] but that's all i could find [11:02:16.0335] In several of the math functions (but, annoyingly, not *quite* all), they'll treat NaN as if it could be every value, and if this still results in a well-defined answer, return that answer instead of returning NaN. That's the case for hypot() - if there's an infinite term, then it doesn't matter what the rest of the terms are, it's gonna return infinity. [11:02:51.0335] (I did some exploration of this while writing the CSS math functions. I chose not to perfectly match JS in this regard, and instead make NaN immediately infectious, because JS wasn't self-consistent anyway.) [11:03:54.0554] (In particular, min/max don't follow these rules. `Math.max(Infinity, NaN)` returns NaN, despite the fact that every possible numeric value the second argument could take would still result in Infinity being returned.) [14:11:31.0880] > <@tabatkins:matrix.org> In several of the math functions (but, annoyingly, not *quite* all), they'll treat NaN as if it could be every value, and if this still results in a well-defined answer, return that answer instead of returning NaN. That's the case for hypot() - if there's an infinite term, then it doesn't matter what the rest of the terms are, it's gonna return infinity. the question is why Infinity has precedence over NaN [14:11:48.0547] if you wrote that code in userland JS, NaN would have precedence over Infinity [14:11:55.0919] wrote it in the naive way, i guess [14:12:22.0618] Yeah, I said why - in several functions, they allow a non-NaN answer if NaN could be replaced with anything without changing the result. [14:13:03.0076] Which is relatively reasonable behavior, I think. (But the other behavior - fully infectious NaN - is also reasonable.) [14:13:05.0852] trying to parse that sentence... [14:14:01.0842] okay sorry i just don't understand the precedence [14:15:52.0580] okay, so the precedent is that several functions already decided that NaN should have lower precedence than Infinity because Infinity is thought of as just another "non-NaN"? [14:16:18.0670] that doesn't give me insight on why they made this decision when the precedence in user `+` is the opposite [14:18:16.0529] No, the (mixed!) precedent is that, in several functions, if the NaN argument *doesn't affect the result* (aka you could replace it with *any non-NaN* value, and every possible substitution would have no effect on the return value), then the function just returns that consistent value. [14:18:49.0850] It's not a "lower precedence" thing, it's a "the return value doesn't depend on this argument, so we won't pay any attention to it" thing. [14:19:36.0114] Infinity *is* just another number; NaN is the weird one that (among other reasons) is returned when multiple possible values are possible. [14:23:16.0274] `+` is consistent with this behavior: in `Infinity + X`, if X=-Infinity you get NaN, while any other value yields Infinity, so the X's value *is* important to the result, so `Infinity + NaN` has to be NaN too. [14:30:45.0406] Infinity + NaN is NaN, right [14:30:53.0038] but hypot(Infinity, NaN) is Infinity? [14:31:04.0153] that's the inconsistency, no? [14:34:50.0070] No, substitute *any* non-NaN value for the second argument there. You'll always get Infinity, still. [14:35:06.0641] So the NaN argument is powerless, and can be safely ignored. [14:36:21.0788] (`hypot(Infinity, Infinity)`, `hypot(Infinity, 0)`, `hypot(Infinity, -Infinity)` all give `Infinity`; once one argument is infinite the entire function is guaranteed to return `Infinity` regardless of the other values.) [14:36:41.0457] i think we're talking past each other somehow [14:37:19.0132] We must be, since you still seem to be talking about this in terms of "precedence", like the existence of an Infinity vs a NaN does something and we have to define which one "wins" when they both appear. [14:37:34.0925] What I'm explaining is that the behavior isn't about that at all. [14:38:00.0776] looking at just +, `Infinity + NaN`, one cannot know whether the rule that applies is "Infinity is infectious" or "NaN is infectious", and people just internalize it as "NaN is infectious" applies over "Infinity is infectious" [14:38:18.0706] in that Infinity + NaN is a degenerate form that has no intuition in extended real arithmetic [14:38:51.0358] Sure. But "`Infinity + NaN` yields `NaN`" is *also* consistent with the reasoning I gave, which appears to be the reasoning used by `hypot()`. [14:39:08.0998] (But not the reasoning used by `min()`/`max()`; they both use "`NaN` is infectious" logic.) [14:39:11.0706] look at `hypot(Infinity, NaN)`, one also cannot know whether the rule that applies is "Infinity is infectious" or "NaN is infectious", and people just internalize one, except it's confusing now because they need to internalize the other one [14:39:34.0255] yeah, the logic isn't about infection in hypot() [14:39:38.0060] is what i keep saying [14:39:50.0001] okay, think i finally see where you're coming from [14:40:12.0386] but doesn't that kick the can one level up? there's still inconsistent in which logic is used for which operations/functions, and it's confusing [14:40:24.0911] Yes, it's inconsistent no matter *what* reasoning you use [14:40:33.0879] our functions are just straight up inconsistent in their NaN handling [14:41:09.0549] okay, bear with me, but now we're back at my still not having any insight on how we arrived at this inconsistency in logic [14:41:14.0234] i guess just accident of how things were argued at the time [14:48:00.0837] yup