2021-03-01 [10:53:34.0000] rickbutton: R&T call is overlapping with TC39 2021-03-02 [15:08:39.0000] I can't reply in editor group but yeah I'm taking the opportunity to thorough read the docs instead [15:08:47.0000] thoroughly even 2021-03-03 [10:39:50.0000] robpalme: Hello are you around? [10:50:35.0000] hello Keith! [10:51:47.0000] robpalme: Dan mentioned that for top level await you wanted microtasks to be delayed so it'd be easier to inline modules into the requester(s)? [10:52:38.0000] I wasn't sure I fully followed that. Maybe you could explain it to me? From what I understood it didn't seem like it would work if you wanted to inline modules with more than depth 2? [10:53:08.0000] Since once you finish the second dependency you have to turn the microtask queue according to the current spec [10:53:40.0000] e.g. if a -> b -> c there needs to be a microtask turn between b and a [10:54:54.0000] If you want I can forward/CC you to an email thread between Dan (+ others) and me, which maybe will help provide context [11:01:43.0000] please forward it on [11:02:58.0000] the original request (promoted by guy bedford) was that synchronous module graphs should remain fully inlineable (i.e. concatenated into one run-to-completion) to preserve what Rollup does today [11:04:36.0000] Oh! Yeah, that makes sense. I also think it won't be web compat to change that [11:04:51.0000] I thought this was about async subgraphs [11:05:07.0000] you want to insert a delay into TLA? [11:05:25.0000] right - guy had a later request that i agreed with on TLA - need to dig it up [11:05:41.0000] I don't have your email can you DM it to me rob? [11:06:31.0000] devsnek: It's to drain the microtask queue between each module in an async subgraph. [11:06:41.0000] right now it drains effectively randomly [11:06:53.0000] https://github.com/tc39/proposal-top-level-await/issues/158#issue-796269657 <-- i think this is the issue [11:07:41.0000] Ah, ok. Yeah I read that issue 2021-03-08 [01:02:25.0000] Hello all, we have a Jitsi video conference trial today (Monday) at 9:30am PT. Details are on the Reflector. [08:16:02.0000] As a reminder, the Jitsi trial is in 75 mins. Attendance is highly encouraged. [09:30:41.0000] Istvan is in the Jitsi and sharing his screen. It works! [09:38:41.0000] please feel free to join us in the Jitsi [10:16:10.0000] where are Jitsi details? [10:16:35.0000] n/m, found it [12:23:45.0000] check this out for potential online hallway track: https://github.com/thecodingmachine/workadventure [12:25:01.0000] https://gather.town/ is what IETF uses but it's nonfree and paid [12:30:48.0000] the 2d ones aren't as immersive ime [12:32:05.0000] ljharb: but they solve the hardware issues! [12:32:20.0000] not all delegates manage to connect to hubs because it needs decent hardware to run [12:33:00.0000] s/solves/avoids, yes [12:33:20.0000] i wonder if hubs could add a 2d mode that'd be low-resource 2021-03-09 [16:04:51.0000] ystartsev akirose robpalme bterlson +{other chairs?] we should nominate André Bargull for the Ecma Fellow Award. [16:07:06.0000] This is optimistic and not a joke. I could stress some reasons why, but I'm pretty solid about my statement. [16:28:14.0000] wanna put those reasons in an email to us? [16:44:42.0000] I'll try to write down some stuff. It should be around anba's extensive contributions to ECMA-262, ECMA-402, Test262 all in a personal capacity, probably unfunded for most of the work, if not 100% of it. [17:03:27.0000] anba has the distinction of being the second-largest contributor to ecma-262 by number of commits [19:14:58.0000] candidate for ES2021 is released: https://github.com/tc39/Reflector/issues/361 [19:23:19.0000] ljharb: should it be on the agenda [19:23:31.0000] it is, part of the 262 update [19:23:37.0000] ah ok [19:24:32.0000] is this the thing where we go through the member list [19:24:51.0000] yeah [19:25:18.0000] exciting [19:35:17.0000] Bakkot: anba is the top contributor of ECMA-402 by number of commits. 5th in Test262, but that's just a rough idea. The contributions are pretty good in quality too. [00:56:12.0000] leobalter: happy to add it to my slides -- did you send me an email (might have missed it) [01:25:35.0000] Bakkot: leobalter added it: https://docs.google.com/presentation/d/1uwBpXKUaZPor14taHnguP29ur6q1gmshho6IHcGbF8w/edit#slide=id.gc5fb7997ab_0_0 [01:27:14.0000] Thanks ystartsev! I’m sending an email in the morning. I had some extra work today until late night so I got late on this. [01:27:31.0000] no prob [01:27:51.0000] i can also give you edit access to the slides? might be faster [06:48:03.0000] hello all, for today's plenary we are going to use Jitsi video conferencing for the first time. as usual, the link is given to you via the sign-in form. [06:48:36.0000] More details are on the Reflector meeting link: https://github.com/tc39/Reflector/issues/348 [06:49:33.0000] I encourage joining early to try out Jitsi features. We will start the Jitsi one hour before the real meeting for anyone wanting to do tech checks. [08:10:46.0000] the draft schedule is now posted on the reflector [08:11:02.0000] ty [09:14:26.0000] the Jitsi meeting is now started for anyone wishing to do a tech check [09:20:50.0000] I cannot login to Jitsi - it's asking me for a key [09:21:14.0000] (maybe password? my display is in Spanish for some reason) [09:21:29.0000] try using the password provided in the sign-in form [09:21:35.0000] "Clave necessario" [09:21:47.0000] right- duh [09:41:17.0000] ystartsev: I did an edit at the slides (André's slide only). I'm not sure if we should include that giving a fellow award to André is valuable for us to make sure the volunteer work is never blocked by them not being part of a member org. 6+ years of contributions is pretty fair for this. [09:48:30.0000] wait, this app yells at you if you're not using Chrome? [09:48:36.0000] that's pretty unfortunate [09:52:16.0000] gonna try to use safari anyway and see what happens [09:57:17.0000] what is missing from firefox/safari that makes video apps prefer chrome? [09:57:39.0000] I hate having a single chrome tab for google meet and others [09:58:43.0000] rkirsling: safari doesn't work on it at app [09:58:44.0000] *all [09:58:49.0000] rkirsling: the audio is trash [09:58:58.0000] rkirsling: mobile safari too [10:01:20.0000] audio seems okay [10:01:39.0000] rickbutton: google meet works okay in safari 👍 [10:01:55.0000] this software seems nice so far [10:02:09.0000] rkirsling: hm, i ended up having to use the native app for it to work at all [10:02:18.0000] (on ipad) [10:02:46.0000] there was an info window that said something about requiring insertable streams [10:02:51.0000] I don't even know what those are [10:05:12.0000] are there meant to be slides? [10:05:21.0000] Minor complaint about jitsi, its hard to tell which audio device is which in settings: https://usercontent.irccloud-cdn.com/file/etG782LQ/image.png [10:05:35.0000] rkirsling: yelling for not using Chromium is an Igalia instance-specific thing 😅 [10:05:35.0000] that is a lot of audio devices [10:05:41.0000] There's an ellipsis, but no way to expand. [10:05:42.0000] (no worries if not I'm just making sure I'm not missing functionality) [10:05:46.0000] because we used to have issues with old firefox versions [10:06:03.0000] I blame voicemeeter for the length of the list, but jitsi for the width of the list :) [10:06:04.0000] ryzokuken: ah okay 😅 [10:06:53.0000] kind of weird that it doesn't highlight/prioritize the view of whoever's speaking [10:07:20.0000] (on the tile view) [10:07:39.0000] ljharb: turn off tile view? but I see what you mean [10:08:02.0000] Is there a way to get it to not cover up parts of the view with controls? [10:08:45.0000] wsdferdksl: toggle to the grid view? [10:09:27.0000] jitsi is beach balling [10:09:35.0000] If you're not in tile view, you can hide the participant list in the bottom right corner: https://usercontent.irccloud-cdn.com/file/Ta9MuFJA/image.png [10:09:43.0000] I'm losing most of the audio [10:10:08.0000] oh whoa sam is on the call [10:10:22.0000] which client are you using leo? the audio is fine for me [10:10:34.0000] same on the electron client [10:10:56.0000] even in non-tile view tho the "big" person isn't always the speaker, is there a way to do that? [10:11:14.0000] wait are we supposed to be seeing slides [10:11:21.0000] no [10:11:39.0000] ok [10:11:41.0000] oh [10:11:42.0000] ystartsev: killed the bot on the assumption we aren't trying to transcribe this [10:11:44.0000] I see them now? [10:11:52.0000] i am presenting [10:12:30.0000] robpalme: Web version on Safari, it recommends to use Chrome or Chromium as the only fully supported alternative [10:12:39.0000] it's going ok on Chrome [10:12:53.0000] ooh those TCQ reactions got deployed [10:12:58.0000] leobalter: Safari has a few issues unfortunately :/ [10:13:46.0000] hmm yeah slides remained a black box [10:13:47.0000] I understand, but it should be better to make that information available with the video link, before I join [10:15:13.0000] FF displays slides [10:16:22.0000] leo, I will update the link to say Safari has known issues [10:16:38.0000] Thanks! [10:16:52.0000] robpalme: could you also recommend the electron app? That should work for most people and all platforms [10:17:06.0000] https://github.com/jitsi/jitsi-meet-electron [10:17:13.0000] another jtsi "issue"? It uses `Shift+S` for fullscreen, but I use `Win+Shift+S` to take screenshots on Windows (like the two I posed above), which causes it to swap between fullscreen and windowed :(. [10:17:57.0000] ryzokuken: where is the electron app? the Downloads page only points to App Store, google play, etc [10:18:02.0000] I never knew the Shift+S shortcut before today! :D [10:18:33.0000] leobalter: https://github.com/jitsi/jitsi-meet-electron [10:19:17.0000] https://github.com/jitsi/jitsi-meet-electron/releases/tag/v2.6.1 was released 4 days ago, should work just fine. [10:21:43.0000] oh the tcq reactions disappeared just as I was gonna try using 'em [10:25:49.0000] Whenever I connect, it disconnects within a minute and tries connecting again. [10:26:27.0000] Michael, which client are you using? [10:26:34.0000] Safari [10:26:50.0000] Jitsi does not seem to work in Safari. [10:27:10.0000] On iOS the native app works well [10:27:30.0000] seems like everybody who's tried it has had a *different* issue but yes, latest FF is more stable [10:27:31.0000] I shouldn't have to download something to attend the meeting. [10:28:06.0000] What is wrong with what we used (Teams) for the last several meetings? [10:28:37.0000] yes, it's unfortunate it doesn't work in Safari [10:29:35.0000] msaboff: soooooo many things [10:29:41.0000] we had reports from multiple people of issues with Teams. [10:29:45.0000] So we are having an open standards meeting with a platform that doesn't work with more than one browser? [10:29:55.0000] It seems it works fine in Edge :) [10:30:30.0000] It works in Firefox [10:30:53.0000] Why should I have to download another browser to attend? [10:33:45.0000] there are also desktop clients available https://desktop.jitsi.org/Main/Download [10:35:23.0000] littledan: Different regexp engines handle duplicate capture groups in different ways. May need to investigate options... [10:37:22.0000] rbuckton: Oh, that's interesting, do you know if there's a summary anywhere? [10:37:53.0000] I guess jitsi sort of works with Safari, just not with very good performance on video, right? [10:38:20.0000] littledan: I'm working on a comprehensive comparison of regexp engines, but haven't written anything up about that yet [10:38:48.0000] It seems jitsi should work on safari but just have some bugs... [10:39:14.0000] littledan: Jordan had many issues trying to make it work on Safari too :( [10:39:24.0000] :( [10:39:28.0000] littledan: when i tried it yesterday, on desktop the audio was jittery and unhearable, and on mobile it was silent [10:39:39.0000] oh, I thought that was due to video, I misunderstood [10:39:49.0000] the video quality was worse, yes, but otherwise usable [10:39:52.0000] audio was fine for me but slides wouldn't appear [10:39:56.0000] that's too bad [10:40:08.0000] Safari users, is there a video conferencing system that you'd recommend better? [10:40:13.0000] (WebEx?) [10:40:41.0000] maybe we could work together on fixing Jitsi--it's an open-source project... [10:41:38.0000] yeah, they just have very little number of contributors running Safari [10:42:03.0000] ideally, even filing in issues would be enough I think :D [10:42:14.0000] wow, we are doing awesome on time! [10:43:41.0000] we should file a bug report for that slide problem [10:43:54.0000] consensus on seeing slides [10:44:08.0000] +1 for seeing slides for stage 1 [10:44:24.0000] :P thanks we'd ask for Stage 2 next meeting then [10:50:40.0000] too many issues with jitsi [10:53:13.0000] I have two monitors, and even with jitsi fullscreen on one monitor, I keep getting a PIP window of the same slides in my other monitor :/ [10:53:52.0000] wsdferdksl: the one specific issue with visual clutter that you mentioned is something that I've felt too, and it also frustrates us when we try to record presentations over Jitsi. [10:54:14.0000] so I'll try to come up with a custom CSS hack that can toggle the controls for now [10:54:24.0000] and ask for that feature on the issue tracker to be built into the client. [10:55:28.0000] for the time-being, I usually just right click to open the inspector and turn off the elements manually. [11:02:12.0000] I am open to forgetting about species [11:06:41.0000] FYI there is a per-person volume bar in the top right corner of the person's tile [11:06:58.0000] If I could only find the person's tile [11:07:00.0000] hover over the hamburger to make it appear [11:07:19.0000] leobalter: it's the one surrounded in blue [11:07:21.0000] this presentation ought to have mentioned that `reverse` and `reversed` is already how python spells these methods [11:07:41.0000] ^ great point [11:07:43.0000] michaelficarra: I'm pretty sure it was not showing in my screen [11:07:56.0000] leobalter: it's a little subtle [11:08:12.0000] Bakkot: +1 [11:09:08.0000] michaelficarra, DR tile is not here and that didn't happen while he was speaking either. https://usercontent.irccloud-cdn.com/file/tppB37vN/Screen%20Shot%202021-03-09%20at%2011.08.13%20AM.png [11:09:38.0000] leobalter: that pane scrolls [11:10:02.0000] thanks! that should solve the problem next time! [11:10:05.0000] i'm told igalia disabled the feature where it pins whoever's talking [11:10:08.0000] blame your OS for hiding scroll bars [11:10:17.0000] that's a terrible UI decision [11:10:24.0000] yuppppp [11:10:39.0000] yes [11:10:42.0000] first things i do on any mac is to unhide scrollbars and disable "natural" scrolling [11:11:13.0000] another example of making it pretty at the expense of usability from Apple [11:12:04.0000] Not sure I asked the correct question... What I asked is it seems `let deleted = a.slice(...); let newArray = a.spliced(...)` repeat some computation. Maybe `let [newArray, deletedItems] = a.spliced(...)` ? [11:14:16.0000] haxjs: Your question was correct, it was just misinterpreted. ^_^ I've seen both patterns, I think, in other languages with non-mutating methods, and I'm not sure which I prefer. :/ [11:16:11.0000] oh I see your question now haxjs, please open an issue for spliced [11:16:17.0000] worth discussion [11:16:49.0000] tbh i don't even know if "splice" has enough use cases to warrant "spliced" :-p [11:16:59.0000] almost every time i've come across splice in the last decade or two is because someone misspelled slice [11:17:25.0000] Will we have a separate repo for these new methods? so I can create issue for that? [11:17:50.0000] I would create the issue on the Record/Tuple repo. Whatever it returns, it should return the same for both. [11:17:58.0000] jridgewell: IIFE boilerplate is a high cost. [11:17:59.0000] ljharb: not wrong but consistency [11:18:03.0000] rickbutton: right [11:18:11.0000] @rickbutton thank u! [11:18:21.0000] I have to look up splice on MDN every time I use it [11:19:20.0000] rickbutton: i _implemented_ it in es6-shim and i still can't figure out its api without a few tries [11:19:27.0000] :) [11:22:15.0000] Compared with the syntax, it's dozen restrictions, and having to learn completion values? [11:22:44.0000] I don't think there's any point to this proposal if it's just sugar. [11:22:59.0000] fwiw I care more about async do, and that one _is_ just sugar under any variant of this [11:23:22.0000] i don't think anyone has to learn most of the completion values; i think it's quite intuitive (and the weird cases should be banned or fixed) [11:23:29.0000] jridgewell: i hear that you don't find value in it. many of us do, tho. [11:24:27.0000] literally even being able to use `const` with an if/else-produced value would be more than sufficient benefit to me [11:24:59.0000] (obv there's many more benefits than that) [11:26:36.0000] /me applauds [11:28:17.0000] yeah, so I was specifically saying, I don't think it's important that study participants be able to answer the kind of question that Waldemar asks [11:35:37.0000] jridgewell do you have similar feelings about async do? [11:36:29.0000] TabAtkins: did you get an answer to your multipage question in jitsi chat? i think it's "yes" [11:36:40.0000] I didn't, but thanks! [11:36:43.0000] https://usercontent.irccloud-cdn.com/file/yUvdt4SA/Screen%20Shot%202021-03-09%20at%2011.36.29%20AM.png [11:37:05.0000] Bakkot: Yes, it's the same [11:37:20.0000] jridgewell so async do fundamentally can't allow return or continue [11:37:26.0000] since it's not executing at the same time [11:37:30.0000] btw were there any technical problems before this one? [11:37:32.0000] does that mean you're opposed to async do in general? [11:37:48.0000] ron had to restart once littledan [11:37:54.0000] @jridgewell I feel if it's not just sugar it also could bring more problems than benefit ... :) [11:37:56.0000] littledan: Only accessing the meeting! [11:38:12.0000] (we definitely had problems with Teams not supporting non-Chrome browsers in the past) [11:38:36.0000] we should just switch back to zoom, the only consistently consistent experience [11:38:39.0000] and also problems with screensharing being broken in Teams [11:38:54.0000] "back to" have we ever used Zoom? [11:39:10.0000] several companies don't allow Zoom on corporate laptops [11:39:11.0000] we used zoom like once in the start of the pandemic [11:39:13.0000] +1 for zoom [11:39:22.0000] zoom has a webview [11:39:29.0000] yep they try real hard to hide it [11:39:32.0000] my company wouldn't allow me to install any of the native chat apps, jitsi include it [11:39:37.0000] *included [11:39:38.0000] I've been reporting feedback to the Teams dev team. [11:39:48.0000] jridgewell btw the motivation for async do is basically this tweet: https://twitter.com/mcclure111/status/1336911574582386688 [11:39:58.0000] (which expresses a sentiment I feel myself on an almost daily basis) [11:39:59.0000] nice [11:40:04.0000] ^ IIFE boilerplate is an exceedingly high cost. [11:40:55.0000] So maybe IIFE sugar is just what people want... [11:41:25.0000] other people also want the nice early-return-in-matching thing that do-exprs allow [11:41:32.0000] Does Zoom work on Safari? It's not clear what problem this is solving. [11:41:50.0000] Note here if the main use case is replacing IIFE, we need to support local return, because many IIFE use early return (guard pattern). [11:42:00.0000] littledan: yes, zoom works fine on safari [11:42:29.0000] littledan: altho to be fair i don't spend much time in the web version [11:59:56.0000] is it by his own choice that he never comes to plenary? [12:00:13.0000] rkirsling: they do not work for a member IIUC [12:00:20.0000] sorry what is the difference between Fellow and Recognition Award [12:00:25.0000] oh I thought he was a mozillian [12:00:33.0000] shu: fellow is a lifetime achievement award [12:00:45.0000] and the latter is more commonly given out [12:00:59.0000] does one of them come with CHFs [12:01:19.0000] idk but probably just glass bricks [12:01:37.0000] shu: iirc a fellow can attend forever without being a member [12:01:37.0000] leobalter: thank you so much for nominating anba :D [12:01:46.0000] shu: ie, brendan and allen [12:01:47.0000] ljharb: oh interesting [12:02:02.0000] (i think they don't get a vote on votable things tho) [12:02:14.0000] they don't get a vote [12:03:01.0000] ryzokuken: I believe we can set a good example while we maintain ourselves as welcoming to André's contributions [12:03:03.0000] when did we last vote on something? [12:03:27.0000] leobalter: yes! I saw you suggesting them and was like "why did I never do this?" [12:03:34.0000] but yeah, their work is amazing [12:04:08.0000] so did the tcq reactions get hidden then? [12:04:35.0000] i think it's a good point, though, that if one of the primary benefits of an Ecma fellow is to be able to come to the meetings, and he doesn't come [12:04:43.0000] i'd rather shower him with money [12:04:44.0000] I saw them there for the first couple of presentations and then they disappeared [12:06:09.0000] msg littledan only andre is suggested as a fellow, i think [12:06:18.0000] lol forgot a / [12:08:25.0000] oh, oops, I guess I would've known that if I clicked on the slides, I was just confused, sorry [12:09:04.0000] Andre has certainly made outstanding contributions and I'd be happy to give him lots of honors [12:09:23.0000] quick point: If we're serious about `yea`/`nay`, we should ask them as independent questions rather than a single question because its hard to differentiate between them when everyone talks at once. [12:09:29.0000] tbh we set up the "Ecma Fellows" program at first because there was no invited expert system, and people at first wanted to have really high standards for this kind of thing [12:22:47.0000] the yea/nay was a spur of the moment thing, we don't have to repeat it [12:22:52.0000] i wanted to make sure people could say no [12:22:56.0000] i hope it worked [12:28:37.0000] (also was in the interest of time, really) [12:36:05.0000] littledan: you're not presenting, right, just practicing? [12:36:46.0000] Right, sorry if it is distracting [12:37:28.0000] I got worried too lol [12:38:50.0000] just panicked that i'm missing things [12:39:16.0000] nope we are starting back up in 21 mins [13:00:26.0000] To preemptively explain a question that will come up with this: "What's the difference between module fragments and module blocks" [13:00:26.0000] The way I found useful to think about is that Fragments are like Function Declarations (must have identifier) and Blocks are like Function Expressions. [13:00:38.0000] The Fragments have additional abilities the Blocks don't. [13:02:17.0000] hm, i don't hear anything [13:02:22.0000] rejoining [13:03:09.0000] (and there's an error on that slide, it should say "can't close over countBlock or uppercaseBlock") [13:03:15.0000] k, rejoining fixed it [13:04:49.0000] really, a JS app has 100k modules? [13:04:54.0000] jridgewell: thanks, that makes more sense [13:05:11.0000] shu: gmail? [13:05:25.0000] or docs [13:05:33.0000] those aren't written in JS natiely [13:05:35.0000] natively* [13:05:57.0000] shu: airbnb had 30,000 react components when i left in july 2019, and many more modules than that [13:06:03.0000] jesus [13:06:15.0000] ljharb: i see, thanks [13:06:28.0000] facebook certainly has more still if thinking about React components [13:06:42.0000] since most codebases do 1 component per moudle [13:07:10.0000] the last time i'd checked with both, airbnb had more components than facebook (altho possibly not more modules) [13:07:25.0000] (that was a number of years ago tho) [13:14:18.0000] i wonder if maybe we could use `private module` and `public module` here 🤔 [13:15:24.0000] drousso: to be that's the same problem with using those terms on class fields; JS only has "reachable" and "unreachable" [13:15:32.0000] it seems `export module` could ensure it always in top-level. And all module not exported is just "private"? [13:15:43.0000] like any other variable, yes [13:15:48.0000] (i'd assume) [13:16:04.0000] i suppose [13:16:15.0000] drousso: you mean `#module` and `module`? [13:16:33.0000] shu not really? 😅 [13:16:41.0000] shu it was an alternative to `export module` [13:16:43.0000] I like the export/un-exported distinction [13:16:45.0000] i guess also since we're already inside a module context then `export` is more understandable [13:16:48.0000] yeah [13:17:43.0000] drousso: ah okay [13:17:51.0000] what happened on `export default module #foo` ? syntax error? [13:19:51.0000] haxjs: Yes [13:20:27.0000] The exports aren't a value, so that wouldn't result in anything that could be imported [13:21:46.0000] like anything that can't appear in expression position, i'd assume so [13:21:59.0000] so does it mean `module #foo {}` actually a special thing and can only in top-level? [13:22:06.0000] Yes [13:22:24.0000] It's a module-level declaration only [13:23:37.0000] like import and export [13:23:49.0000] dan is saying that splitting into separate modules has demonstrable perf issues [13:24:15.0000] that can be mitigated by combining them into fragments [13:27:51.0000] is the idea that you can declare any module specifier or only a fragment at the containing module's URL? [13:28:08.0000] only a fragment [13:28:15.0000] should only fragment [13:28:46.0000] interesting, how does that work with other ecosystems that use non-URL module specifiers? [13:29:00.0000] like node? [13:29:05.0000] so you are declaring a subdivision (a fragment) that can be externally referenced [13:29:19.0000] yeah a fragment isn't really a thing in the node module specifier namespace [13:29:23.0000] yes it is [13:29:27.0000] oh, it is? [13:29:30.0000] package.json files can have an "imports" field [13:29:39.0000] and those are like a package-local import map [13:29:45.0000] and those all have to start with `#` [13:30:00.0000] AMP is affirmatively for this. [13:30:16.0000] michaelficarra: https://www.npmjs.com/package/has-package-imports is my detection package, which lists node versions and links to the docs [13:30:26.0000] a interesting thing is import x from './mod/lib.js#foo' maybe already work today ... not sure whether it will be any compat issue... [13:31:14.0000] littledan: I'm happy to be a lowercase c co-champion haha [13:31:22.0000] I have a lot of things on my plate though... [13:31:34.0000] So, I may or may not have a ton of time. [13:31:46.0000] yeah I think we can all bring different things to the table here so I'm happy to work with keith_miller and Mark as they're available [13:31:52.0000] and any others--there's no limit here [13:32:05.0000] ljharb: this imports thing seems unrelated to what is proposed [13:32:23.0000] michaelficarra: right but in node you can currently `import 'package-name/#foo'` and it does a thing [13:32:35.0000] Re: normalization, yes yes *yes*, it's, I think, the largest reason we can't use native Maps in the DOM. [13:32:39.0000] michaelficarra: so if package-name's "main" had an exported module fragment, there's a conflict [13:32:56.0000] okay so you're saying it's actually related in its incompatibility with that system [13:33:00.0000] correct [13:33:04.0000] I thought you were saying it worked well with that system [13:33:07.0000] @littledan Jack may be also interested in module fragment but he is sleeping now, i will ask him tommorow :) [13:33:18.0000] michaelficarra: ah no, the reverse [13:33:44.0000] can the queue be advanced? [13:33:57.0000] akirose robpalme bterlson ^ [13:34:12.0000] ty [13:34:13.0000] my b [13:34:33.0000] ljharb: This seems like a really small edge-case [13:34:56.0000] Same as in the browser. It technically already does something, but what it does is dumb, and I've never seen it used. [13:34:58.0000] jridgewell: i'm not sure how small it is, but i'm also not sure how its size makes a difference - it'd still have to be dealt with [13:35:08.0000] you've not seen it used because it's very new, and most tooling doesn't support it yet [13:35:20.0000] as for "is dumb", that's a subjective opinion i'm not sure how many will share [13:35:44.0000] wsdferdksl: can you confirm the last time we talked about this, that you'd be content with "Set can accept coerceKey or coerceValue, but not both"? [13:36:05.0000] jridgewell : "and I've never seen it used" --- not sure but someone may use it by import.meta.url ? (does import.meta.url keep fragment??) [13:36:47.0000] given that import maps can act on it, i'd hope so [13:37:30.0000] haxjs: That's great to hear, I'm a big fan of Jack's work and I'd be happy to work with him on this effort [13:40:35.0000] `import.meta.url` does include hash: https://candy-nutritious-cantaloupe.glitch.me/ [13:41:49.0000] I used searchparam via import.meta.url in some code but never test fragment, glad it also work :P [13:46:16.0000] keys and set values are both the things with uniqueness constraints. set values are not map values :/ [13:46:50.0000] Param makes sense though, since it actually causes a fetch [13:47:06.0000] Hash can't cause a fetch, but does create a new module instance, which is extremely surprising [13:50:34.0000] Some's child is speaking? Is someone other than Jordan umuted? [13:51:44.0000] shu: what would it do for a Set if it returned `[1, 2]` - which one would it select [13:51:58.0000] or are you saying that the coercer could check `arguments.length` [13:53:22.0000] ljharb: that would be ok [13:53:25.0000] What first mean here? [13:53:28.0000] wsdferdksl: thanks [13:53:31.0000] haxjs: `[0]` on the entry [13:53:55.0000] but it's an option bag? [13:54:07.0000] but i assume shu is suggesting `function coerce(...args) { if (args.length === 1) { /* set */ } else if (args.length === 2) { /* map */ } }` [13:54:25.0000] oh?? [13:54:40.0000] keith_miller: the same function could still return different results for both calls [13:54:47.0000] keith_miller: which would be nonsensical on a Set [13:55:14.0000] ljharb: I just mean for Set if they are the same you would call the function once [13:55:42.0000] keith_miller: right, but then the coercer fn would have to know that's the case, where it might be expecting one call for key and one for value [13:55:58.0000] well, I mean that's a bug I guess [13:56:04.0000] could pass a "type" [13:56:18.0000] although you have to name the type :/ [13:56:22.0000] yup [13:56:31.0000] I dunno, that seems like an unusual use case [13:56:34.0000] I thought shu was suggesting something like: [13:56:34.0000] ``` [13:56:34.0000] function coerce(entry, kind) { [13:56:34.0000] if (kind==="key+value") { /* map, entry is [key, value] */ } [13:56:34.0000] else { /* set */ [13:56:35.0000] } [13:56:35.0000] ``` [13:56:36.0000] Seeing as how we use `key+value` for map iterators [13:56:50.0000] ah true, that would work too [13:56:51.0000] ljharb: I would generally expect the coercer function to be pure [13:56:59.0000] keith_miller: as would i, but, javascript [13:57:06.0000] haha yeah fair [13:57:14.0000] ljharb: if maps and sets are the only collections in your universe of collections, sure [13:57:35.0000] Not sure we should design around all possible things JS programmers could do though [13:57:37.0000] the important thing was just: use positional parameters that match the positions to the set/add/whatever function that actually adds new entries to the collection [13:57:38.0000] and ignore names [13:57:41.0000] right [13:58:18.0000] so a 1-ary coercer could be used for Arrays and Sets [13:58:24.0000] but that kind of reuse is probably nonsensical [13:59:01.0000] Yeah, IMO the return being an Array makes me :( [13:59:08.0000] to avoid the Array allocation issue, you can provide an array of coercers [13:59:15.0000] [coercer_for_param1, coercer_for_param2] [13:59:19.0000] O.o [13:59:35.0000] that's no different than { coerceValue, coerceKey }, right? just not named [14:00:00.0000] That's fair although I think it will have the same issue that the Map iterator has [14:00:07.0000] what's that? [14:00:07.0000] does that mean you need to pass [coercer] for a Set? [14:00:14.0000] rickbutton: yes, i'd say so [14:00:32.0000] but that's only at Set creation time, which should be much rarer than actually using the Set [14:00:32.0000] ew for the same reason as returning [newValue] from a Set coercer [14:00:34.0000] then you couldn't reuse the same options bad for a map and a set tho, which was the original complaint [14:00:48.0000] ljharb: why can't you? [14:01:00.0000] ljharb: you can pass an array with more coercers than will be used, the rest can be ignored [14:01:04.0000] ohh i see what you mean [14:01:10.0000] ok, sure [14:01:25.0000] it works for waldemar because it so happens that the "key" of the set is the only param, and the key for Maps is the 1st [14:01:37.0000] but there's no "deep" reason, it's just the order they appear [14:02:44.0000] shu: If you do map.entries() you get [key, value], which is mostly annoying because destructuring uses array iterator [14:02:45.0000] would be nice for `Map` tho if there's a way to coerce both the key and value at the same time (i.e. coerce the value based on the key) [14:03:16.0000] drousso: well, the current proposal falls short there too, right? [14:03:33.0000] yeah [14:03:42.0000] keith_miller: yeah, but you do that iteration protocol presumably once, at creation time [14:03:44.0000] so maybe it's ok [14:03:56.0000] Yeah, it's probably fine [14:03:59.0000] im still not really convinced of the need/benefit of this over just modifying `map.set = function() { ... }` [14:04:05.0000] but i don't have a strong opinion [14:04:10.0000] oh don't monkeypatch bro [14:04:12.0000] drousso: use subclassing!! [14:04:15.0000] no [14:04:16.0000] or subclassing [14:04:16.0000] no [14:04:17.0000] nooo [14:04:34.0000] we really need to have a conversation about how we expect subclassing to work in this language… [14:04:51.0000] i'll extend that sentiment, yes [14:04:53.0000] might be a relevant topic for this proposal [14:05:15.0000] and the previous topic [14:05:15.0000] I expect it to work how I want to use it in the current circumstance :P [14:05:19.0000] shu: what a derived joke [14:05:49.0000] Wait are we against subclassing now? [14:05:54.0000] ^ +1 [14:05:58.0000] seriously though, I don't think we can make progress on some of these proposals without that conversation first [14:06:07.0000] One thing I've considered proposing is providing a way to control equality in a Map/Set (essentially via `{ equal(a, b) { ... }, hash(a) { ... }`), which would only operate on the runtime value that determines existence in the collection. For a `Map` that's only ever the key, for a `Set` that's the key/value. As much as I'm in the camp of "A `Set` stores unique *values*", the similarity with how keys are [14:06:07.0000] treated in `Map` and values are treated in `Set` is making me lean towards using `{ coerceKey }` for `Set` (where "key" means "the runtime value compared to other runtime values to indicate presence in the collection") [14:06:23.0000] michaelficarra: but that didn't answer my question lol [14:06:40.0000] keith_miller: no, we just don't have a good way to do it [14:06:54.0000] in what sense? [14:07:13.0000] see the Set methods proposal and our last discussion there [14:07:39.0000] do you mean in the spec? [14:07:46.0000] or for end users? [14:07:50.0000] do we make some core API that all operations observably go through? [14:07:52.0000] for end users [14:07:56.0000] keith_miller: i am against subclassing, yes [14:08:00.0000] how we design built-ins to support subclassing [14:08:06.0000] keith_miller: yulia and i have that proposal to kill subclassing [14:08:10.0000] shu: same, but that's different [14:08:19.0000] I guess most end users think Set only have value, no key... [14:08:41.0000] I think of sets as only having keys lol [14:09:07.0000] i.e. it's Map [14:09:10.0000] ^ same but that's why we have both aliased [14:09:11.0000] i think of sets as having keys, yes [14:09:15.0000] keith_miller: `Set.prototype[Symbol.iterator].name` disagrees with you [14:09:16.0000] sets have "elements" which are analogous to map keys [14:09:46.0000] keith_miller: also `Set.prototype.keys.name` [14:10:08.0000] ljharb: those were arbitrary choices and you know it [14:10:09.0000] lol [14:10:14.0000] perhaps so [14:10:32.0000] if we had considered that future committee might base a decision on it, we definitely would have made keys the canonical one [14:10:33.0000] but i also don't agree with the mental model that set elements are analogous to map keys (altho i recognize it's a valid model) [14:10:34.0000] Not if I do Set.prototype.keys.name = keys [14:10:50.0000] `Set.prototype.keys.name = "keys"` [14:10:51.0000] a Set is a list. that it has O(1) lookup doesn't make it have keys ¯\_(ツ)_/¯ [14:11:08.0000] ljharb: it's unordered, so it's a bag [14:11:13.0000] in JS it's quite ordered [14:11:13.0000] with uniqueness [14:11:23.0000] sure, JS sets are ordered [14:11:26.0000] it's not a list because it's unique [14:11:33.0000] yeah, it's definitely ordered in JS, which we should reconsider because memory [14:11:35.0000] uniqueness = not a list [14:11:49.0000] maybe needs to be a different type tho [14:11:51.0000] sure, but conceptually i think most JS devs think of sets as having values. [14:11:55.0000] I mean in math sets have elements, and if you don't use a Set, then you effectively use a Map [14:12:13.0000] certainly there are domains where that mental model is the one that makes sense [14:12:19.0000] so there's no precedent for calling them values, but it's also not to say that it's awkward to call them values [14:12:31.0000] i mean, the vox populi can also be wrong [14:13:42.0000] very true, but we still chose not to say mean things about ASI :-p [14:14:08.0000] maybe not in the spec but I'll subtweet ASI all day [14:14:52.0000] we shouldn't shame people for disagreeing with us but we can still take positions on things [14:15:21.0000] sure. but i don't think we're going to get consensus on a position that "sets have keys" [14:15:30.0000] agree with ljharb :P though i also understand why professional programmers would agree it's key ... hard to say which side is much "correct" :-P [14:15:54.0000] JS devs are professional programmers too. [14:16:12.0000] neither is more correct, words have no meaning, the goal should be to satisfy the expectations of the developer (on average) [14:16:42.0000] keith_miller: btw this topic that Mark is asking about is exactly what I was talking about earlier [14:16:58.0000] I missed it... [14:16:59.0000] I mean given that we chose not to call it `elements`, it made sense to have `values` alias `keys` [14:17:04.0000] keith_miller: uggghhhh [14:17:20.0000] sorry! [14:17:22.0000] ...and it's fine that it's actually the reverse, _so long as_ we never require a user to know that [14:17:44.0000] rkirsling: the "so long as" isn't something we have consensus on either :-) [14:17:45.0000] ljharb: sorry, i mean senior devs may be more sensitive to some semantic attribute like "unique", so think it as key. [14:17:53.0000] keith_miller: whether you extend functionality by overriding some "core" set of methods or having to override every method, including any new ones added later [14:18:03.0000] ah yeah [14:18:07.0000] there are pros and cons to each [14:18:12.0000] and we go back and forth constantly [14:18:13.0000] haxjs: perhaps. but i also know plenty of senior devs who think of it as having values. seniority doesn't require familiarity with advanced math concepts. [14:18:22.0000] true lol [14:18:53.0000] ljharb: honestly it's probably more about formal education than years of experience [14:18:58.0000] perhaps so [14:19:06.0000] I refer back to "words have no meaning" [14:19:07.0000] certain things, especially naming, are just passed down that way [14:19:11.0000] seniority and professionalism also do not require formal education. [14:19:11.0000] agree [14:19:25.0000] we should just pick random strings whenever this comes up [14:19:26.0000] seniority seems irrelevant in this conversation [14:19:30.0000] echo pwgen >> spec.emu [14:19:31.0000] right [14:19:32.0000] ljharb: sorry it's hard to express my meaning in accurate english word due to my poor english level... [14:19:45.0000] haxjs: nah i think i got what you meant! just wanted to clarify :-) [14:20:00.0000] words have so many meanings what you talkin about [14:20:14.0000] but yeah i think both are valid mental models. [14:22:21.0000] Yeah I think keys vs values comes down to whether you took a bunch of abstract math clases [14:22:32.0000] before learning to program [14:23:09.0000] or well, just intro to discrete math really [14:23:11.0000] at least that's probably why I see set as a typedef of Map [14:23:18.0000] discrete yeah [14:23:20.0000] that's what I meant lol [14:23:21.0000] but whether you've learned what a set is in school [14:23:59.0000] and yeah "unit" would be more correct, I'm just thinking of it in terms of like [14:24:26.0000] from a purely JS standpoint, even after Set was first available, it was still more common to do like [14:24:36.0000] yeah Unit is correct, I saw both Void and Boolean earlier and refrained from commenting [14:24:37.0000] `{ key1: true, key2: false }` [14:24:45.0000] err [14:25:11.0000] `{ key1: true, key2: true }` [14:25:12.0000] I tend to support jordan's solution, allow any of it, but if provide both for Set, and not the same function reference, throw error... [14:25:32.0000] my fingers keep making weird typos today [14:26:36.0000] Ooops, PLAIN date again? It's previous discussion decide to drop "plain" prefix? [14:26:47.0000] Isn't [14:27:09.0000] it's been PlainDate for awhile i think [14:27:57.0000] https://github.com/tc39/proposal-temporal/issues/1072 [14:28:01.0000] So I miss that part... don't remember it been talked in the meeting, maybe I was sleeping in that meeting?? [14:28:32.0000] i doubt it was talked about in the meeting [14:30:07.0000] I am in favor of just outright dropping subclassing support from this proposal [14:30:12.0000] of all kinds, not just species [14:30:17.0000] agreed ^ [14:31:11.0000] until we have better motivation for it and a better plan for extensibility of built-ins in general [14:31:12.0000] though it's solely a bikeshed issue ,but I feel it's not very common to subvert previous decision without discussion in the plenary. [14:32:23.0000] Oh it seems the decision is based on twitter counts? 🤪 [14:33:13.0000] I remember many delegates don't like such thing? [14:38:11.0000] littledan: agree that it's unfair to put it all on Temporal; but when the existing pattern is "sometimes" i don't think it's a stretch to claim it's inconsistently applied [14:38:26.0000] regexp... regexp is the worst lol [14:38:28.0000] Bakkot: yes, ofc me too [14:38:49.0000] especially because it's a group of classes all interacting [14:38:51.0000] I think there's a good argument for this proposal being unique in this regar: it is a collection of classes [14:38:53.0000] yeah, that [14:39:02.0000] right [14:39:02.0000] anyway that's my queue item up next [14:39:03.0000] I'm very happy we're at least starting this conversation right now [14:40:01.0000] like, beaming [14:40:18.0000] and everyone is being very thoughtful and respectful :-) [14:40:27.0000] Bakkot: do you mean like, "throw if `new.target` isn't the base class"? [14:40:58.0000] i think that part is "fine" [14:41:08.0000] which part [14:41:11.0000] but i want methods to just do Construct(%Temporal.Foo%) [14:41:27.0000] right but that would mean we couldn't add subclassing later, if that's what we decide to do [14:41:36.0000] ljharb: i was saying the fact that you can type "new (class foo extends Temporal.Foo {})" and doesn't throw seems "fine" [14:41:37.0000] because people would have made subclasses and relied on it producing a base class instance [14:41:49.0000] ljharb: I don't think our pattern is "sometimes". We have different analyses of what JavaScript has right now. You were conflating protocols and implementations in your listing. [14:41:51.0000] whereas if it throws, then nobody can have possibly made a base class until we're ready to let them [14:42:05.0000] ljharb: DOM heavily depends on that kind of subclassing [14:42:10.0000] the magic method instance creation, not so much [14:42:14.0000] shu: right but temporal isn't dom [14:42:25.0000] littledan: hm, ok. surely worth trying to get all of us on the same page about that analysis [14:42:27.0000] yes, that's true, and part of Bakkot's argument [14:42:38.0000] I'd be up for removing @@species in Temporal, but there's a ton of other stuff going on in the TimeZone and Calendar protocols... [14:42:48.0000] littledan: if i can be made to understand that there is in fact a currently applied consistent mental model then that would be really helpful [14:43:02.0000] well, I mean, we discussed it last meeting; I'm not sure what more to discuss [14:43:16.0000] people proposed new possible changes, but I described what we do today [14:44:08.0000] let's find a time to discuss offline; what you described in the last meeting isn't a consistent model to my understanding, so perhaps there's something i'm missing [14:46:06.0000] ystartsev: I think the "cautious" route is actually not supporting any kind of extensibility until we have a clearer plan [14:46:25.0000] ystartsev: i also think the cautious route isn't actually web compat [14:46:27.0000] wait, no [14:46:28.0000] it's fine [14:46:41.0000] ystartsev shu: to be clear I was only making an argument for what we should do with _this_ proposal, not for other cases, so there's no potential web compat issue [14:46:48.0000] right, yes [14:47:11.0000] wait, it can't be a SyntaxError [14:47:18.0000] it can be a TypeError or something [14:47:23.0000] tbf i am multitasking so i was a bit surprised by the question. I need to think about it more, and don't have a confident answer yet. [14:47:24.0000] I don't understand, what syntax error? [14:47:32.0000] misunderstanding sounds like [14:47:33.0000] runtime error [14:48:01.0000] I would kind of lean towards not making it an error but only very weakly [14:48:17.0000] Can I ask how to make it runtime error? [14:48:22.0000] i want extends to work, still, but i don't really have a good reason [14:48:40.0000] haxjs: you say "if new.target is not [the right thing], throw" [14:48:40.0000] I started a broader thread about hooks and optimizability, to speak more to Yulia's point. I really think that it will be hard to make the more non-trivial tradeoffs (beyond @@species) in the air, and it's better to make the tradeoffs in the context of an implementation that is developed. https://github.com/tc39/proposal-temporal/issues/1432 [14:49:16.0000] haxjs concretely, see step 1 of https://tc39.es/proposal-temporal/#sec-temporal.plaindate [14:49:31.0000] littledan: let's separate the "hooks is the future" thread and the "how possible is Stage 3 for Temporal that removes all subclassing and have no hooks" [14:49:33.0000] it would change to `If NewTarget is not %Temporal.PlainDate%` [14:49:35.0000] I kinda feel like we might as well let extends work, just not do anything in particular to make it work *well* (like use the constructor of instances) [14:49:43.0000] shu: i would argue that extends doesn't work, if methods don't produce subclass instances [14:50:31.0000] Intesting, but could people still use old ES5 way to make it work? [14:50:42.0000] Ujjwal just answered Richard's question [14:50:52.0000] haxjs no, these can't be called without `new` [14:51:02.0000] or, maybe I don't know what you mean by "the old ES5 way" [14:51:09.0000] isn't the answer that "stage 3 is not 'ship' it's 'implement'"? [14:51:13.0000] haxjs: `new.target` works the same way in ES5 constructors, and can constrain them the same [14:51:15.0000] rickbutton: it's both [14:51:24.0000] yeah, it has to ship before stage 4 [14:51:26.0000] rickbutton: no, we usually mean ship [14:51:55.0000] do we mean ship behind flag or ship unflagged? [14:51:55.0000] rickbutton: engines are free to ship without a flag immediately once it hits stage 3, and are encouraged to do this quickly (not necessarily encouraged to lack a flag, ofc) [14:52:02.0000] ok [14:52:03.0000] rickbutton: stage 4 requires 2 unflagged [14:52:06.0000] depends on the proposal, but we usually want web compat feedback, not just implementability feedback [14:52:17.0000] right, makes sense, thx [14:52:53.0000] I mean u can just get the instance, change the prototype? [14:53:04.0000] rickbutton: in general any time there's an observable change after stage 3 advancement, it's either motivated by web compat, implementability, or we should have caught it before stage 3 [14:53:24.0000] haxjs: sure, but that's fine, that's not proper subclassing [14:54:43.0000] "we should have caught it before stage 3" --- what if we failed to caught it ? [14:55:07.0000] I'm also thankful that the champions chose an appropriate timebox for this topic [14:55:13.0000] haxjs: then we may, or may not, be able to change it [14:55:30.0000] haxjs: but that's why the risk of that kind of changes is supposed to be effectively zero before stage 3 advancement [14:56:03.0000] rickbutton: "shipped" simpliciter usually means "unflagged" [14:56:19.0000] 👍 [15:00:12.0000] did they think they had to define a total ordering? [15:00:16.0000] a partial ordering seems fine [15:01:04.0000] Bakkot: https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html says "It is strongly recommended (though not required) that natural orderings be consistent with equals." [15:01:28.0000] ljharb: partial ordering can still be consistent [15:01:30.0000] iow yes, it's not required there, but it's also not "wrong" [15:01:44.0000] ljharb it also says "One exception is java.math.BigDecimal, whose natural ordering equates BigDecimal objects with equal values and different precisions (such as 4.0 and 4.00)." [15:01:48.0000] sure [15:01:51.0000] which is exactly this case: [15:02:00.0000] the points are the same on the line in question, they just have extra data [15:02:08.0000] so the sort the same, but are not equal [15:02:10.0000] Bakkot: ftr i think your example is very compelling, where sorting would give you the wrong timeline order. [15:02:12.0000] *they sort the same [15:02:26.0000] and obviously you can write all sorts of comparators that return 0 for two unequal things [15:04:11.0000] yeah I mean it is true that it is usually a good idea for them to agree [15:04:38.0000] just that it isn't a hard requirement, and I think that cases like this are exactly where the requirement should be violated 2021-03-10 [09:39:55.0000] The Jitsi room is open. Let me know if you have trouble joining or any other technical issues [10:00:14.0000] were we not continuing the Temporal topic today? [10:01:33.0000] looks like it's on the draft schedule for after lunch [10:01:45.0000] (due to schedule constraints requiring some of these things being in the morning) [10:02:22.0000] correct [10:13:54.0000] +1 on being explicit, precedence is the devil when working in new spaces like this [10:18:38.0000] I didn't realise this proposal would integrate with sequence properties like this [10:18:42.0000] it seems really hazardous [10:19:35.0000] Oooh I was hoping that someone would propose "Just add a gd parser proposal", nice [10:20:00.0000] i'm behind a built-in parser-combinator library, even if it's just regex equivalent right now [10:23:03.0000] TabAtkins: it's not like parser combinator libraries are big, you can just ship one [10:24:00.0000] Of course, but regexes are built in. If we want to ensure people have the same power, without forever extending regexes to ever more intricate syntax, we need to match the built-in-ness. [10:25:01.0000] I mean, right on this topic - union/intersection/etc is very easy to apply in a parser combinator, but we're adding it to regex bc that's what we have in the language. [10:28:27.0000] I have a lot more regexp syntax features I plan to propose in the future, all based on prior art in other languages and have been putting together a comprehensive comparison between all major regexp engines. [10:32:09.0000] someone fill out the header in the notes please? [10:39:46.0000] ljharb Bakkot thanks! Somehow I thought we should be assigning reviewers as well. [10:39:49.0000] Error causes is speedrunning proposal advancement :D [10:39:56.0000] mmarchini: [10:39:58.0000] oops [10:40:06.0000] leobalter: at this point the only reviewers are test262 maintainers and 262 editors :-) [10:40:25.0000] mmarchini: I saw things going so much faster this seems a okay pacing [10:41:14.0000] Yeah that's the first proposal I saw reach stage 3 on the third meeting [10:41:32.0000] But wouldn't be surprised by faster ones [10:41:42.0000] omigod this is such a better name [10:43:03.0000] jridgewell: oof, how does amp depend on that? [10:43:24.0000] Part of amp-script exports blessed functions on a global [10:43:34.0000] Doing something like `exports[fn.name] = fn` [10:44:20.0000] and amp-script is deployed on user-controlled sites? [10:44:54.0000] Yes [10:45:07.0000] bummer, ok [10:45:09.0000] We could update, but it's just the web compat risk is real [10:45:24.0000] right [10:45:41.0000] seems ideal for amp-scripts to update to not rely on function names in general, but doesn't remove the compat risk. [10:53:28.0000] I definitely read "race" to be "scary" [10:53:31.0000] I know not everyone does [10:53:33.0000] but I sure do [10:53:39.0000] agree [10:54:32.0000] or if not "scary" it's at least an "eff it, who cares what happens" vibe [10:55:35.0000] to me "any" gives that vibe [10:55:42.0000] do we have an acronym for this presenter? [10:56:30.0000] someone has written "WWG" so I assume that's right [10:57:53.0000] Bakkot: we don't, so we should ask them to add an entry to delegates.txt at the end of the topic [10:58:00.0000] I have done so [10:58:07.0000] WWG is someone else I think, fwiw :( [10:58:26.0000] should be WWL as his name [10:58:45.0000] https://github.com/tc39/notes/pull/97 [10:59:54.0000] remember to assign reviewers! [11:00:17.0000] Bakkot: it's KWL in case you missed this :-D [11:02:33.0000] is Wenlu or Daniel R. in this channel? I tried many times to volunteer as a reviewer, but I was double muted [11:03:11.0000] leobalter: i don't think either is, but i think maybe robpalme could interject briefly to add you as a reviewer after this presentation? [11:03:38.0000] sure [11:04:14.0000] robpalme: leobalter: I've let wenlu know you cna review [11:04:38.0000] (i think it still needs to be in plenary notes tho) [11:05:43.0000] ljharb: I'll reach them through the proposal repo [11:05:47.0000] bterlson: thanks! [11:06:16.0000] ljharb: I can do it informally, unless we need 3 reviewers [11:13:23.0000] leobalter: we prefer to have 2 non-editor reviewers, so it is welcome [11:14:19.0000] Jordan and Yulia are already assigned, I'd be the 3rd one. [11:17:56.0000] oof, reading the length as a way to explicitly synchronise? [11:19:41.0000] there must be a better way to communicate that intent [11:59:39.0000] yay pipeline! [12:18:38.0000] gotta run an errand. I expect to be back in time but if not I've set the bot to start itself up again in 30 minutes [12:54:08.0000] ok back we're good [13:17:20.0000] These slides are great [13:20:49.0000] well I wish the colours for the different execution orders weren't basically identical [13:24:01.0000] It's a breadth-first upwards traversal [13:25:41.0000] what was shu saying? "a serial"? [13:25:58.0000] /me /shrug [13:26:34.0000] a serial, yes [13:26:41.0000] like a monotonic increasing number [13:28:10.0000] Is this any more difficult than changing a depth-first to a breadth-first? [13:33:03.0000] jridgewell: yes [13:34:44.0000] How so? [13:35:25.0000] jridgewell: i might've misread your question, now i no longer know [13:35:32.0000] maybe after this preso [13:35:41.0000] 👍 [13:40:35.0000] https://usercontent.irccloud-cdn.com/file/iqZfwHob/queue.png [13:40:44.0000] ^^ saved temporal queue [13:44:06.0000] btw the slides were prepared based on the old queue already [13:45:26.0000] littledan: objection to going through the replies to make sure the questions are answered? [13:45:44.0000] no, no objection [13:47:57.0000] so noted :-D [13:49:24.0000] I just realized there's two temporal champions speaking [13:49:26.0000] I don't know which they are [13:49:32.0000] I've been attributring everything to PFC in the notes [13:49:47.0000] if someone knows who the speakers are please help fix up the notes [13:51:40.0000] phillip dunkel and phillip chimento [13:51:49.0000] the one who just talked to mark is dunkel [13:52:03.0000] oh jeeze there's two phillips [13:52:10.0000] which one is now? [13:52:26.0000] philip chimento is the main speaker [13:52:57.0000] within the champion group, they can be differentiated by ptomato vs pdunkel, or alternatively, Philip vs Philipp [14:15:10.0000] definitely agree with haxjs that the original naming issue should've been bumped [14:15:28.0000] not the end of the world, it's hard to keep track of these things, just something for people to try to be aware of in the future [14:15:34.0000] that's what i heard as well; not really about twitter, but about notification of changes [14:16:02.0000] Yeah, it make me too late to back to the discussion. [14:16:08.0000] and tbh it's tough to follow the entire repo when the majority of the activity isn't directly related to the spec [14:17:39.0000] Another point is the poll sample is too small, if we want to do poll to get some data, we need a guide to make sure we do the poll in right way. not like that. [14:25:15.0000] FYI: "Hack" style refers to the Hack programming language: https://docs.hhvm.com/hack/expressions-and-operators/pipe [14:25:19.0000] "Tab's Essay" is https://gist.github.com/tabatkins/1261b108b9e6cdab5ad5df4b8021bcb5 [14:26:42.0000] wish "hack style" were called "topic variable" instead [14:27:05.0000] too late now ofc [14:27:08.0000] "topic style" [14:27:45.0000] Most fp guys (i mean who use lodash/fp or ramda or similar libs) i know prefer F# style much than topic style... [14:28:45.0000] haxjs: Well obviously ^_^ [14:28:52.0000] But guys who not heavy fp guys sightly prefer topic style --- this is what i found. [14:29:07.0000] Bakkot: I pushed for the "Lang-style" naming to avoid the value judgement of "minimal proposal" [14:29:13.0000] i believe most JS users are not "heavy FP users" [14:29:52.0000] "version that explicitly privileges higher-order programming over all other syntax" is popular with people who like using higher-order programming heavily, news at 11. ^_^ [14:30:01.0000] I am still very bullish on partial application and its value with or without pipeline. [14:30:33.0000] moreover "heavy FP users" is not the same thing as "heavy users of FP within JS" [14:30:53.0000] Would you need to await all the rest of the operands of |>? [14:31:11.0000] nope, no more than you'd need to await all following statements in normal code flow [14:31:11.0000] We have another choice, let avg user use extensions like `x :: extMethod()` and let heavy fp users use F# style pipeline op. Both will happy. [14:31:39.0000] The :: as this-piping operator is even worse :( [14:31:41.0000] haxjs: average user use is more likely to be in between those - not heavy FP, but also not this-using [14:31:50.0000] What does x |> await do? [14:31:57.0000] for what its worth, `(await (x |> f)) |> g` is no less complex than `(await x.f()).g()` [14:32:17.0000] wsdferdksl: it's a special form that awaits the input and passes it to the output [14:32:27.0000] wsdferdksl: same as `await x`? [14:32:32.0000] ljharb: extensions is designed to make avg user not worry about `this` anymore. [14:32:55.0000] `x |> f |> await |> g` is equivalent to `(await (x |> f)) |> g` [14:32:55.0000] With `x |> await |> y` being `y(await x)` [14:33:26.0000] haxjs: right; there's an open issue where we're discussing that, and it is very much not clear that there's consensus on the motivation for that [14:34:00.0000] haxjs: iow, the original bind operator was about being able to easily use this-sensitive functions in a chain without installing properties, which doesn't obviate the need to know how `this` works [14:34:37.0000] I've always argued F# pipes are fairly simple `x |> F` is essentially `F(x)`, and that partial application dovetails into that well. [14:34:37.0000] it's not possible to "omit placeholders initially" though...? [14:34:54.0000] rkirsling: in the F# one i think it is [14:34:59.0000] rkirsling: but not in hack, obv [14:35:00.0000] placeholders are the more basic proposal though I mean [14:35:11.0000] ljharb: yeah, the original bind op still need user know too much about `this`. So I try to find some way to solve that in extensions proposal. [14:35:17.0000] F# without placeholders would block hack-style. [14:35:31.0000] s/F#/F#-style [14:35:49.0000] haxjs: right, but that's not something i consider a problem (and thus not something to be solved), but i have a strong need to be able to chain methods on a receiver without having them present on the object :-) [14:36:05.0000] rbuckton how so? [14:36:14.0000] rbuckton assuming hack-style has a requirement that `?` appears on the RHS [14:36:25.0000] To avoid easily mistakes, Hack-style requires a placeholder, yeah. [14:36:53.0000] oh no robot [14:36:56.0000] Bakkot: IIRC, hack-style doesn't support point-free? That's where "smart mix" came from [14:37:12.0000] rbuckton right [14:37:36.0000] so it doesn't overlap with F# without placeholders, right? [14:37:47.0000] If this feature will ever move forward, we need to pick one direction. [14:37:54.0000] oh, sure [14:38:06.0000] I thought you meant that it was technically impossible, not that it was a bad idea [14:38:09.0000] Bakkot: I'm not sure what you mean about it doesn't overlap. [14:38:20.0000] ljharb: yes, extensions also can achieve that. The only point here is extensions is optimized more for oo-style (like lodash) and pipeline op is (i hope) optimized more for fp-style (like lodash/fp). [14:38:29.0000] rbuckton: like, technically, you can disambiguate them, yes? [14:38:46.0000] not "is it a good idea to have both", just, technically I don't see a problem disambiguating [14:38:57.0000] haxjs: most of the use cases i have or have seen in codebases for pipeline aren't point-free (ie, the FP unary function style) [14:39:13.0000] can you use the placeholder more than once in the RHS? [14:39:16.0000] F# actually allows multiple arguments in pipes, but we didn't propose that yet. [14:39:25.0000] (if ever) [14:39:42.0000] michaelficarra: in Hack or in partial application? [14:39:44.0000] michaelficarra: sure, 'cause you're never subbing two different things [14:40:29.0000] in Hack [14:40:48.0000] ljharb: point-free style guys bascily use a very special libs like ramda so how common u see such code depend on whether u are a ramda or lodash/fp fans :) [14:41:06.0000] haxjs: right - i'm saying i don't find "usage of ramda or lodash/fp" very common [14:41:14.0000] haxjs: obv that's just my personal experience [14:41:18.0000] I echo the confusion that Tab is expressing [14:42:14.0000] ljharb: But I feel many strong supporters of pipeline op are coming from that world. [14:43:11.0000] I don't see how it can possibly be argued that F# is simpler [14:43:16.0000] regardless of which you prefer [14:43:20.0000] To me, "Hack-style" doesn't add any new capability to the language we don't already have, which decreases its motivation to me. [14:43:40.0000] rbuckton: neither does partial application [14:43:43.0000] rbuckton: F#-style doesn't either. They're both identical in terms of expressiveness. [14:43:54.0000] literally 100% identical (so long as `await` is handled by F#) [14:44:02.0000] (and yield) [14:44:12.0000] I've already shown you can do "Hack-style" in JS today with `,`. I like F# because it adds something new. [14:44:25.0000] (again, I meant F#-style) [14:44:27.0000] rbuckton: only with intermediate variables [14:44:36.0000] rbuckton: or am i missing something [14:44:39.0000] It's not about expressiveness, it's about developer experiences... [14:44:48.0000] these are all just sugar [14:44:48.0000] rbuckton: also because of the declaration, it can't be done in one line [14:46:15.0000] I disagree that partial application doesn't add anything new. We have `.bind` and arrow functions, but `.bind` only supports leading arguments, and arrow functions defer evaluation. [14:46:56.0000] `add(?, x())` returns a function where the result of `x()` has already been evaluated and bound to an argument. Doing that today requires a lot more boilerplate. [14:47:09.0000] rbuckton: yet it's capable today, thus, it's not a new ability, it's just sugar. [14:47:30.0000] rbuckton: i'm not arguing against partial application, i'm arguing against "not a new capability" as making a syntactic proposal less useful or important. [14:47:33.0000] (inherently) [14:51:18.0000] Seen many LINQ in JS approaches. It's more than just threading fwiw, you often want to assemble some kind of query plan that can be send wholesale to the database to execute. [14:52:30.0000] bterlson: yeah, i find it compelling, especially the "it's only a burden to have to think about what to name the subparts of the query" [14:52:41.0000] the query is somehow this indivisible thing mentally [14:52:57.0000] a big part of this story fwiw is how to send simple predicates to the server [14:53:04.0000] that is maybe a key capability we should investigate [14:53:16.0000] what's meant by "send simple predicates to the server?" [14:53:39.0000] so I see linq-like syntaxes like [14:53:58.0000] query.select("x, y").where("x > 10") [14:54:54.0000] the problem they are trying to solve here is to let the server handle any projection and filtering so you don't send way more data to clients than you need [14:54:54.0000] that was mark's whole project with the deferred send thing, or whatever it was called [14:55:04.0000] C#'s LINQ relies on type information, where if you pass an arrow function to an argument expecting a specific type, the compiler returns an "Expression Tree" which is a simplified AST representation of the arrow function that can be converted into, say, a SQL WHERE clause. [14:55:06.0000] yeah LINQ is something totally else [14:56:03.0000] TabAtkins: the implementation certainly is a different beast, but isn't that usage pattern generally what you want to enable? [14:56:07.0000] bterlson: i see, thanks [14:56:31.0000] I don't even know what LINQ's usage pattern really is. [14:56:35.0000] I'm always concerned that introducing topic variables introduces scoping complexity. [14:56:45.0000] TabAtkins: essentially generator comprehensions [14:57:01.0000] I just want linear code flow, like what method chaining gives me. [14:57:01.0000] TabAtkins: my very surface understanding is that it's the database query equivalent of parser combinators, kinda [14:57:03.0000] a topic variable does mean that one pipeline nested into another is tricky [14:57:08.0000] using `FLWOR`-like syntax. [14:57:20.0000] Yeah, nesting pipelines is a "don't do that" sort of thing honestly [14:57:29.0000] "doctor it hurts when I do this" [14:57:39.0000] the answer used to be "don't do this" [14:57:46.0000] the answer now sometimes is "you have gotten older" :(( [14:58:10.0000] shu: too real [14:58:12.0000] ``` [14:58:12.0000] let result = [14:58:12.0000] from x in ar [14:58:12.0000] where x.foo > 1 [14:58:12.0000] orderby x.bar ascending [14:58:12.0000] select x.baz; [14:58:12.0000] ``` [14:58:16.0000] "as a language gets older, it starts getting painpoints in places that used to be fine" [14:58:23.0000] lol [14:58:25.0000] ohno [14:59:02.0000] I mean I want to say it's as simple as "if your expression requires parens, you should be breaking it up" but [14:59:11.0000] I know that it's easy to find counterexamples [14:59:38.0000] So many Justins now. [14:59:41.0000] rbuckton: Don't forget the `limit 100`. [15:00:36.0000] wsdferdksl: i once forgot to limit 10000 or on https://httparchive.org/ query, ran up a several hundred dollar gcp bill :( [15:00:43.0000] luckily it was free as a googler, but still [15:01:10.0000] bterlson: Do you know if the 2021 opt out period has started? [15:01:21.0000] msaboff: it has [15:01:22.0000] msaboff: theoretically it began yesterday [15:01:37.0000] For how long? [15:01:38.0000] istvan said today or yesterday right [15:01:43.0000] We need published ECMA documents for the opt-out period [15:01:50.0000] right, pending that [15:01:55.0000] msaboff: 2 months i believe [15:02:01.0000] msaboff: ends May 10 [15:02:15.0000] When do we think the ECMA documents will be published? [15:02:26.0000] June 22 is the GA date [15:02:29.0000] they said they were published today [15:02:35.0000] the opt-out ones, anyway [15:02:42.0000] Thanks [15:02:46.0000] I am still always *so curious* what people mean when they say Hack-style looks more implicit. What magic are y'all thinking is happening? [15:03:13.0000] I'm fully over in the "too knowledgeable to understand first-learners" camp now unfortunately. [15:03:15.0000] yeah, "explicit" is the definition of what Hack-style is [15:04:57.0000] littledan: FYI, I disagree with the con regarding "garden path" to partial application. While it was brought up by Waldemar when I initially proposed the feature, I've presented on how that concern isn't new to the language given destructuring. [15:07:40.0000] msaboff: just making sure, did istvan answer your questions re: opt-out? If it helps the ECMA document number is Ecma/TC39/2021/012. [15:08:05.0000] Yep. Thanks [15:10:40.0000] rbuckton: Hm, how is destructuring an example of it already existing? [15:15:25.0000] The "garden path" concern was that, without some kind of leading syntax a user wouldn't know whether a call expression was an invocation or a partial application until they see the `?`, which could be arbitrarily far down the argument list. The same is true for existing language features such as array destructuring: [15:15:25.0000] ``` [15:15:25.0000] [a, b, c, d, e, ...f] = g [15:15:25.0000] ``` [15:15:25.0000] The above looks like an array until you reach the `=`. [15:16:09.0000] As well as arrow functions: `(a, b, c = d) => e` could just be a comma list until you get to the `=>`. [15:16:22.0000] good example, but there is a little difference. destructuring normally start with `const` / `let`. [15:16:25.0000] Its not a new issue, and wasn't blocking for arrow functions or destructuring. [15:17:08.0000] rbuckton: I mean, *technically* yes, but in practice starting a line with an array or object literal is a *very* strange thing to do. [15:17:32.0000] So in practice it's not a garden path at all, you just always assume that a line-starting `[` or `{` means destructuring is happening [15:17:42.0000] Tab, true, but `a = [b, c, d] = e` is also legal javascript. [15:17:43.0000] And arrow function normally in the position of expression, so people can recognize it in the first place. [15:17:44.0000] rbuckton: It's not quite the same thing. [15:17:50.0000] Again, legal, but *weird* [15:18:04.0000] Like, nobody writes that ^^_ [15:18:18.0000] So they do not have garden path issue in practice, at least in most cases. [15:18:29.0000] If you could write [a + b, f(x)*g(y) + 17, "foo", d+e] = g and have it change the meaning of subexpressions, it would be worse [15:19:14.0000] wsdferdksl: My point is that `?` doesn't change the fact that `f(?)` still returns a value like a call expression would, while `[a, b, c] = d` completely changes the meaning. Also, `f(?, g())` still eagerly calls `g()`. [15:19:28.0000] And that's my beef with the garden path variants of the proposal. [15:19:31.0000] Note I don't think garden path issue is very serious, just want to clarify. [15:21:03.0000] rbuckton: There would be pressure from folks to write things like f(g(), ? + 3). [15:21:30.0000] What gets evaluated when gets messy really fast [15:21:41.0000] wsdferdksl: I'm aware, which is why some prefer the "Hack-style" for pipelines [15:21:43.0000] Isn't that a syntax error? [15:22:12.0000] haxjs: Everything we're discussing is currently a syntax error [15:22:28.0000] I mean it 's a syntax in partial app proposal [15:22:29.0000] But I'm extrapolating to what folks would demand [15:22:29.0000] For partial application, I've kept the proposal's scope intentionally limited. [15:23:03.0000] I don't want `?` to just mean an arbitrary function is created. Its always an argument placeholder. [15:25:07.0000] My only misuse worry about partial application is someone may write code `f(?, a, b(?))` which expect the semantic like in hack-style. I worry about that much than garden path issue. [15:25:21.0000] I know there are some that have argued that they would want `f({ x: ? })` because object literals/destructuring is essentially the JS version of "named arguments", but I'm still opposed to that. I'd much rather see us invent an *actual* named arguments capability instead, but I'm not going to push hard for it. [15:28:49.0000] Yeah either of those are why I'm against partial-application. :( `foo(?+1)` is invalid, `foo(1, bar(?))` isn't what you expected, `foo({x:?})` is invalid... it's so so limited and/or confusing in practice [15:28:52.0000] My proposal for partial application was to *just* support partial application. the `?` isn't a value, its an unsatisfied argument position. The "partial application" is actually everything *except* `?` bit. [15:37:37.0000] Yeah, I just don't think that pulls its weight given the mines it leaves around itself. I understand that the early-vs-late evaluation differences in `x=>foo(x, expensive())` vs `foo(?, expensive())`, but I feel like that's a footgun all its own honestly. [15:38:10.0000] Plus, partial application has other capabilities in its problem-space. If you want `f({ x: ?})` you can still do that with an arrow. Partial application covers other use cases: [15:38:10.0000] ``` [15:38:10.0000] // getting only the arguments you expect [15:38:10.0000] [1].forEach(console.log); // oops, logs: 1, 0, 1 (or [1] depending on your runtime...) [15:38:10.0000] [1].forEach(console.log(?)); // logs: 1 [15:38:10.0000] // swap argument order [15:38:11.0000] const f_swapped = f(?1, ?0); [15:38:12.0000] // simplified references [15:38:12.0000] element.addEventListener("click", this.onClick(?)); [15:38:13.0000] // More powerful than .bind [15:38:14.0000] const g = foo(?, 1, 2, ?); // bind only binds leading arguments, but here you can bind middle arguments [15:38:14.0000] ``` [15:38:50.0000] (honestly not sure if that code sample went through, freenode just spat a bunch of errors at me) [15:39:03.0000] i see it [15:39:24.0000] TabAtkins: its the same mental model as `foo.bind(void 0, expensive())` except you have more control over unbound arguments. [15:48:13.0000] Yeah I get that, but I don't think "it's just like `.bind()`" is a very compelling argument for understandability ^_^ [15:48:18.0000] What I know is that I want pipeline in some form. We would *heavily* use it in the TypeScript codebase at the very least. I also want partial application in some form, because there are so many cases of callback passing that could be simplified using it. I like the F#-style pipeline because (while in some ways limited compared to the Hack-style), it reduces the burden of knowledge for what operator to use where [15:52:11.0000] Ah ok, let me pick your brain about that last statement - what's the burden of knowledge you see wrt that in Hack. [15:52:29.0000] If I know that ` x |> F` is just `F(x)`, and that `F(?)` is basically `_ => F(_)`, using the two together is fairly simple and extremely powerful. I don't have to think about "partial application uses ?" while pipeline uses `#`", or "I can't use partial application in a pipeline because the meaning of `?` changes". If the arrow restriction goes the way littledan proposed, a lot of the Hack-style pipes can be [15:52:29.0000] done with arrows: [15:52:29.0000] ``` [15:52:29.0000] x |> say(?) [15:52:30.0000] |> _ => _ + _ [15:52:30.0000] |> _ => ({ x: _ }) [15:52:31.0000] |> _ => [_] [15:52:31.0000] |> nameMyTopicWhatIWant => (y |> f(?, nameMyTopicWhatIWant)) [15:52:32.0000] ``` [15:54:14.0000] TabAtkins: I'm talking about a scenario where we might have Hack-style pipelines *and* partial application. You either use different symbols for each (the topic or the placeholder), or you have confusing restrictions on where you can use the same symbol. [15:54:31.0000] Ohhh okay. [15:54:41.0000] Plus Hack-style pipes have issues with multiple topics. [15:55:15.0000] Are you referring to nested pipelines? [15:55:53.0000] I think that could be argued as a feature, if it makes something we don't advise doing less easy [15:55:57.0000] ``` [15:55:57.0000] # using hack-style [15:55:57.0000] x |> f(?, y |> g(?, ?)) // but I want the outer `?` in one of these... [15:55:58.0000] ```\ [15:56:18.0000] oh in param position, hmm [15:56:49.0000] i think it's probably better if pipeline and partial had different placeholders anyways [15:56:56.0000] So yeah, nested pipelines. [15:57:04.0000] for the above, you would need to have a way to declare the name of your topic, so you end up with: [15:57:04.0000] ``` [15:57:04.0000] x |> (_ => f(_, y |> g(?, _))(?) [15:57:04.0000] ``` [15:57:05.0000] At that point you should be breaking the expression apart and using variables. [15:57:25.0000] Or use an iife, yeah, but I think that's not worth the syntax cost. [15:57:39.0000] TabAtkins: Whenever I see `|> ? + 1` in a Hack-style pipe I think the same thing. [15:58:06.0000] You think "add 1 to this value" is worth breaking the xpression apart? Or just not worth the syntax? [15:58:57.0000] Yes, its true that F#+papp doesn't solve this either, but it makes the arrow-function part easier: [15:58:57.0000] ``` [15:58:57.0000] // F#+papp [15:58:57.0000] x |> _ => f(_, y |> g(?, _)) [15:58:57.0000] ``` 2021-03-11 [16:00:04.0000] TabAtkins: I think "add 1 to this value" can also be done with this: [16:00:04.0000] ``` [16:00:04.0000] ((x |> say(?)) + 1) |> print(?) [16:00:04.0000] ``` [16:01:05.0000] Those parens ar emaking me physically recoil [16:01:48.0000] That's *precisely* the sort of code contortions I want to make sure are never necessary. [16:02:07.0000] Going from `x |> say(?) |> print(?)` to... that, just because you realized you needed to incrememnt the value in the middle [16:03:10.0000] (realistically you'd write `x |> say(?) |> x=>x+1 |> print(?)` tho) [16:03:40.0000] I've considered proposing functional operators for those kinds of cases too, which are similar to F# symbolic operators. [16:04:38.0000] And I dont' think that's an unreasonable thing to propose on its own, but as a way of avoiding Hack-style pipelines, it's just piling more and more new features ^_^ [16:04:41.0000] Basically `{+}` which means `(a, b) => a + b`, plus fixed arguments: `2 {+}` meaning `(b) => 2 + b` [16:05:39.0000] So, you'd end up with: [16:05:39.0000] ``` [16:05:39.0000] x |> say(?) [16:05:39.0000] |> {+} 1 [16:05:39.0000] |> print(?) [16:05:40.0000] ``` [16:05:40.0000] Or [16:05:41.0000] ``` [16:05:41.0000] [1, 2, 3, 4].reduce({+}, 0) [16:05:42.0000] ``` [16:06:53.0000] Or even: [16:06:53.0000] ``` [16:06:53.0000] x |> filter({>} 0) [16:06:53.0000] |> map({+} 1) [16:06:53.0000] |> reduce({*}, 1) [16:06:54.0000] ``` [16:07:22.0000] I'd just as well have Operator.add or something at that point, I think [16:07:33.0000] I mean, it's not bad. Now do the same thing for all the other cases in the comparison slide. ^_^ [16:07:44.0000] rkirsling: Yeah, I have a package with operators like that. [16:08:08.0000] TabAtkins: `|> _ => (/*whatever was in the slide*/)` ? [16:08:43.0000] Yes, you're proposing ways to avoid having to write an arrow function [16:09:01.0000] partial-application, operator-funcs, etc [16:10:53.0000] ljharb Do you know where the 2021 Ecma/TC39/2021/012 document was posted? All I can find is https://tc39.es/ecma262/ which looks like the evolving draft. [16:11:14.0000] it's on the releases page [16:11:45.0000] https://github.com/tc39/ecma262/releases/tag/es2021-candidate-2021-03 [16:12:00.0000] namely https://github.com/tc39/ecma262/releases/download/es2021-candidate-2021-03/ECMA-262.12th.edition.June.2021.pdf [16:12:28.0000] er [16:12:38.0000] that's the PDF version, I mean [16:12:44.0000] HTML version is https://tc39.es/ecma262/2021 [16:12:54.0000] rkirsling Thanks [16:13:02.0000] sure! [16:28:40.0000] ``` [16:28:40.0000] const Op = { [16:28:40.0000] set(obj, key, value) { obj[key] = value; return obj; }, [16:28:40.0000] new(f, ...args) { return new f(...args); }, [16:28:40.0000] }; [16:28:41.0000] x |> o.m(?) [16:28:42.0000] x |> o.m(0, ?) [16:28:42.0000] x |> Op.new(o.m, ?) [16:28:43.0000] x |> ? {+} 1 [16:28:43.0000] x |> Array.of(0, ?) [16:28:44.0000] x |> Op.set({}, "key", ?) [16:28:44.0000] x |> o.m(?) |> await [16:28:45.0000] x |> o.m(?) |> /* tough one because `yield` is valid on its own... */ [16:28:45.0000] ``` [16:34:49.0000] Meta operators (mostly tongue-in-cheek idea, but maybe...?): [16:34:49.0000] ``` [16:34:49.0000] x |> o.m(?) |> await.? [16:34:49.0000] x |> o.m(?) |> yield.? [16:34:50.0000] ``` [16:34:56.0000] That works! Note tho that every single line you wrote is either identical to Hack-style, or longer/more complex/new features. [16:35:34.0000] the `Op.new` thing is because I currently disallow `new f(?)`, but I could remove that restriction. [16:36:38.0000] Sure, the exact set of ops isn't that imporant; you need more than the two you listed anyway, like `get` [16:36:56.0000] Also, I was thinking that F# has multiple pipeline operators: `|>`, `||>`, `|||>`. Though for those its about piping multiple inputs (i.e., `a b ||> f` is equivalent to `f a b` in F#) [16:37:27.0000] JS has that reasonably covered already - `[a, b] |> f(...#)` [16:37:36.0000] We could have both (as long as the topic and the placeholder don't share the same token). [16:38:17.0000] ``` [16:38:17.0000] x ||> [0, #] [16:38:17.0000] ``` [16:38:18.0000] I just don't like overloading the syntax that much though. [16:39:31.0000] I agree that I'm not a fan of mixing partial-app and Hack-style. I just think that the result of that unease is to regard it as one more strike against partial-app. [16:39:43.0000] the only thing infeasible with F#+papp compared to Hack is yield. Honestly though, if you're yielding in the middle of a pipeline that seems a bit like code-smell... [16:40:35.0000] Likely, yeah; `yield` is important to me only in the sense that we carved out a special exception to make `await` work, but left this other very similar keyword out in the cold. [16:40:47.0000] It feels dirty, is all. But I don't think it's important in practical terms. [16:41:10.0000] Very much a "theoretical purity"-level concern in the priority of constituencies. [16:41:29.0000] We could do the same thing we do in async generators with `yield promise` and just have `|>` await the result for you... [16:41:42.0000] Not that I'm a fan of that [16:42:02.0000] Yeah, not a fan of that magic outside of the explicit async boundary. [16:42:41.0000] but something explicit like `await.?` informing the pipeline would work for `yield.?` too... [16:43:46.0000] Like I said during the talk, ultimately the two are *so close to identical*. Ignoring await, *every single* Hack-style pipeline like `val |> XXXXX` becomes an F#-style with `val |> x=>XXXXX`. And *every single* F#-style pipeline like `val |> XXXXX` becomes a Hack-style with `val |> XXXXX(#)`. Doesn't matter how complex the XXXXX expression is, the transform works in 100% of cases (ignoring await). [16:44:26.0000] `await` and `yield` violate TCP, so they're always going to be tough to work around. [16:45:39.0000] With await, the only diff is that F#-style *requires* you to unfold the XXXXX into two or three steps, with the promise isolated in the middle step. `val |> foo(await fetch(#))` must be unfolded into `val |> fetch |> await |> foo`; you can't write `val |> x=>foo(await fetch(x))`. [16:46:26.0000] (Technically you could write `val |> async x=>foo(await fetch(x)) |> await`, but ugh.) [16:47:39.0000] I was also considering that `|> yield` could be a special form like `|> await`, and if you *really* wanted to yield `undefined` you could use parens or `do` or something: [16:47:39.0000] ``` [16:47:39.0000] x |> m.o(?) |> yield |> print(?); // basically `print(yield(m.o(x)))` [16:47:39.0000] const memo = _ => () => _; [16:47:39.0000] x |> m.o(?) |> memo(yield) |> print(?); // basically `print((m.o(x), yield))` [16:47:43.0000] ``` [16:50:08.0000] I don't understand how the `memo(yield)` part works. That doesn't produce a function. [16:50:11.0000] F#+papp only requires you to unfold the steps if you are awaiting the "topic": [16:50:11.0000] ``` [16:50:11.0000] x |> o.m(?, await p); // perfectly reasonable. [16:50:11.0000] ``` [16:50:12.0000] Since you only have a single "topic", awaiting it in the middle isn't that burdensome (and if anything is clearer) [16:50:20.0000] `memo` produces a function [16:50:57.0000] rbuckton: The moment your expression is complex enough to need an arrow-func, not partial-app or operator-funcs or what-have-you, it fails regardless of what you're awaiting. [16:51:07.0000] It produces a function that always returns the argument passed to `memo`: [16:51:08.0000] ``` [16:51:08.0000] const memo = _ => () => _; [16:51:08.0000] const f = memo(3); [16:51:08.0000] console.log(f()); // 3 [16:51:08.0000] console.log(f()); // 3 [16:51:08.0000] console.log(f()); // 3 [16:51:09.0000] ``` [16:51:11.0000] rbuckton: Right, but `yield` isn't a function. [16:52:09.0000] Yeah, you evaluate an expression that returns a function. `memo(yield)` is an expression. I was illustrating the exceedingly rare case of "I want to `yield` the value `undefined` and return its result" [16:52:23.0000] That's the reason `|> yield` doesn't work but `|> await` does. [16:52:32.0000] `await` requires an operand, `yield` does not. [16:52:32.0000] Ohhhh, okay, so it's not the same as the preceding line (which interprets `yield` as a special form that yields the topic) [16:52:57.0000] Yield should behave the same as await. [16:53:01.0000] no, I was explicitly illustrating the "if you *really* wanted to yield `undefined` you could use parens or `do` or something:" case [16:53:18.0000] Okay, using the parens from a wrapping function call was confusing me. ^_^ [16:53:31.0000] jridgewell: As I said, the reason it doesn't is that `yield` (no operand) is a valid expression in JS [16:53:50.0000] So `x |> yield` might mean something different to one person vs. another. [16:53:54.0000] Yes, in pipe, it should be treated like `await` [16:54:15.0000] It could mean, "I want to yield x", or it could mean "I want to call the function resulting from yielding `undefined` with the value of `x` [16:55:03.0000] jridgewell: I was proposing we do something like `|> await.?` and `|> yield.?` to be more specific about the behavior, but I generally agree. `|> yield` should be treated like `|> await` if it comes down to it. [16:55:21.0000] That's resolve by `|> (yield)` vs `|> yield` [16:55:37.0000] If you want the "I want to call the function resulting from yielding `undefined` with the value of `x case just do `|> (yield)`. [16:55:38.0000] yeah [16:56:00.0000] The first invokes the return of yield, and the second yields the pipeline arg [16:56:46.0000] But this all comes down to `yield` being inherently incorrect, it should have been spec'd like `await` [16:57:04.0000] It always takes an arg, and if you wanted to yield nothing, do `yield undefined` [16:57:50.0000] Requiring that `yield` have an operand is a very "iterator-centric" point of view and ignores other generator/coroutine-like scenarios. [16:58:18.0000] You might always just want to write `const x = yield` since it only matters what you're sent, not what you receive. [17:00:13.0000] That's making very similar operators behave very differently for, what I imagine, is .0000000000000000000001% of the uses. [17:00:19.0000] Regardless, its too late to change that. [17:00:42.0000] I agree that we could make the distinction that `|> await` and `|> yield` behave the same. [17:01:29.0000] In F# pipes, if you wanted pipe `x` into a function stored in a Promise, you'd have to do `x |> (await pfn)` anyways [17:01:58.0000] No different from `x |> (yield y)` really [17:24:35.0000] Why would you have to do that? Aside from the "bare await" syntax carve-out, the RHS is just an arbitrary expression that must resolve to a function, so in F#, `x |> await pFn` should be completely valid. [17:25:57.0000] https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011&build=&builtIns=false&spec=false&loose=true&code_lz=B4AgPgfCCGDu0EsAuIAOAxAdkA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=stage-0&prettier=true&targets=&version=7.13.10&externalPlugins= [17:26:17.0000] We forbid await without parens to avoid the ambiguity [17:26:25.0000] But it could be made lega [17:26:28.0000] legal** [17:26:34.0000] That's not an unreasonable position to take, imo. [17:27:20.0000] Oh, Babel didn't even implement `x |> await`, though [17:27:23.0000] So I have no idea. [17:29:59.0000] A) we need a way to `await` the "topic" [17:29:59.0000] B) we want to reduce confusion and be consistent. [17:29:59.0000] If we want consistency between `await` and `yield`, then we need to explicit. [17:29:59.0000] `|> await` has no operand and awaits the topic [17:29:59.0000] `|> (await p)` awaits `p` and invokes the result with the topic [17:30:00.0000] `|> yield` has no operand and yields the topic [17:30:00.0000] `|> (yield)` yields `undefined` and invokes the result with the topic [17:30:01.0000] `|> (yield p)` yields `p` and invokes the result with the topic [17:30:02.0000] Both `|> await` and `|> yield` would need NLTs and restrictions to forbid a leading `AwaitExpression` or `YieldExpression`. [17:30:03.0000] Also, due to the precedence of `yield`, you probably need to parenthesize it since `yield`'s precedence will probably conflict with `|>` [17:31:30.0000] ``` [17:31:30.0000] // if no parens, for this: [17:31:30.0000] x |> yield |> F [17:31:30.0000] // you probably wanted: [17:31:31.0000] (x |> yield) |> F [17:31:32.0000] // but you got this instead: [17:31:32.0000] x |> (yield |> F) [17:31:33.0000] ``` [17:31:47.0000] or rather [17:32:27.0000] That example was incorrect. [17:32:30.0000] ``` [17:32:30.0000] x |> yield a |> F [17:32:30.0000] // would be [17:32:30.0000] x |> yield (a |> F) [17:32:30.0000] // but you wanted [17:32:30.0000] (x |> yield a) |> F [17:32:30.0000] `` [17:32:37.0000] ``` [17:33:22.0000] Agreed. [17:33:42.0000] So, forcing the parens is better for user expectations: [17:33:42.0000] ``` [17:33:42.0000] // no precedence concerns [17:33:42.0000] x |> (yield a) |> F [17:33:42.0000] ``` [17:34:24.0000] So, if we want to avoid precedence issues and remain consistent, `|> await` and `|> yield` would be special forms, and if you don't want the special forms, you use `|> (await ...)` and `|> (yield ...)` [17:34:49.0000] rbuckton: For your point A), I think a more general statement is that we need a way to `await` *things* inside a pipeline. The topic is one thing and often what you'll want, but not the sole thing, depending on what your code is doing. [17:35:32.0000] Not unreasonable to start from `val |> x=>foo("arg", x)` and later realize you actually need to grab `"arg"` from the network. [17:35:58.0000] Yeah. Outside of the position immediately to the right of `|>`, you could use `await` anywhere else in the pipeline expression, i.e. `x |> foo(?, await y)`. [17:35:59.0000] Sucks if `val |> x=>foo(await fetch("/arg"), x)` doesn't work and there's no way to make it work without contortions [17:36:18.0000] Well, that wouldn't work unless you made the arrow async anyways... [17:36:21.0000] Again that point is *only* valid so long as you can avoid an arrow-function wrapper. [17:36:45.0000] ("that point" being that you could just drop an `await` into partial-app) [17:37:00.0000] ``` [17:37:00.0000] x |> foo(await fetch("/arg"), ?) [17:37:00.0000] ``` [17:37:00.0000] Would be valid in F#+papp [17:37:36.0000] Yes, because the RHS happens to be simple enough to be expressible in partial-app. If that's not true, you need a wrapper function. [17:37:38.0000] The `await fetch("/arg")` happens first, before the papp function is returned. [17:37:42.0000] And suddenly you need to contort yourself. [17:38:15.0000] Assume that you're gonna manipulate the topic as well so you can't papp it, like `foo(await fetch("/arg"), ? + 1)` [17:39:03.0000] `x |> ? + 1 |> foo(await fetch("/arg"), ?)` works for that, but I see your point. [17:39:09.0000] well [17:39:45.0000] ``` [17:39:45.0000] x |> ? {+} 1 |> foo(await fetch("/arg"), ?) [17:39:45.0000] ``` [17:39:45.0000] rather, if we're talking functional operators... [17:40:36.0000] I guess one of my issues with Hack-style is that you don't need new syntax for it. [17:40:46.0000] Yeah, my point is that suddenly you're having to do *larger* rewrites from your starting point of `val |> x=>foo("arg", x+1)` [17:41:10.0000] rbuckton: explain? [17:41:24.0000] ``` [17:41:25.0000] var _; [17:41:25.0000] ( [17:41:25.0000] _ = x, [17:41:25.0000] _ = _ + 1, [17:41:25.0000] _ = foo(await fetch("/arg"), _), [17:41:25.0000] _ [17:41:26.0000] ) [17:41:27.0000] ``` [17:41:36.0000] That's a hack pipe with no new syntax. [17:41:47.0000] plus, you can control your topic variable. [17:42:12.0000] No new syntax, sure. But quite a lot of tax. [17:42:38.0000] F# doesnt' require any new syntax either: [17:42:47.0000] Not much, you're replacing `|>` with `_=` and `,` [17:43:07.0000] `function pipe(val, ...fns) { for(const fn of fns) val = fn(val); return val; }` is F# pipe. [17:43:42.0000] `pipe(val, {+} 1, foo(await fetch("/arg"), ?))` [17:43:45.0000] Except static analysis for type systems sucks for that case. [17:44:17.0000] Valid, tho not a concern for 90%+ of JS devs. ^_^ [17:44:23.0000] In TypeScript, you end up with an overload ladder that eventually bottoms out. [17:46:47.0000] And given that, as I said earlier, Hack and F# pipelines are *trivially* translatable between each other, if Hack-style is bad because you can already write it in existing syntax, then F# is too. [17:47:08.0000] Tbf, it does invoke a slightly larger tax - every line would have a `(_)` at the end of it. [17:48:54.0000] Regardless, tho, "you can use comma and assignment to get the same effect at a similar cost in characters" doesn't fly in practice, because people still love method chaining but don't love it enough to do comma-and-assignment. It feels much, much nastier and heavier-weight even if the raw character weight is similar. [17:49:05.0000] When I started down the road of looking into `|>` and papp several years ago, my design choices were driven by projects like lodash and Ramda. Specifically, designing a syntax that doesn't heavily prefer one over the other as I don't want it to feel like TC39 is "choosing a winner" [17:49:23.0000] this was following on the heels of the earlier `::` bind proposal. [17:49:43.0000] Yeah, "better `::`" is one of the reasons I came to support `|>` too. [17:50:06.0000] One of the upsides of the F#+papp proposal, is that it worked equally well with both (and other) fp-style libraries. [17:50:52.0000] Hack-style works too, but favors lodash, since Ramda uses currying. [17:54:07.0000] ``` [17:54:07.0000] // F#+papp [17:54:07.0000] // lodash-style [17:54:07.0000] x |> map(?, _ => _ + 1) [17:54:07.0000] // Ramda-style [17:54:07.0000] x |> map(_ => _ + 1) [17:54:08.0000] // Hack [17:54:09.0000] // lodash-style [17:54:09.0000] x |> map(?, _ => _ + 1) [17:54:10.0000] // Ramda-style [17:54:11.0000] x |> map(_ => _ + 1, ?) // can't leverage Ramda currying [17:54:11.0000] ``` [18:01:36.0000] Plus, lodash and Ramda both support partial application: [18:01:36.0000] ``` [18:01:36.0000] // Ramda [18:01:37.0000] R.curry(g)(R.__, 2, 3)(4) [18:01:37.0000] // lodash [18:01:38.0000] _.partial(g, _, 2, 3)(4) [18:01:38.0000] ``` [18:01:39.0000] But that requires a fair amount of code beneath the surface to support, vs: [18:01:40.0000] ``` [18:01:40.0000] g(?, 2, 3)(4) [18:01:41.0000] ``` [18:30:03.0000] Sorry, wife came home and I had to rush off to make dinner. I'll pick up tomorrow. 2021-03-22 [10:32:47.0000] Bakkot: think it's worth a PR to change them all to "Property Key"? since it's a type it feels better to me capitalized [10:33:28.0000] ehh, we don't consistently capitalize types [10:33:34.0000] "(a non-negative integer)", e.g. [10:33:36.0000] that is true [10:33:56.0000] there's not a strong reason to do it, for sure [10:36:53.0000] I'm inclined to leave things alone by default [10:36:59.0000] absent strong reason to change [10:42:07.0000] alrighty 2021-03-23 [17:57:45.0000] PSA: anyone interested in running an incubator call on ystartsev's lazy imports proposal this week? the two timeslots i can do it don't work well for other stakeholders [17:59:30.0000] https://github.com/tc39/Reflector/issues/363#issuecomment-804504100 2021-03-25 [10:39:02.0000] another incubator call PSA: the champions of the regexp set notation are especially interested in getting general design direction feedback. if you have an interest in regexps please try to attend https://github.com/tc39/Reflector/issues/365 2021-03-29 [23:56:22.0000] someone lock https://github.com/tc39/proposals/issues/346 maybe? [08:05:29.0000] done