00:23 | <Rob Palmer> | Good morning from Tokyo. Plenary begins in 37 minutes. |
00:59 | <Rob Palmer> | We are starting in one minute! |
01:13 | <msaboff> | The notes don't have a header for attendee names, org and abbreviation. |
01:13 | <bakkot> | is tcq down for anyone else? |
01:13 | <littledan> | yes :( I guess we'll have to go to the google sheets backup? |
01:13 | <ryzokuken> | just now, I think |
01:13 | <rkirsling> | yes |
01:13 | <msaboff> | Yeah, looks down to me. |
01:15 | <ryzokuken> | back on? |
01:15 | <msaboff> | LGTM now |
01:17 | <jkup> | Are the task group reports still on for this first section today? |
01:17 | <Michael Ficarra> | ... we have delegates.txt for that msaboff |
01:17 | <littledan> | jkup: Yes |
01:18 | <sffc> | Would really appreciate having Locale Extensions get onto the agenda in order to surface stakeholders and get a temperature check on the current direction. ( Rob Palmer ryzokuken Chris de Almeida ) |
01:18 | <littledan> | ... we have delegates.txt for that msaboff |
01:18 | <Michael Ficarra> | yes let's not continue this practice for no reason |
01:18 | <rkirsling> | ah, perhaps it just needed to be made clear that we no longer need it |
01:18 | <rkirsling> | I was wondering too |
01:18 | <littledan> | ah, perhaps it just needed to be made clear that we no longer need it |
01:19 | <littledan> | (I don't know either way) |
01:19 | <rkirsling> | oh sorry, I was inferring that it was |
01:19 | <rkirsling> | I have no idea |
01:19 | <ryzokuken> | msaboff should be good to go now |
01:20 | <Michael Ficarra> | motion to delete it again |
01:20 | <Rob Palmer> | So to confirm, TCQ appears to be working. |
01:21 | <msaboff> | msaboff should be good to go now |
01:21 | <Rob Palmer> | Would really appreciate having Locale Extensions get onto the agenda in order to surface stakeholders and get a temperature check on the current direction. ( Rob Palmer ryzokuken Chris de Almeida ) |
01:22 | <sffc> | Is this on the agenda? If not, please PR it. |
01:23 | <ryzokuken> | we'll try to free up as much time as we can as we go and try to bring items from the overflow to discussion |
01:23 | <bakkot> | "pdf has highest downloads" is meaningless; the editor's draft on github does not have statistics |
01:24 | <shu> | i am laughing on the inside |
01:29 | <snek> | i'm pretty sure github pages has some analytics |
01:31 | <snek> | oh nvm i'm thinking of repo analytics |
01:32 | <ljharb> | re notes, it's nice to have the abbreviation list in the same document, i think |
01:33 | <bakkot> | at some point all the time spent talking about the PDF is going to successfully annoy me enough to do the automation just so we can stop talking about it |
01:33 | <bakkot> | which was the goal I guess |
01:33 | <Michael Ficarra> | ljharb: we have tabs; when I am taking notes, I just keep delegates.txt open in a tab |
01:33 | <ljharb> | true, maybe just a link to the list for easy tab-opening would be better then |
01:33 | <bakkot> | the PDF is a fair bit of work and it is hard to motivate because I don't use the PDF at all |
01:33 | <bakkot> | which is why we keep trying to get ECMA to hire people instead |
01:34 | <shu> | i think, in general, practitioners and implementers that engage with the PDFs are rarely doing so on purpose for checking the behavior of a particular yearly version, and because they missed that there is a draft they should be using |
01:34 | <ljharb> | i never use the pdf; even when checking a past yearly version i use the HTML versions |
01:34 | <shu> | so it's primarily for archival purposes, which is mainly consumed by ecma |
01:35 | <ljharb> | afaik the concerns aren't about archival tho, they're about readability when printed. webpages can be easily archived as PDFs without any additional changes. do many people even own a printer anymore? |
01:35 | <shu> | fair, i meant archival-as-printed-physical-artifact |
01:35 | <littledan> | I agree that practitioners should typically use the editor's draft, but I want to note that the market for "archival purposes" is broader than Ecma and that's a good thing. This is shared with ISO, put in libraries, etc. |
01:36 | <littledan> | there's been a lot of stuff lost in the past and it's good to have printed artifacts to avoid that |
01:36 | <littledan> | anyway I think everyone agrees the editors are already doing a lot and no need for this to be all on them |
01:36 | <snek> | the new font is quite good |
01:37 | <shu> | except the # |
01:37 | <shu> | so weird |
01:37 | <shu> | oh god |
01:37 | <snek> | lol |
01:37 | <shu> | i can't just type the sentence "# so weird", there's Markdown support in Element? |
01:37 | <ljharb> | # so weird |
01:37 | <snek> | did we check if there is a font variant for # in the font we're using? |
01:38 | <ryzokuken> | is it just the bold # ? |
01:38 | <shu> | that's what we thought at first, i think we found out it was the monospace # |
01:39 | <Michael Ficarra> | https://github.com/tc39/ecmarkup/issues/556 |
01:39 | <Michael Ficarra> | yes, it is all monospace variants |
01:39 | <bakkot> | https://github.com/IBM/plex/issues/401#issuecomment-1727079001 |
01:39 | <Michael Ficarra> |
|
01:39 | <snek> | nice |
01:40 | <shu> | watch the stylistic alternate remove the horizontal overlapping segments too |
01:40 | <rkirsling> | https://tc39.es/ecma262/ is somehow slow to the point of unusable for me |
01:40 | <snek> | slow how? |
01:40 | <rkirsling> | like, I'm scrolling and it's just blank |
01:40 | <Michael Ficarra> | rkirsling: yes it is a very big document |
01:40 | <bakkot> | try Firefox |
01:40 | <Michael Ficarra> | ^ |
01:40 | <bakkot> | chrome always struggles on long pages |
01:41 | <snek> | its super responsive for me in firefox, and i'm not even using gpu acceleration |
01:41 | <Michael Ficarra> | also try the multipage document |
01:41 | <rkirsling> | this is Safari |
01:41 | <rkirsling> | but yeah multipage would help |
01:41 | <Michael Ficarra> | https://tc39.es/ecma262/multipage/ |
01:41 | <bakkot> | m to switch! |
01:41 | <snek> | wow the single page is very good in chrome too |
01:41 | <snek> | like maybe as good as firefox |
01:42 | <Michael Ficarra> | firefox is definitely more responsive and loads in maybe 1/10th the time |
01:42 | <snek> | safari takes like 15 seconds to even show the top of the page |
01:43 | <Michael Ficarra> | oof |
01:43 | <bakkot> | ecma404 is my favorite specification |
01:43 | <shu> | one day chip will surprise us |
01:43 | <bakkot> | someday I hope 262 achieves that level of stability |
01:43 | <shu> | JS is much more like a shark than JSON |
01:44 | <shu> | i do not hope for that |
01:44 | <snek> | someday I hope 262 achieves that level of stability |
01:44 | <Michael Ficarra> | wasm! |
01:44 | <bakkot> | JS is much more like a shark than JSON |
01:45 | <rkirsling> | something about jumping, probably |
01:45 | <shu> | no, that if it stops swimming it dies |
01:45 | <shu> | it's an annie hall reference, i don't actually know if it's true of actual sharks |
01:45 | <msaboff> | Safari took ~5 seconds for me and this is a 2019 Intel MBP. |
01:45 | <snek> | it is true of most shark species |
01:46 | <snek> | there are a few that can pump water through their gills instead of having to swim |
01:46 | <snek> | Safari took ~5 seconds for me and this is a 2019 Intel MBP. |
01:47 | <snek> | i'd be curious to see how other committees handle security issues |
01:48 | <Jack Works> | I am curious what vulnerability can happen in ECMAScript since it does not have too much IO |
01:50 | <snek> | i think the embedded devices folks have added a bunch |
01:50 | <snek> | actually i guess they're a separate TC now |
01:50 | <Jack Works> | that's an engine specific thing right? just like v8 bug is v8 only |
01:54 | <Richard Gibson> | true, maybe just a link to the list for easy tab-opening would be better then |
01:54 | <rkirsling> | that's an engine specific thing right? just like v8 bug is v8 only |
01:54 | <rkirsling> | but my knowledge of security is very weak |
01:58 | <littledan> | syg: msaboff To be clear, I'm not saying everything needs to be discussed in TC39 plenary, just that Spectre represented an interesting case to review, as it was a vulnerability at the design level rather than in a particular implementation. |
01:59 | <snek> | it could have been constructive to discuss SAB at a higher level though idk how different the outcome would have been in practice... will be interesting to see what happens in the future i guess, whatever the next intel vulnerability is. |
01:59 | <shu> | these are all interesting properties but are not vulnerabilities in my book |
02:00 | <rkirsling> | vulnerability "potentials"? |
02:00 | <snek> | in that its about the hardware you're running js on, not js itself? |
02:00 | <shu> | i don't have any reservations with saying TG3 ought to discuss security properties, and ones that get raised |
02:01 | <msaboff> | syg: msaboff To be clear, I'm not saying everything needs to be discussed in TC39 plenary, just that Spectre represented an interesting case to review, as it was a vulnerability at the design level rather than in a particular implementation. |
02:02 | <littledan> | sure, but we worsened them through exposure from TC39. Anyway, yeah, there probably wasn't any meaningful discussion to have here at that point, and I don't think you needed to disclose more |
02:02 | <snek> | i think its a bit ambiguous. ultimately the design of js is guided by how the hardware we run it on works |
02:02 | <bakkot> | I am fine with this but would want the disclosure text to make it really clear that we do not expect "vulnerabilities in the language" to really be a thing |
02:02 | <bakkot> | and saying you probably want something else |
02:06 | <msaboff> | It just seems a little weird to me that an open standards body would discuss vulnerabilities. The CVE and other similar processes provide a means for those with issues to address them before bad actors are generally aware of the vulnerability. |
02:06 | <littledan> | sorry, I probably shouldn't've said anything. I don't feel like you needed to disclose Spectre in any kind of different way. |
02:06 | <shu> | It just seems a little weird to me that an open standards body would discuss vulnerabilities. The CVE and other similar processes provide a means for those with issues to address them before bad actors are generally aware of the vulnerability. |
02:06 | <shu> | but i am not very hooked into the CVE process either |
02:07 | <snek> | i am interested to see how it goes at least |
02:07 | <shu> | vulnerabilities at some conceptual level can exist because there's a mismatch between a thing (an implementation) and a source of truth (a spec), and people depend on properties of the source of truth, making it an vulnerability |
02:08 | <shu> | but i don't know what that means if it is "a vulnerability in the spec" because it is the source of truth |
02:08 | <shu> | i am very uncomfortable if the mismatch is in fact with unsaid properties that could be depended upon but we have not otherwise explicitly committed to keeping |
02:09 | <Michael Ficarra> | shu: surely you can imagine that there are assumed invariants about the language that may not actually hold because of the way we have specified it (which then may or may not be reflected in an implementation) |
02:09 | <shu> | Michael Ficarra: right. i can also imagine that we don't actually unanimously agree on those assumed invariants |
02:10 | <Michael Ficarra> | of course, and that is work to be done later |
02:10 | <littledan> | i am very uncomfortable if the mismatch is in fact with unsaid properties that could be depended upon but we have not otherwise explicitly committed to keeping |
02:10 | <bakkot> | I don't think of SAB having a vulnerability? |
02:10 | <bakkot> | "the language lets you get a high-res timer" is not a vulnerability |
02:10 | <eemeli> | Not really an issue with the JS spec, but something like the Billion Laughs Attack in XML and YAML could be considered as a spec "vulnerability". |
02:10 | <bakkot> | "the hardware leaks memory if you have a high-res timer" is a vulnerability |
02:11 | <littledan> | well, it was part of the exploit, sorry I guess I'm using security words wrong |
02:13 | <Michael Ficarra> | the editors had already raised concerns about it being a note |
02:14 | <bakkot> | *262 editors |
02:14 | <Michael Ficarra> | sorry, 262 editors |
02:15 | <littledan> | yes this is what I was saying |
02:15 | <littledan> | (to Mark) |
02:15 | <bakkot> | ... isn't it normative already? |
02:15 | <bakkot> | it says it's normative on the agenda |
02:15 | <bakkot> | and in the PR title |
02:19 | <ryzokuken> | https://github.com/tc39/ecma402/pull/831 |
02:19 | <ryzokuken> | ... isn't it normative already? |
02:20 | <ryzokuken> | I guess the consensus is to do things without the non-normative label |
02:21 | <Michael Ficarra> | everything inside notes is non-normative; everything outside notes is normative |
02:23 | <bakkot> | some things outside notes are also non-normative |
02:33 | <Michael Ficarra> | I feel like I'm crazy, this is already what the PR does |
02:34 | <bakkot> | 'axc'.replace(/x/, '$01') === 'a$01c' |
02:34 | <ryzokuken> | everything inside notes is non-normative; everything outside notes is normative |
02:35 | <ljharb> | it's certainly possible that it's an issue in my impl, but it's practically 1:1 with the spec text ¯\_(ツ)_/¯ |
02:36 | <ljharb> | 'axc'.replace(/(x)/, '$01') tho |
02:36 | <Michael Ficarra> | I keep re-reading it and I don't see how you could have any other behaviour |
02:36 | <bakkot> | ljharb: link your impl? |
02:36 | <ljharb> | still local since i just wrote it 8 minutes ago |
02:36 | <ljharb> | i'll share a link if a bit of debugging doesn't reveal the problem on either side |
02:36 | <Michael Ficarra> | I'm gonna take Occam's razor here |
02:37 | <msaboff> | Does anyone know how long implementations had this replace behavior? |
02:37 | <snek> | ? https://gc.gy/163400847.png |
02:38 | <ljharb> | right, exactly - that shows that $1 and $01 both hit the first capture group |
02:38 | <bakkot> | 'axc'.replace(/(x)/, '•$01•') === 'a•x•c' maybe makes that easier to see |
02:39 | <ljharb> | the difference is if you have, say, 12 captures in the regex, and you use if you have < 11 captures in the regex, |
02:40 | <littledan> | in that case we could move the text out of the notes |
02:42 | <bakkot> | if we have time which we cannot otherwise use, I am happy to take any >10m slot to get through as much of "stop coercing things" as possible |
02:42 | <bakkot> | though IIRC someone wanted to be there for that, which makes it harder to do impromptu |
02:43 | <ryzokuken> | if we have time which we cannot otherwise use, I am happy to take any >10m slot to get through as much of "stop coercing things" as possible |
02:47 | <ljharb> | Michael Ficarra: occam wins again, i fixed it. either way the test262 PR needs coverage for this :-) |
02:48 | <Michael Ficarra> | 🎉 |
02:52 | <nicolo-ribaudo> | <small>Ladybird, Serenity is the OS</small> |
02:53 | <rkirsling> | it uh |
02:53 | <rkirsling> | might be too cold in here, by a bit |
02:53 | <littledan> | if we have time which we cannot otherwise use, I am happy to take any >10m slot to get through as much of "stop coercing things" as possible |
02:54 | <littledan> | https://chromestatus.com/feature/5073244152922112 |
02:54 | <dminor> | ljharb: https://bugzilla.mozilla.org/show_bug.cgi?id=1841113 |
02:54 | <ryzokuken> | for TG2 proposals, we do this kind of tracking centrally (in a wiki in this case). Would it be useful to do this as part of tc39/proposals or something like that? |
02:58 | <Andrew Paprocki> | Does anyone know how long implementations had this replace behavior? |
03:05 | <Andrew Paprocki> | This is the relevant v8 code I believe https://github.com/v8/v8/blob/main/src/runtime/runtime-regexp.cc#L208-L251 |
03:26 | <msaboff> | The second digit thing in there appears to be from when replace was first implemented in C++ in 2009: https://github.com/v8/v8/commit/e2af4529c3a5a31eaf21240ffc6fce42f0af2d3b#diff-df9cd537d3ef3350ae6d69fd7067704522b83ff80efdcfd53d2e30870ab977d2R1457-R1465 |
03:27 | <Jack Works> | I feel it's too cold in the meeting room 🥶 |
03:29 | <ptomato> | though IIRC someone wanted to be there for that, which makes it harder to do impromptu |
04:03 | <ljharb> | for TG2 proposals, we do this kind of tracking centrally (in a wiki in this case). Would it be useful to do this as part of tc39/proposals or something like that? |
04:04 | <ryzokuken> | sure, I'm not sure if centralization like this would make it easier to update/provide information |
04:04 | <ryzokuken> | but it'd certainly make it easier to find it, although out-of-context |
04:12 | <bakkot> | https://github.com/tc39/how-we-work/blob/main/terminology.md#override-mistake :) |
04:14 | <rkirsling> | whoa TIL > [!NOTE] |
04:16 | <ljharb> | it's pretty new, and got a lot of pushback in the first iteration; i think the second iteration addresses most of that tho |
04:17 | <Andrew Paprocki> | FYI https://docs.transcend.io/docs/consent/reference/privacy-and-security#read-before-using-tamper-resistance |
04:18 | <bakkot> | Transcend has been great about trying to get their customers upgraded |
04:18 | <Andrew Paprocki> | "Note that an interaction between Chrome 117, Transcend Consent's Tamper Resistance mode, and versions of regenerator-runtime (a common JavaScript library) older than v0.13.8 can cause errors and could negatively impact your website. To resolve these errors please update airgap.js to version 8.11.11 or higher to automatically disable Tamper Resistance mode. If you're using an earlier version of airgap.js and are unable to update, you can also manually disable Tamper Resistance by setting the the data-tamper-resist="off" attribute on your airgap.js script." |
04:18 | <Andrew Paprocki> | So they did change the default to now be off |
04:19 | <Christian Ulbrich> | Yeah SES does also freezing... |
04:19 | <littledan> | hmm, they didn't make a working tamper-resistant mode? |
04:20 | <Jack Works> | Yeah SES does also freezing... |
04:21 | <bakkot> | hmm, they didn't make a working tamper-resistant mode? |
04:21 | <Andrew Paprocki> | I assume upgrading regenerator-runtime also "fixes" it? |
04:21 | <bakkot> | correct |
04:21 | <Christian Ulbrich> | they freeze in the correct way. ses grabs the Iterator from [].values() not global name |
04:21 | <Jack Works> | I assume upgrading regenerator-runtime also "fixes" it? |
04:21 | <bakkot> | any version after 0.13.8 (inclusive) |
04:22 | <Christian Ulbrich> | Good to know, there is a correct way. I did not mean it as criticism, but as a response to nicolo-ribaudo asking, whether some other members are using this strategy... |
04:29 | <snek> | does pursing a "holistic approach" necessarily preclude the specific pr for this proposal |
04:30 | <snek> | like say we take some other approach like "freeze but correctly and also without a performance hit somehow", that doesn't fix the existing code that wasn't able to be updated |
04:31 | <Bradford Smith> | Could someone provide a link to a summary of what "the override mistake" means? |
04:31 | <bakkot> | https://github.com/tc39/how-we-work/blob/main/terminology.md#override-mistake |
04:31 | <Bradford Smith> | thx! |
04:38 | <rbuckton> | Have we considered adding a new descriptor property that, in combination with [[Writable]]: false explicitly opts in to a behavior of "if the prototype property is [[Writable]]: false , then define the property on the original object being assigned to"? Then workarounds for this become slightly less one-off? I'm not sure if that helps, to be honest. |
04:39 | <shu> | [[Writable]]: a secret 3rd thing |
04:39 | <snek> | you mean null |
04:40 | <snek> | is it acceptable to the object inheriting though? |
04:40 | <snek> | or is this something in the domain of the person doing the setting |
04:40 | <rbuckton> | [[Shadowable]]: true or something to that effect |
04:41 | <snek> | i feel like its something the person doing the setting wants control over, not the object, but idk |
04:41 | <snek> | maybe its weird and niche enough that it doesn't matter |
04:41 | <ljharb> | if you're doing the setting and want control you'd use Object.defineProperty |
04:41 | <Jack Works> | |
04:42 | <rbuckton> | then the question becomes how you add it. if you change how O.freeze works, you're basically fix the whole override mistake Object.freeze or Set semantics themselves. |
04:42 | <Jack Works> | but old code is using O.freeze so... |
04:43 | <rbuckton> | Yes, it would be something you would have to opt-in to, and something like Iterator.prototype.constructor would opt-in by default. |
05:16 | <snek> | thats quite interesting |
05:16 | <snek> | the done true thing |
05:16 | <snek> | i think i prefer rust's size hints |
05:17 | <ljharb> | Yes, it would be something you would have to opt-in to, and something like |
05:26 | <littledan> | my very intelligent comment: I don't like when it runs out of memory either |
05:27 | <snek> | always a fan of not running out of memory |
05:27 | <snek> | bakkot: the done:true size hinting you mentioned, that's not required for correct behavior right? |
05:28 | <rkirsling> | this is the internet, can't we just download more memory |
05:28 | <rkirsling> | oops wrong channel 😛 |
05:28 | <ljharb> | you wouldn't download a ram |
05:31 | <shu> | could someone remind me why do is no longer blocking for throw expressions? |
05:32 | <ljharb> | as i recall, throw expressions were considered independently useful even if do expression also existed? |
05:33 | <shu> | ah, okay, not some technical thing that was resolved, just that we decided it'd be fine to have both |
05:33 | <snek> | we are doing all this syntax just because of comma operators? |
05:33 | <snek> | does anyone use comma operators? |
05:34 | <ljharb> | minifiers and rebels |
05:34 | <Christian Ulbrich> | Does this mean, that function(a, b = throw c, c = throw d) would be legal? |
05:34 | <nicolo-ribaudo> | No, you have to wrap the first throw with this restriction |
05:35 | <snek> | wait what |
05:35 | <snek> | oh man yeah we do need to fix this |
05:35 | <snek> | lol |
05:35 | <ljharb> | because c, c = throw d is a potentially valid expression |
05:35 | <snek> | you know what i agree with richard |
05:35 | <snek> | lets take precedence from import and require parens |
05:35 | <HE Shi-Jun> | so u need to write c = (throw d) ? |
05:35 | <ljharb> | so it's either function(a, b = (throw c), c = throw d) or function(a, b = throw (c, c = throw d)) |
05:36 | <ljharb> | lets take precedence from import and require parens ** |
05:36 | <Christian Ulbrich> | in other words, how could I write a function, that throws if multiple arguments are not given by using throw as a default value? Thx. ljharb ... |
05:36 | <HE Shi-Jun> | what about let x = throw c, d = 1 ? |
05:36 | <ljharb> | same, you'd need let x = (throw c), d = 1 |
05:36 | <ljharb> | in other words, how could I write a function, that throws if multiple arguments are not given by using |
05:37 | <HE Shi-Jun> | Seems too strict? |
05:37 | <ljharb> | i mean who's going to write that code tho |
05:37 | <ljharb> | let x = throw c, d = 1 will throw and never define d in either interpretation |
05:37 | <Christian Ulbrich> | ljharb: But, would function(a, (b = throw c), (c = throw d)) also work? |
05:37 | <ljharb> | ljharb: But, would |
05:37 | <ljharb> | oh no wait |
05:38 | <ljharb> | a, b = (throw c), c = (throw d) - parens aren't around the = part. |
05:38 | <snek> | what on earth |
05:38 | <ljharb> | so either we require these parens or we totally change how the comma operator works |
05:38 | <Christian Ulbrich> | Okay, that would be fine with me, I would not want to explain to devs, that the syntax depends on the position of something... |
05:38 | <HE Shi-Jun> | it's possible in destructing to mean required. let [x, y = throw new Error(), z] = ... |
05:38 | <ljharb> | Okay, that would be fine with me, I would not want to explain to devs, that the syntax depends on the position of something... |
05:39 | <ljharb> | it's possible in destructing to mean required. |
05:39 | <Christian Ulbrich> | no, just the necessity of the syntax. i'm sure there'd be a linter that either forbids or requires the parens in the terminal case |
05:40 | <HE Shi-Jun> | I agree it's not a big deal, just ask whether we can loose the restriction... |
05:40 | <nicolo-ribaudo> | I agree it's not a big deal, just ask whether we can loose the restriction... x = throw a, b being different from throw a, b is ok |
05:40 | <nicolo-ribaudo> | (the first one throws a , the second one b ) |
05:41 | <eemeli> | TCQ is indeed frozen. |
05:41 | <HE Shi-Jun> | Because in let x = 1, y = 2 it already not follow comma expression. |
05:41 | <ljharb> | yeah true, that's not the comma operator so maybe that one would be fine? |
05:42 | <HE Shi-Jun> | yeah true, that's not the comma operator so maybe that one would be fine? |
05:42 | <eemeli> | I'd like to reply as well. |
05:42 | <snek> | i still don't get why we're talking about comma operators in the context of human understandability |
05:42 | <snek> | seems like garbage in garbage out |
05:42 | <ryzokuken> | it's back |
05:44 | <Chris de Almeida> | can whoever was having TCQ problems check again? |
05:44 | <Christian Ulbrich> | without Promise.withStaticResolvers() we need: let resolve, promise = new Promise(res => resolve = red) ... :) |
05:44 | <nicolo-ribaudo> | Temperature check? |
05:45 | <HE Shi-Jun> | yeah thats what I ask |
05:46 | <bradfordcsmith> | Could it work to follow the pattern of import for throw . Treat it like a function call - require parentheses like throw(thingTothrow) - does that help anything? |
05:46 | <haxjs> | Could it work to follow the pattern of |
05:46 | <ljharb> | oof, import() is like a function call, and throwing isn't, that doesn't seem like an ideal workaround to me |
05:47 | <haxjs> | because throw(x), y also a valid statement |
05:47 | <devsnek> | oof, |
05:47 | <devsnek> | (i am the call/cc people) |
05:47 | jesse | waves to the fellow schemers |
05:48 | <ljharb> | what happened to nicolo's queue item? |
05:48 | <nicolo-ribaudo> | what happened to nicolo's queue item? |
05:48 | <ljharb> | ah k |
05:48 | <nicolo-ribaudo> | It would be throw using an early error as kevin describes |
05:49 | <nicolo-ribaudo> | But not with the current lookahead grammar |
05:50 | <ljharb> | isn't await 's super low precedence relevant here? |
05:50 | <ljharb> | like, await 1, 2 will never await 2, only 1 |
05:50 | <ljharb> | so if throw 's precedence is super low also (above or below await's) then would the problem just go away? (because people trying to USE the comma operator would be forced to paren-wrap, and who cares about that) |
05:51 | <Michael Ficarra> | ljharb: that's high, no tlow |
05:51 | <snek> | i appreciate that we have the opportunity to have 3 different precedence keyword unary operators |
05:51 | <bakkot> | ljharb: the problem is that statement position throw is low precedence |
05:51 | <Michael Ficarra> | snek: blame allen :-( |
05:51 | <bakkot> | so throw 1, 2 already means "throw 2" |
05:51 | <hax (HE Shi-Jun)> | One question is why choose follow await not yield |
05:52 | <rkirsling> | which direction is "high" precedence will never not be confusing |
05:52 | <snek> | things with higher precedence evaluate first |
05:52 | <ljharb> | sigh, comma operator's so gross |
05:52 | <Michael Ficarra> | rkirsling: I think it's person to person, like whether you have left/right and west/east ingrained |
05:52 | <snek> | simple rule |
05:52 | <hax (HE Shi-Jun)> | sigh, comma operator's so gross |
05:53 | <littledan> | which direction is "high" precedence will never not be confusing |
05:55 | <bakkot> | if we force you to write parentheses in the ambiguous case then no reader will ever have to be confused |
05:55 | <bakkot> | so that seems like the best outcome |
05:55 | <bakkot> | writers occasionally getting a message like "you gotta use parens here" seems like the least evil |
05:56 | <nicolo-ribaudo> |
Can somebody remind me why this is not doable? |
05:57 | <hax (HE Shi-Jun)> |
|
05:58 | <nicolo-ribaudo> | I believe it's doable, just introduce some inconsistence and refactor harzard when switch from throw exp/statement |
05:59 | <hax (HE Shi-Jun)> | nicolo-ribaudo: Maybe I misunderstand ? |
05:59 | <nicolo-ribaudo> | Throw statements are throw Expression , and I'm asking if throw expressions can be the same but with a high precedence on the left side. |
06:00 | <nicolo-ribaudo> | UnaryExpression precedence on the left, Expression precedence on the right |
06:00 | <bakkot> | I am not sure that function f(x = throw a, y){} throwing y is actually a good outcome either |
06:01 | <nicolo-ribaudo> | I am not sure that |
06:02 | <rbuckton> | I'm beginning to think the only option is to move throw to Expression and just always require parenthesis. Every other option is blocked. |
06:03 | <rbuckton> | Actually, maybe it isn't? We do some grammar tricks with UpdateExpression and could do something similar |
06:04 | <rbuckton> | I'll have to think on it. |
06:06 | <snek> | i'n happy as long as we aren't making things weirder to make comma op more readable |
06:07 | <rbuckton> | I don't think a grammar-only solution is feasible, as it would also trigger ASI. |
06:11 | <rbuckton> | If I cannot use an Early Error (per waldemar), and we cannot use UnaryExpression without banning trailing infix punctuators (per bakkot), I do not see another solution aside from always requiring parens. I'm open to other suggestions, though. |
06:17 | <bakkot> | i'n happy as long as we aren't making things weirder to make comma op more readable throw , including code which does not use the comma operator. |
06:17 | <littledan> | If I cannot use an Early Error (per waldemar), and we cannot use UnaryExpression without banning trailing infix punctuators (per bakkot), I do not see another solution aside from always requiring parens. I'm open to other suggestions, though. |
06:17 | <littledan> | there are four possibilities at play, and all violate one or other goal |
06:18 | <rbuckton> | waldemar: We use an Early Error to ban optional chain followed by a template literal specifically to avoid ASI. I'm not sure why we wouldn't be able to do the same in this case? |
06:18 | <littledan> | (the fourth being, don't advance this proposal) |
06:19 | <rbuckton> | Yes, it might require a number of SS rules, but we have precedence within the specification. |
06:21 | <nicolo-ribaudo> | I don't think a grammar-only solution is feasible, as it would also trigger ASI. |
06:21 | <rbuckton> | I also suggested that, but waldemar seemed against that as well. |
06:23 | <bakkot> |
x && throw a || b . right now we ensure the grammar is unambiguous everywhere except the annex B regexp grammar. |
06:23 | <rbuckton> | I could add a grammar to throw expressions that consumes all of the infix operators and the expressions that follow, and then report an early error in static semantics. |
06:25 | <bakkot> | that would still make the grammar ambiguous if it was at Unary precedence |
06:25 | <bakkot> | and if it at AssignmentExpression precedence then you can't write a ?? throw b |
06:26 | <bakkot> | (like you can't do a ?? yield b ) |
06:26 | <snek> | oh my |
06:26 | <rbuckton> | Or just static semantics rules to each of the infix operators, like:
|
06:27 | <snek> | this is the first real use of boxed primitives i've seen i think |
06:27 | <bakkot> | we should not encourage boxed primitives |
06:27 | <snek> | yeah i'm not sure how i feel about it |
06:28 | <bakkot> |
|
06:28 | <bakkot> | frankly I do not understand the concern about having a bunch of early errors |
06:28 | <ljharb> | errors are best encountered early |
06:28 | <rbuckton> | frankly I do not understand the concern about having a bunch of early errors |
06:28 | <hax (HE Shi-Jun)> | (like you can't do |
06:35 | <rbuckton> | that was my suggestion in the thread but waldemar doesn't like having a bunch of early errors delete , so we have precedence for both parts of this within the spec as well. |
06:39 | <bakkot> | in tdz michael said he like the "force you to always use parentheses" option |
06:40 | <nicolo-ribaudo> | Including cases like a ?? (throw b); ? |
06:40 | <bakkot> | Michael Ficarra: ^ ? |
06:40 | <Michael Ficarra> | not only do I like it, I independently discovered it and thought it was good |
06:40 | <bakkot> | If we did that and also made the RHS be a UnaryExpression, then it would be kind of the intersection subset which everyone can live with |
06:40 | <bakkot> | no new early errors, no ambiguity |
06:41 | <Michael Ficarra> | 😁 |
06:41 | <rkirsling> | I mean ?? throw x really seems like the core case though |
06:41 | <bakkot> | and using UnaryExpression as the RHS means we could, in the future, relax the restriction, if people relax their concerns |
06:41 | <rbuckton> | I'm not a huge fan of requiring the parenthesis since they wouldn't otherwise be necessary for most cases. |
06:41 | <Michael Ficarra> | rkirsling: and you can do that, you just need to write parentheses or you get a syntax error |
06:41 | <rkirsling> | you_cant_just.jpg |
06:42 | <rbuckton> | If throw is at Expression precedence, then we don't need ThrowStatement anymore, since it would be completely covered by ExpressionStatement. |
06:42 | <bakkot> | (to be clear I would also prefer the early error route, over forcing parens everywhere, but I could live with forcing parens everywhere) |
06:42 | <snek> | is shane in here |
06:43 | <rkirsling> | I too had no idea about ?? yield x though. does that also apply to ?? await x ? |
06:43 | <bakkot> | If |
06:43 | <nicolo-ribaudo> | I too had no idea about |
06:43 | <bakkot> | I too had no idea about await is unary precedence |
06:43 | <bakkot> | await and yield parse very differently |
06:44 | <rkirsling> | fair enough |
06:45 | <rbuckton> | I don't think we need the EE rules for everything, just + , - , and / , the rest could still just be a lookahead restriction. |
06:45 | <nicolo-ribaudo> | And /= |
06:45 | <Michael Ficarra> | If |
06:45 | <rbuckton> | I think that might change its completion value though |
06:46 | <Michael Ficarra> | oh, fair lol |
06:52 | <waldemar> | errors are best encountered early |
06:52 | <bakkot> | For a user of the language, there is no difference between "in the grammar" and "as an early error" |
06:53 | <waldemar> | The difference is complexity. In most cases, if you're using early errors, then you're doing something more complicated than what can be expressed in a grammar, and that carries a cost. |
06:54 | <shu> | where is this gist? |
06:55 | <bakkot> | The cost is fairly small. Concretely, here's the trilemma:
|
06:55 | <bakkot> | the third arm of the trilemma seems obviously better than the first two, to me |
06:55 | <bakkot> | where is this gist? |
06:55 | <rkirsling> | (wow, I never actually stopped to analyze dilemma into di+lemma before...) |
06:55 | <waldemar> | I am concerned about usability. |
06:55 | <rbuckton> | I've created https://github.com/tc39/proposal-throw-expressions/pull/18 to show what the Early errors would look like. |
06:56 | <rbuckton> | Hmm. it didn't publish a rendered spec |
06:56 | <littledan> | the third arm of the trilemma seems obviously better than the first two, to me |
06:56 | <littledan> | I mean, the hazard case of the third one |
06:56 | <rbuckton> | ah, now it did |
06:57 | <bakkot> | I am concerned about usability. |
06:57 | <shu> | https://gist.github.com/bakkot/5a22c8c13ce269f6da46c7f7e56d3c3f |
06:57 | <rbuckton> | I only need to add 3 static semantics rules and remove + , - , / , and /= from the banned token list. |
06:57 | <bakkot> | I agree it is a little more complicated, but you have to weigh that against the costs of the other options, which seem a lot worse. |
06:57 | <hax (HE Shi-Jun)> | Will there be new things need to escape in the future? |
06:58 | <bakkot> | The idea is, no |
07:01 | <waldemar> | Either a throw expression can be used in a logical expression or not. Having it sometimes be usable in a logical expression and sometimes not is too confusing. |
07:01 | <waldemar> | That's what we'd get with the early errors. |
07:01 | <bakkot> | I think having it usable only as the RHS of a logical expression is completely fine. |
07:01 | <bakkot> | There is no use case for having it as the LHS of a logical expression. |
07:01 | <nicolo-ribaudo> | Either a throw expression can be used in a logical expression or not. Having it sometimes be usable in a logical expression and sometimes not is too confusing. -1 ** 2 vs 1 ** -2 |
07:02 | <Michael Ficarra> | ryzokuken: can we get the queue cleared out? |
07:02 | <waldemar> | That analogy is not helpful. |
07:03 | <nicolo-ribaudo> | It is an expression that can be used only on one side of a binary operator and not on the other |
07:03 | <ryzokuken> | ryzokuken: can we get the queue cleared out? |
07:03 | <waldemar> | How is that relevant? |
07:03 | <ryzokuken> | should be good now |
07:03 | <rbuckton> | Either a throw expression can be used in a logical expression or not. Having it sometimes be usable in a logical expression and sometimes not is too confusing. throw has to be the right-most thing, unless you parenthesize it" to be that confusing. |
07:04 | <waldemar> | I do. It violates intuition about how operator precedence works. |
07:06 | <bakkot> | No user will ever have to learn that throw can't be used on the LHS of a logical expression, so they will not have anything to be confused by. |
07:07 | <bakkot> | The only reason someone would write throw x || y is if they were hoping to throw x || y , and that isn't the behavior they'd get with higher precedence and no early errors anyway. |
07:07 | <waldemar> | Parenthesizing throw expr as throw(expr) is intuitive. Parenthesizing it as (throw expr) is not. |
07:07 | <rbuckton> | Parenthesizing throw . |
07:08 | <rbuckton> | If you want to throw a || b from an expression position, you write throw (a || b) |
07:08 | <waldemar> | I gave a counterexample during the plenary. |
07:12 | <bakkot> | Can you repeat it here? |
07:13 | <waldemar> | b && throw(c) || d |
07:14 | <rbuckton> | to me that would be akin to how we required parens when mixing ?? with && or || . |
07:14 | <waldemar> | But we can mix && and || without requiring parentheses. |
07:15 | <rbuckton> | (b && throw c) || d or b && (throw c) || d |
07:15 | <bakkot> | OK, yes, that's a good example. I retract the claim that no one will have to learn that throw can't be used on the LHS of a logical expression, but I stand by the claim that this cost is less than that of having throw a ? b : c throw a . |
07:15 | <rbuckton> | linters would generally push you towards the parens anyways |
07:16 | <bakkot> | Making things illegal with early errors means that you're forced to confront the complexity as early as possible, instead of accidentally writing a program whose behavior is not what you thought. |
07:16 | <bakkot> | And throw a ? b : c seems like a case which will come up a lot if it is not made illegal |
07:19 | <ryzokuken> | I see a black screen |
07:19 | <ryzokuken> | for some reason |
07:19 | <ryzokuken> | ah, it fixed itself |
07:19 | <waldemar> | You can fix that by requiring the throw(expr) form for throw-expressions. |
07:20 | <bakkot> | Can you elaborate on that? |
07:21 | <waldemar> | The argument of a throw-expression must be a parenthesized expression. |
07:21 | <bakkot> | If throw is at unary expression precedence, then even if the RHS of throw is a ParenthesizedExpression, you would still have throw (a) ? b : c being legal |
07:21 | <waldemar> | Just like the condition of an if-expression must be parenthesized. |
07:22 | <waldemar> | The first operand of ?: is rarely parenthesized. |
07:28 | <bakkot> | True, but it would be confusing for readers. |
07:30 | <bakkot> | Also, personally, I would prefer having throw only usable in parentheses. (throw new Error()) looks a lot more natural, to me, than throw (new Error()) . |
07:31 | <bakkot> | (And has fewer edge cases.) |
07:33 | <nicolo-ribaudo> | I somehow want to both 👍️ and 👎️ this -- I think you should write throw without a trailing space like usually done for dynamic import |
07:33 | <waldemar> | Also, personally, I would prefer having (throw expr) form. It's simple, understandable syntax. |
07:35 | <nicolo-ribaudo> | I would not block that, always parens is better than, for example, parens-in-function-params-except-for-last-one. I think it looks particularly bad compared to the parens-less version, but better than the current inconsistency with comma-separated lists |
07:37 | <shu> | real talk my brain is not working very well |
07:37 | <shu> | please make temperature check real simple |
07:39 | <hax (HE Shi-Jun)> | seem need to refresh the page to see the temp check |
07:41 | <nicolo-ribaudo> | TCQ feedback: we have two positive options but just one negative |
07:42 | <rbuckton> | I do not see the temp check, even after refreshing. |
07:42 | <rkirsling> | same here |
07:42 | <rkirsling> | tried in two browsers |
07:42 | <rkirsling> | no options appear |
07:43 | <snek> | TCQ feedback: we have two positive options but just one negative |
07:44 | <Bradford Smith> | Isn't the API for a proposal supposed to be mostly settled before moving to stage 2? |
07:45 | <nicolo-ribaudo> | Well the API is either this or nothing |
07:45 | <Bradford Smith> | "Possible API to do the clamping logic" doesn't seem settled to me. |
07:45 | <ljharb> | it'd just be a one-arg function |
07:45 | <bakkot> | the thing where some specific person needs to say "I withhold consensus" seems like it makes proposals to easy to advance |
07:45 | <nicolo-ribaudo> | "Possible API to do the clamping logic" doesn't seem settled to me. |
07:46 | <snek> | the thing where some specific person needs to say "I withhold consensus" seems like it makes proposals to easy to advance |
07:46 | <bakkot> | having 40% of the plenary unconvinced does not seem like it should amount to "consensus" |
07:46 | <snek> | i mean yeah jordan is just being nice |
07:47 | <snek> | under the pure rules, if jordan wants x and no one has some strong blocker for x, it would move forward |
07:47 | <bakkot> | the pure rules say "consensus" |
07:47 | <bakkot> | we have been operating in a mode where, if no one says "I withhold consensus", it is regarded as consensus |
07:47 | <bakkot> | but that seems absurd after 40% of delegates indicated they were unconvinced |
07:48 | <rkirsling> | I guess it's a question of whether people need to be "convinced" |
07:48 | <rkirsling> | as opposed to merely not "convinced of the opposite" |
07:48 | <bakkot> | there is no "convinced of the opposite" box |
07:48 | <rkirsling> | right |
07:48 | <bakkot> | there is an "indifferent" box, though |
07:49 | <rkirsling> | ah true. |
07:49 | <snek> | oh man symbol.thenable |
07:49 | <snek> | i was so upset when this didn't get stage 1 |
07:49 | <snek> | i had an angry thread on twitter |
07:50 | <nicolo-ribaudo> | What does it mean to withdraw a stage 0 proposal, doesn't our actual process start at stage 1? |
07:50 | <nicolo-ribaudo> | "Stage 0 is just an idea" |
07:50 | <snek> | i've seen real code hit this problem |
07:51 | <Michael Ficarra> | yeah I think technically stage 0 and withdrawn are ~equivalent |
07:52 | <Jack Works> | i've seen real code hit this problem |
07:52 | <bakkot> | thenables are like a top-three mistake in JS, after "accepting things of the wrong type" and "existence of object.prototype" |
07:53 | <snek> | dunno if i'd put them that high but definitely up there |
07:53 | <hax (HE Shi-Jun)> | I really hope we can have Symbol.thenable or any solution to solve the weird behaivor of module with then export. |
07:53 | <nicolo-ribaudo> | thenables are like a top-three mistake in JS, after "accepting things of the wrong type" and "existence of object.prototype" |
07:53 | <bakkot> | I really hope we can have Symbol.thenable or any solution to solve the weird behaivor of module with |
07:53 | <hax (HE Shi-Jun)> | thenables are like a top-three mistake in JS, after "accepting things of the wrong type" and "existence of object.prototype" |
07:53 | <Jack Works> | with enters the room |
07:53 | <snek> | Symbol.thenable wouldn't fix that, since you can't export a symbol name |
07:53 | <nicolo-ribaudo> | export { true as "@@thenable" } 😆 |
07:53 | <hax (HE Shi-Jun)> | Symbol.thenable wouldn't fix that, since you can't export a symbol name |
07:54 | <Jack Works> | just let module have it automaticlly |
07:54 | <Michael Ficarra> | Symbol.thenable wouldn't fix that, since you can't export a symbol name |
07:54 | <bakkot> | people have already started relying on the current the behavior, so we can't just unconditionally add it to all namespace objects |
07:54 | <nicolo-ribaudo> | just let module have it automaticlly then |
07:54 | <snek> | "breaks" |
07:54 | <snek> | wait no i have to avoid getting into this argument again 😅 |
07:54 | <nicolo-ribaudo> | Oh well, you could have then[Symbol.thenable] = false on the function |
07:55 | <hax (HE Shi-Jun)> | It breaks modules that currently export |
07:56 | <bakkot> | if we are willing to break the web I have a lot of higher-priority things I would like to fix |
07:56 | <snek> | web2 right |
07:56 | <bakkot> | unfortunately I think we are not willing to break the web, so we can't fix it |
07:56 | <shu> | msaboff: ljharb: yes, endianness is about the bytes, not the bits. but clamping clamps something between 0 to 255, i think in a DataView method that is like, all about reinterpreting byte buffers, isn't there a possibility for confusion on whether you're clamping the leftmost byte or the rightmost byte of the Number value? |
07:56 | <shu> | like the other methods don't combine some operation on top of the conversion to and from number formats |
07:56 | <shu> | am i too jet lagged |
07:58 | <hax (HE Shi-Jun)> | unfortunately I think we are not willing to break the web, so we can't fix it |
07:58 | <Christian Ulbrich> | I think, if we have consensus we can do EVERYTHING, who cares about the past. :) |
07:59 | <hax (HE Shi-Jun)> | Previously, when at land, I already point out it conflict with old corejs polyfill, but no one care. |
07:59 | <hax (HE Shi-Jun)> | IMO, it's really worse than Symbol.thenable. |
07:59 | <snek> | did it break things? |
08:00 | <nicolo-ribaudo> | In this case we know people rely on it |
08:00 | <shu> | did it break things? 'at' as a key |
08:00 | <snek> | we broke lego? :O |
08:00 | <shu> | but... not in whatever way corejs was doing at afaik |
08:00 | <rkirsling> | bricklink.com, yeah |
08:00 | <shu> | it was some lego marketplace site |
08:00 | <Michael Ficarra> | D: |
08:00 | <shu> | bricklink or something? it had brick in the name |
08:01 | <msaboff> | msaboff: ljharb: yes, endianness is about the bytes, not the bits. but clamping clamps something between 0 to 255, i think in a DataView method that is like, all about reinterpreting byte buffers, isn't there a possibility for confusion on whether you're clamping the leftmost byte or the rightmost byte of the Number value? |
08:01 | <snek> | so we've got lego and nasa on the list |
08:01 | <snek> | i wonder what else |
08:01 | <shu> | msaboff: your intuition matches what jordan said, so i withdraw my withholding of consensus based on the possible confusion |
08:01 | <shu> | since i am off the mark on my intuition |
08:01 | <shu> | that said i'd be much comfortable going to stage 2 with a clear direction |
08:02 | <shu> | not 3 possible choices |
08:02 | <msaboff> | that said i'd be much comfortable going to stage 2 with a clear direction |
08:02 | <Christian Ulbrich> | @snek Wasn't it for Array.group* IBM? |
08:06 | <rbuckton> | /= is a strange case for throw expressions. a ?? throw b /= c wouldn't be legal even without the token restriction, because a ?? throw b isn't a LeftHandSideExpression. |
08:08 | <nicolo-ribaudo> | With `/=` you have to be very careful about how things get tokenized, before applying the syntactic grammar |
08:09 | <nicolo-ribaudo> | So we must be careful with saying that it doesn't have the same problem as `/` |
08:11 | <rbuckton> | The issue is this:
is interpreted as |
08:21 | <rbuckton> | Well, it could work if I added a level between UpdateExpression and LeftHandSideExpression, I guess. |
08:25 | <rbuckton> | Or just add it to LeftHandSideExpression, since it wouldn't be a valid assignment target anyways. |
13:57 | <bakkot> | chairs: shu and I are happy to reduce our TDZ/coercing items (respectively) to 45 minutes if it means getting to discuss both items |
13:57 | <bakkot> | (I am also happy to ok with reducing mine further if that's the only way we can fit it in) |
14:35 | <Chris de Almeida> | chairs: shu and I are happy to reduce our TDZ/coercing items (respectively) to 45 minutes if it means getting to discuss both items |
14:37 | <Chris de Almeida> | this also increases the likelihood of getting to discuss both items, although we now have time for TDZ already, per time already freed up |
17:19 | <TabAtkins> | I think we just need a "use semicolons" parser switch that turns off ASI honestly. |
19:52 | <rbuckton> | Avoiding parens for throw may end up being more complex than it's worth to try to handle /= , but I'm not sure I want to give up on the UnaryExpression precedence. I'm thinking about restricting throw to be only valid in ParenthesizedExpression for now, while still leaving it's operand to be UnaryExpression. While fairly restrictive for now, it would give us the ability to relax the grammar in the future by either resolving the ASI issue somehow, or widening the operand. |
20:48 | <Michael Ficarra> | so this means we use it like an s-expression? 😁 |
21:29 | <shu> | Chris de Almeida: then reduce TDZ to 45 mins |
21:30 | <shu> | Chris de Almeida: further reduce it to 30 minutes if (and only if) that accommodates the coercion item, otherwise keep it at 45 |
21:40 | <Chris de Almeida> | thank you for being flexible! given these parameters, it's likely we will be able to get to both items. still, I'm hopeful that we will gain some time today so that we don't have to compromise too much on the original timeboxes |