02:09 | <rbuckton> | Somewhat offtopic, but if there are any NodeJS implementers present that are familiar with Node's support for the W3C Web Performance APIs, can they reach out to me either via IRC or email? |
04:40 | <devsnek> | rbuckton: sup |
17:40 | <littledan> | rbuckton: On Node.js Web APIs, are you in touch with James Snell or Matteo Collina? They're doing a lot of implementation these days. I can put you in touch by email if you want. |
18:08 | <michaelficarra> | I love everything about this proposal |
18:10 | <rickbutton> | yep format*ToParts is universally great |
18:11 | <rkirsling> | editing is still intense, wow |
18:11 | <rkirsling> | the delay is large enough that it's easy to forget what was said by the time the mistake appears |
18:12 | <devsnek> | resizable arraybuffers are good |
18:12 | <Bakkot> | rkirsling yeah :( |
18:12 | <rbuckton> | littledan: that would help. We switched TS to leveraging the WC3 perf API for some performance monitoring in the TypeScript compiler and have run into cases where using perf_hooks is 20x slower than what we were doing before. |
18:12 | <Bakkot> | a bit of that is introduced by me for dumb technical reasons |
18:12 | <Bakkot> | rkirsling I kind of want to look into putting teams on a one-second lag while I'm taking notes |
18:13 | <rkirsling> | ahh yeah |
18:13 | <devsnek> | rbuckton: i'm curious how that performs if you use node >=15 with `--turbo-fast-api-calls` |
18:20 | <littledan> | rbuckton: Oh, I see. BTW you can find more information about people and discussions in this area at https://github.com/nodejs/diagnostics |
18:21 | <devsnek> | qard is also working on improving tracing api performance |
18:21 | <rbuckton> | devsnek, littledan thanks! |
18:27 | <Bakkot> | rkirsling are you still taking notes? |
18:27 | <Bakkot> | I've been doing it but want to tweak the bot |
18:27 | <Bakkot> | and it'll get behind if I step away |
18:28 | <rkirsling> | Bakkot: I think my eyes are not strong enough to keep up with something like this |
18:28 | <Bakkot> | kk, not to worry |
18:29 | <rkirsling> | I'm struggling with them daily as it is but this feels more intense than your average competitive video game |
18:31 | <rkirsling> | like I feel mildly sick from 20 minutes of it |
18:32 | <ystartsev> | general newbie question for this topic: does this make page size observable? maybe it already is from wasm? |
18:32 | <ystartsev> | are these slides published anywhere? i see other people looking at it but its not on the agenda or in the notes? |
18:35 | <rkirsling> | ystartsev: they're in the agenda? |
18:35 | <rkirsling> | https://docs.google.com/presentation/d/1lkDe1j1LcX8fg4KeLRKEeBG6VF0ffBz4Q_kA130V_aQ/edit?usp=sharing |
18:35 | <Bakkot> | mark is current winner for person-who-bot-likes-best |
18:35 | <ystartsev> | ah, i didn't refresh recently |
18:42 | <Bakkot> | can someone fixup peter's acronym in the notes |
18:42 | <Bakkot> | I don't have time to look it up |
18:44 | <michaelficarra> | Bakkot: PHE |
18:44 | <ljharb> | Bakkot: on it |
18:44 | <ljharb> | nvm |
18:44 | <michaelficarra> | already got it ljharb ;-) |
18:45 | <michaelficarra> | delegate shorthands are listed in https://github.com/tc39/notes/blob/master/delegates.txt FYI |
18:46 | <michaelficarra> | it's good to keep that handy when on note-taking duty |
18:51 | <devsnek> | queue needs to be advanced |
18:53 | <ljharb> | fwiw a ton of my packages have a necessary use of `Function` in their dep graph, so while getting rid of `eval` seems achievable, getting rid of `Function` seems significantly less so. |
18:54 | <devsnek> | i see that a lot too |
18:55 | <caridy> | yeah, this is also related with his presentation yesterday. the fact that when using anything from someone else, having a global setting is not going to work. make it work usually wins over security issues unfortunately! |
18:55 | <rkirsling> | what is the necessary use of Function? |
18:55 | <rkirsling> | the d3-dsv readme just states that it's `(safe) use of dynamic code generation for fast parsing` |
18:56 | <ljharb> | rkirsling: objects only reachable from syntax - ie, AsyncFunction, GeneratorFunction, AsyncGeneratorFunction, etc. |
18:56 | <Bakkot> | bot writes "eval" as "evil" like 80% of the time |
18:56 | <ljharb> | rkirsling: iow by making them "not globals", a significant percentage of the web ends up having use of `Function` ¯\_(ツ)_/¯ |
18:57 | <ljharb> | Bakkot: where's the error tho |
18:57 | <rkirsling> | I see... |
19:02 | <akirose> | i've had to make some big overhauls to the schedule, please lmk if you see any misses or conflicts |
19:08 | <michaelficarra> | note takers: the shorthand for the current speaker is KOT, not KKL |
19:08 | <Bakkot> | oops, I probably did that all day yesterday too |
19:08 | <Bakkot> | they're adjacent in delegates.txt |
19:09 | <michaelficarra> | nope, it's correct yesterday |
19:11 | <devsnek> | so if d3 can create a trusted types thing |
19:12 | <devsnek> | what stops some other random evil thing from creating a trusted types thing |
19:12 | <Bakkot> | devsnek if you can create a policy you can already run arbitrary code |
19:12 | <Bakkot> | is the assumption |
19:12 | <devsnek> | oh does the policy say "the d3 url" can create trusted types? |
19:13 | <Bakkot> | no |
19:13 | <devsnek> | i guess i'm confused about the scoping of this |
19:13 | <Bakkot> | am taking notes thoug hsorry |
19:13 | <devsnek> | no worries |
19:22 | <michaelficarra> | I feel the current concerns should be pre-stage 2, not post-stage 2 |
19:22 | <Bakkot> | same |
19:22 | <gibson042> | I get the same impression |
19:22 | <devsnek> | same |
19:22 | <littledan> | I am slightly sympathetic to Caridy's argument (which seems valid to hold Stage 2 for), but completely disagree with several of Mark's points. |
19:23 | <littledan> | I don't think these should be thought about as the same point |
19:23 | <ljharb> | since they deal with "should this be in the language", that seems decidedly pre-stage-2 to me |
19:23 | <bradleymeck> | i'm actually fine w/ stage 2 but think it needs a fair amount of modification |
19:24 | <akirose> | the queue kkotowicz https://snaps.akibraun.com/588t7.jpg |
19:25 | <robpalme> | thanks aki |
19:25 | <robpalme> | this item is 30mins (not 60 mins as tcq indicates) |
19:26 | <michaelficarra> | am I supposed to be seeing slides? |
19:26 | <akirose> | no |
19:26 | <rickbutton> | woah selfhosted screenshots |
19:26 | <akirose> | rickbutton: Monosnap + AWS S3 + CloudFront |
19:26 | <devsnek> | i host my screenshots on s3 as well |
19:26 | <rickbutton> | nice |
19:26 | <devsnek> | there's some bug where they don't charge me for s3 usage |
19:26 | <devsnek> | and i don't intend to tell them |
19:27 | <rickbutton> | bezos covers your s3 bill with his pocket lint |
19:27 | <akirose> | i got real upset when Evernote bought and ruined Skitch in 2012 so I decided never again and set up the above. |
19:28 | <devsnek> | i had to add this big scary sentence to the vm docs https://gc.gy/79394277.png |
19:29 | <bradleymeck> | devsnek: that ain't stopping people |
19:29 | <bradleymeck> | XD |
19:30 | <devsnek> | it did reduce the number of issues people opened asking if vm is safe |
19:30 | <bradleymeck> | fair |
19:30 | <devsnek> | if i don't observe the exploit it doesn't exist :P |
19:32 | <bradleymeck> | shu: we have some slides that show the cycle problem somewhere around here when we tried to figure out some stuff for Loaders |
19:32 | <Bakkot> | syg there is another serious flaw with this approach |
19:32 | <Bakkot> | remind me to talk about it |
19:35 | <shu> | Bakkot: "this approach" = sync message-passing? |
19:35 | <Bakkot> | yeah |
19:35 | <shu> | put yourself on the queue? |
19:35 | <Bakkot> | am notes |
19:35 | <shu> | ah |
19:37 | <Bakkot> | am now on queue |
19:40 | <chicoxyzzy> | The font in TCQ needs some more weight IMHO. It's a bit hard to read sometimes |
19:40 | <ljharb> | +1 |
19:42 | <rkirsling> | I agree on the queue screen in particular |
19:42 | <rkirsling> | light font weight could be used for Agenda Item, Topic, and Speaking |
19:43 | <rkirsling> | but using it for the values of those makes them harder to read |
19:43 | <ystartsev> | bterlson is working on a new version |
19:43 | <ystartsev> | but i guess for now we can update it to be easier to read? |
19:50 | <ljharb> | re Bakkot's point, if "we can fix some of it" is ok for trusted types, why isn't it ok for realms? |
19:51 | <ljharb> | the line about "spectre, so who cares" is pretty frustrating |
19:51 | <ystartsev> | I think there is the option of renaming, and that might be a good direction |
19:52 | <ystartsev> | i think the highlighting of membranes as a pattern rather than an end in it self is pretty important, and I am curious about some of the discussion that has been had here so far... what that middle road is |
19:52 | <ystartsev> | I would like to see the fleshed out proposal |
19:53 | <devsnek> | honestly i'm still not 100% sure what a membrane is |
19:53 | <rickbutton> | a bunch of code that isolates two sides of an object graph |
19:54 | <devsnek> | neat |
19:55 | <ystartsev> | i've been thinking about it as telepresence |
19:55 | <robpalme> | i believe there is a wet and dry side |
19:55 | <devsnek> | yeah i remember the wet and dry side |
19:55 | <devsnek> | that was my first tc39 meeting 😅 |
19:56 | <rbuckton> | Is the problem that we keep trying to define these "security" features piecemeal? Each individual piece doesn't solve a specific security issue and on their own seem to be considered a footgun. Do we need a comprehensive strategy for security boundaries and trust levels in synchronous code? |
19:57 | <devsnek> | i think mark would say yes we need a comprehensive principled approach |
19:57 | <rickbutton> | i think we should ban the word security without a qualifier |
19:57 | <rbuckton> | For example, I could see a built-in mechanism combining Proxies/Membranes, Realms, and import assertions to establish trust levels between imports and exports, such that when one module interacts with another module that it doesn't "trust", it goes through a membrane and isolates the other module/package. |
19:58 | <shu> | bradleymeck: there is a broader strategy they're executing on |
19:58 | <shu> | coop/coep |
19:58 | <shu> | features to nudge people to opt in to the process boundary and disabling those APIs otherwise |
20:00 | <devsnek> | i'm still surprised that major js engines don't support HMR better |
20:01 | <devsnek> | especially google after all that work on dart/flutter hot reload |
20:01 | <caridy> | just to clarify, it seems that some folks are confused, the main issue solved by the counter proposal from google is to avoid the two objects graphs to be interconnected, basically, it avoid identity discontinuity all together |
20:01 | <bradleymeck> | shu: that isn't the strategy of others XD |
20:02 | <devsnek> | isn't isTemplateObject being driven by google? |
20:02 | <devsnek> | seems to be part of the identity discontinuity issue |
20:02 | <shu> | yes |
20:02 | <shu> | it is? |
20:02 | <shu> | actually i have to run for an hour, sorry will be unresponsive |
20:03 | <devsnek> | no worries |
20:05 | <bradleymeck> | shu: that is only the web contingent and doesn't work for things like Node, also has a large implication of same domain model |
20:09 | <Bakkot> | devsnek the answer to your earlier question about policies (if I understand it correctly) is that policies have names, you have to put the names in the CSP header, and the names are use-once |
20:09 | <Bakkot> | or at least this was my understanding last I checked |
20:09 | <Bakkot> | so to use the d3 lib you would add "polices: d3-csv" to your CSP (or whatever the actual syntax is) |
20:09 | <Bakkot> | and this would whitelist only d3 |
20:10 | <devsnek> | ah ok |
20:10 | <Bakkot> | or, if some other dependency tried to use it, doing so would break d3 |
20:11 | <Bakkot> | I am uhhhhhhhhh let me say "somewhat skeptical" that companies other that google will actually have the process in place to reliably go from "added a transtive npm dependency to some component" to "updated their CSP" |
20:11 | <Bakkot> | but that's the theory |
20:13 | <bradleymeck> | doesn't that mean that it is only applied to an entire source text and doesn't do bundling issues? the slide on reasons people continue to use eval mentioned the usage of eval exactly because of bundling |
20:13 | <bradleymeck> | everyone bundles at some level, even Google |
20:15 | <Bakkot> | bradleymeck the idea is that they would convince all the dependencies to move to a pattern of using trusted types in a way which would allow them to be used both by non-TT and TT consumers, I think |
20:15 | <Bakkot> | but there is also this "default policy" escape hatch |
20:16 | <Bakkot> | which you can read about at https://w3c.github.io/webappsec-trusted-types/dist/spec/#default-policy-hdr |
20:18 | <ljharb> | mathiasbynens: once rebased, https://github.com/tc39/ecma262/pull/1585 seems like it should be ready |
20:21 | <bradleymeck> | Bakkot: i guess? but that wouldn't have per invocation site tuning since it lacks a referrer of some kind. likely they expect every library to use a unique policy name in its source text??? |
20:41 | <Bakkot> | bradleymeck I shouldn't speak for them, but that is what I understood |
20:55 | <Bakkot> | mathiasbynens there's a few editorial tweaks necessary for 1585 to land, in addition to the rebase. since we want to cut 2021, it's probably easiest if the editors just take care of that, unless you / szuend object? |
21:12 | <littledan> | +1 to Shane's comment. We should not be designing locale data schema in plenary; there are other standards here |
21:13 | <littledan> | the ECMA-402 calls manage to bring in more i18n experts than we get in plenary. I encourage people who want to argue out the details to join that, though more feedback here is always good |
21:17 | <michaelficarra> | littledan: I'm not trying to (re)design the API here, I'm trying to validate its usefulness (as presented) for JavaScript devs |
21:17 | <littledan> | OK, that's legit, sorry for my comment |
21:17 | <michaelficarra> | I think that's kind of the purpose of 402 presenting fully worked proposals ot committee |
21:18 | <littledan> | yes |
21:19 | <michaelficarra> | as I said, I'm not an expert and don't feel qualified to propose an alternative or even really sit at the table with the TG2 people when they do their design |
21:19 | <Bakkot> | ystartsev I might kill the bot while frank is talking |
21:19 | <Bakkot> | not sure it's capturing him well enough to be worth it |
21:19 | <Bakkot> | thoughts? |
21:19 | <ystartsev> | hm |
21:20 | <ystartsev> | sure |
21:20 | <ystartsev> | its not bad though |
21:26 | <ystartsev> | "Flying on Auntie here Yeah this one." brilliant |
21:27 | <shu> | aunties always meddling |
21:29 | <gibson042> | https://github.com/unicode-org/cldr/blob/master/common/bcp47/calendar.xml , for those following along at home |
21:29 | <Bakkot> | gibson042 thanks, I put it in the notes |
21:31 | <ljharb> | queue needs advancing also |
21:31 | <ljharb> | all set |
21:43 | <littledan> | It'd be great to let this presentation finish before we do any more queue items IMO |
22:01 | <robpalme> | hey, i am kinda proud we spent a total of 7 minutes on chair elections this year |
22:02 | <littledan> | hmm, was the queue cleared on purpose? |
22:02 | <littledan> | I had something on there that now seems like it's gone |
22:03 | <robpalme> | please refresh |
22:11 | <ljharb> | i'm confused why "understand common X" implies "we refuse to understand uncommon X" |
22:34 | <littledan> | TC39 has been following the 10-day rule for a long time, with Ecma management aware of this. We should propose bylaws changes if Ecma wants to start enforcing a 3-week period. |
22:34 | <michaelficarra> | reflector thread about security TG: https://github.com/tc39/Reflector/issues/313 |
22:35 | <michaelficarra> | littledan: I don't think it's a concern, since we won't be actually forming until the next meeting where the chairs recommend a leadership selection process |
22:37 | <rkirsling> | also do exprs creates a motivation to fix completion value bugs in engines lol |
22:38 | <rkirsling> | 'cause JSC doesn't not eval `try` blocks correctly :P |
22:38 | <rkirsling> | *does not |
22:38 | <TabAtkins> | This example would be even more evocative if it was `const`, bc that's a *very* annoying case to do this exact thing with. |
22:39 | <michaelficarra> | do + try is a convenient way to turn throwing APIs into predicate APIs |
22:39 | <michaelficarra> | isValidJSON becomes much less awkward, for example |
22:39 | <rkirsling> | mhm |
22:39 | <TabAtkins> | Oooh, interesting point |
22:40 | <rkirsling> | I still maintain that "sorry, magic doesn't happen" suffices as an explanation for the loop case |
22:41 | <TabAtkins> | yeah i'm very happy to handle comprehensions on their own, and much better, than smuggling a basic version in via do-exprs |
22:42 | <TabAtkins> | i don't understand why break/return would be controversial, i presume there's something subtle in the mechanics |
22:43 | <TabAtkins> | to my ordinary-webdev eyes, it looks like something that should "just work" |
22:43 | <ljharb> | TabAtkins: to mine, that would be bad code that every styleguide i influenced would aggressively ban |
22:43 | <TabAtkins> | i don't disagree with that, but that doesn't mean we should disallow them imo |
22:43 | <ljharb> | TabAtkins: conflating flow control with expression positions is confusing and hard to maintain, it's why the airbnb guide bans assignment in expression position, for example. |
22:44 | <TabAtkins> | i'll ask on q |
22:45 | <TabAtkins> | someone remind me what the completion value of a loop is? |
22:45 | <littledan> | This proposal is awesome! Let's go for it! |
22:46 | <ljharb> | TabAtkins: without checking, i'm not sure you'd get any common answer if you polled people about that |
22:46 | <TabAtkins> | lol def |
22:46 | <ljharb> | TabAtkins: i *think* it's the last completion value of the last iteration tho |
22:46 | <TabAtkins> | i'll check, was just asking if someone had it at hand |
22:46 | <TabAtkins> | that's what i presumed |
22:46 | <ljharb> | TabAtkins: yeah, `eval('for (var i = 0; i < 3; i++) { i; }')` produces 2 |
22:47 | <shu> | +1 should be legal in sloppy |
22:48 | <michaelficarra> | I kind of prefer it introducing a strict context actually |
22:48 | <michaelficarra> | it's a new feature, who would want to write sloppy code inside a new feature? |
22:49 | <ljharb> | yeah i kind of like that too |
22:49 | <ljharb> | historically the pushback to that is "refactoring hazard", but somehow that was fine for Modules and `class` |
22:49 | <michaelficarra> | yeah |
22:49 | <ljharb> | (ie, `async function`, generators, etc weren't auto-strict for that reason, iirc) |
22:50 | <michaelficarra> | that makes sense though since functions don't auto-introduce strict and they're just function variants |
22:50 | <michaelficarra> | this is a new kind of thing, like class |
22:50 | <michaelficarra> | totally fine for those to introduce strict mode |
22:50 | <ljharb> | fair |
22:50 | <rkirsling> | in a way, given that `async function` is a kind of `function` it makes sense that it would need to use `'use strict''` whereas `do {}`, like `class {}`, wouldn't have a directive _within_ it |
22:51 | <michaelficarra> | ^ exactly |
22:51 | <rkirsling> | so I would agree with strict-only unless we can think of a way in which it is harmful |
22:51 | <michaelficarra> | I guess I'll open an issue on the repo |
22:53 | <gibson042> | the intent seems to be introduction of a new block in expression context; silently adding strictness inside that would be quite surprising |
22:53 | <devsnek> | i'm still sad that control flow isn't allowed |
22:53 | <michaelficarra> | strictness issue: https://github.com/bakkot/do-expressions-v2/issues/7 |
22:53 | <rkirsling> | gibson042: how do you feel about `x = class {}` though? |
22:54 | <leobalter> | ljharb: your topic should be a reply, just saying :) |
22:54 | <gibson042> | the scope introduced by a class expression is much more than a simple block |
22:55 | <ljharb> | thanks, couldn't find the button |
22:55 | <rkirsling> | obligatory "stop wanting that" |
22:56 | <drousso> | ^ +1 |
22:56 | <devsnek> | is bradford on irc |
22:56 | <bradleymeck> | rkirsling: it isn't just about "want" it is about expect |
22:57 | <rkirsling> | yeah I know |
22:57 | <bradleymeck> | see people coming from languages from comprehensions |
22:57 | <bradleymeck> | with comprehensions* |
22:59 | <TabAtkins> | yeah, requiring an expr limits the usefulness of this a lot |
23:01 | <rkirsling> | I guess banning loops makes banning break/continue a corollary |
23:01 | <devsnek> | i don't agree |
23:01 | <rkirsling> | oh wait |
23:01 | <shu> | oh god |
23:01 | <shu> | noooooo |
23:01 | <shu> | kill me nooooo |
23:01 | <rkirsling> | no that's not true sorry |
23:01 | <rickbutton> | tab has ascended |
23:02 | <TabAtkins> | ugh fuck my cam does this sometimes |
23:02 | <devsnek> | when ur tesla coil goes off |
23:02 | <TabAtkins> | skip me for now |
23:02 | <rkirsling> | was that a shaver? or a taser |
23:02 | <rickbutton> | thats the sound of someone becoming one with the internet |
23:02 | <gibson042> | teleporter |
23:02 | <ystartsev> | the start of some epic noise music |
23:02 | <rickbutton> | ^ |
23:03 | <devsnek> | we had answers for these questions, one of which was that the loop heads don't allow break/continue in them |
23:04 | <rkirsling> | I feel like the question of what `return` does is an even more legitimate source of confusion than the loop thing |
23:05 | <devsnek> | the only thing i've seen is that people would expect "return" to be the return value of the do expression |
23:05 | <devsnek> | which seems surface level enough to not be a blocking concern |
23:05 | <ljharb> | that's a major point of confusion |
23:06 | <ljharb> | or would be |
23:06 | <rkirsling> | I thought there were people arguing for returning from the containing function |
23:06 | <leobalter> | bterlson: if we still have objections to Stage 2, I'd set this for overflow. I hope we get stage 2 in this meeting |
23:06 | <ljharb> | rkirsling: the problem is that there's not a common intuition about what it does |
23:06 | <rkirsling> | that's what I'm saying |
23:06 | <michaelficarra> | this is an unfortunate situation :-( |
23:06 | <TabAtkins> | Ugh, no. |
23:06 | <ljharb> | wsdferdksl: fwiw there's a big difference between a statement that runs 0/1 times, and one that runs 0-N times, and what programmers will expect as the completion value. |
23:07 | <TabAtkins> | yes def |
23:07 | <rkirsling> | I *want* to be like "deal with it" for the loop thing but `return` is WAY harder to argue |
23:07 | <devsnek> | i am surprised that people find return scarier than the loops |
23:07 | <ljharb> | flow control bad |
23:07 | <TabAtkins> | rkirsling: Yes, `return` should trigger a return from the containing function. |
23:07 | <devsnek> | i think if you tell someone what a do expression is |
23:08 | <rkirsling> | yeah so my problem is that I don't feel like either interpretation is obviously wrong |
23:08 | <devsnek> | it would be clear to them that the return wouldn't be part of it |
23:08 | <devsnek> | if someone doesn't know what a do expression is this is all moot anyway |
23:08 | <devsnek> | since they wouldn't know it has anything to do with `return` |
23:08 | <TabAtkins> | I mean, having the ability to early-"return" from a do-expr makes sense, but finagling that separately from returning from the outer context is a bunch of work and you might as well just IIFE then |
23:08 | <rbuckton> | Since `do` is a new syntactic construct, perhaps we could introduce a keyword for explicitly exiting a `do` block with a value, rather than implicitly relying on completion values |
23:08 | <ljharb> | and when there's multiple intuitive solutions, banning it is both a thing we've done before, and a reasonably approach |
23:09 | <Bakkot> | alas :( |
23:09 | <Bakkot> | rbuckton that's been proposed multiple times and fairly resoundingly rejected; I at least am not interested in trying to pick it up again |
23:09 | <littledan> | Bakkot: keep going! |
23:09 | <devsnek> | i'm surprised that people think returning early from a do expression makes sense |
23:10 | <rbuckton> | devsnek: less about returning early, more about making it explicit what the result value is. |
23:10 | <rkirsling> | is it a block in an "everything's an expression language"? or is it IIFE-like? |
23:10 | <rbuckton> | If the result value was explicitly defined, then there'd be no confusion about `for`/`while`/etc. |
23:10 | <rkirsling> | both views can hold for most purposes |
23:11 | <rkirsling> | therefore both views will exist among the masses |
23:11 | <devsnek> | i mean with rust, which has expression blocks, i've never seen a single person be confused about it |
23:11 | <shu> | i remain of the opinion that while early returns from the outer function are useful in obvious places, risks run high of understandability of either figuring out what it should do in the positions where it is currently impossible, or how to best ban them |
23:11 | <devsnek> | and it's not like a different mental model from js or smth |
23:11 | <ljharb> | rkirsling: i think in ruby, a block's last completion value is what the block is, but `return` returns from the containing function? it's been awhile tho |
23:11 | <rkirsling> | devsnek: it's not confusing in Rust |
23:11 | <rkirsling> | it is a fundamental construct |
23:11 | <shu> | i imagine rust syntax was designed from ground up to have a more meaningful statement vs expression distinction |
23:11 | <rkirsling> | ^ |
23:11 | <devsnek> | rkirsling: it would even be the same syntax if we didn't have object literals |
23:12 | <shu> | we have an... accreted such understanding of the distinction in JS |
23:12 | <rbuckton> | The slides didn't describe `yield`, just that `await` is deferred until `async do` is a thing... |
23:12 | <rkirsling> | devsnek: I'm not sure that object literals are relevant though? |
23:12 | <shu> | but not like JS statement-vs-expr distinction was designed with principles |
23:12 | <devsnek> | no i'm just confused why rust is being dismissed as prior art |
23:12 | <devsnek> | it seems identical to this |
23:12 | <shu> | because it is not actually prior art |
23:12 | <rkirsling> | the question is about the default behavior of statements in a language |
23:12 | <shu> | we are prior art |
23:13 | <devsnek> | its prior art on being useful |
23:13 | <rkirsling> | yeah, this is sandboxed "everything's an expression" |
23:13 | <rbuckton> | nm, confusion about `async do`. `await` was called out as supported in `do {}`, but `yield` wasn't (though I assume it would be as well, if the outer context was `+Yield`). |
23:13 | <devsnek> | rkirsling: i don't know what you mean |
23:14 | <rkirsling> | I mean I've said it to you personally in every conversation about this |
23:14 | <Bakkot> | rbuckton yeah, see readme: https://github.com/bakkot/do-expressions-v2#awaityield |
23:14 | <devsnek> | no i mean i literally don't know what you're saying |
23:14 | <rkirsling> | Rust isn't confusing because there's nothing to be confused by in an everything's-an-expression language |
23:14 | <devsnek> | i'm saying no one has ever been confused by returns inside blocks inside expression positions |
23:15 | <ystartsev> | Bakkot: some stuff might be testable via a usability study |
23:15 | <rkirsling> | but when you're adding that behavior on *top* of a language's norms then people can find justification for different interpretations |
23:15 | <ystartsev> | if that sounds interesting i can raise it with the research group? it would be a nice topic for us |
23:15 | <devsnek> | and i guess you're saying rust is so fundamentally different from js that it doesn't count? |
23:15 | <devsnek> | but i don't agree with that |
23:15 | <TabAtkins> | `yield` not implying `return` makes sense from the code-review standpoint (we expect `yield` to be resumed from; if it doesn't, that's a massive code smell on its own), but at least it assures me that there's nothing technical about `return` being hard (unlike `break`/`continue`) |
23:15 | <Bakkot> | ystartsev I think in this particular case a usability study wouldn't help with anything |
23:15 | <rkirsling> | I don't mean it doesn't count |
23:16 | <rkirsling> | it's just that if we're gonna worry about loop behavior, which I do not consider confusing within the context of JS |
23:16 | <ystartsev> | well, let me know if we can help -- it would allow testing out some intuitions people might have about how people would approach these things |
23:16 | <rbuckton> | If we allow `const x = y ?? do { return; }`, why wouldn't we just allow `const x = y ?? return;` (following the "everthing's an expression" concept). We investigated this when we were discussing throw expressions. |
23:16 | <rkirsling> | then `return` is obviously a *greater* concern than that |
23:17 | <rkirsling> | because there are justifications for both views within the context of JS norms |
23:17 | <TabAtkins> | rbuckton: I mean, sure, but that's neither here nor there. return-exprs don't seem too wild to me, but neither is there a big request for them |
23:17 | <TabAtkins> | vs the more complex code flow we implicitly expect in a do-expr, which I *do* think I'll end up wanting to put early-returns into |
23:17 | <devsnek> | rkirsling: i also don't see the connection between the loops and this |
23:18 | <rbuckton> | There was back when I first introduced `throw` expressions, at least from the committee's side. |
23:18 | <TabAtkins> | In the context of throw-exprs, return-exprs seem like a natural extension, sure |
23:18 | <rkirsling> | devsnek: they are the controversial topics |
23:18 | <TabAtkins> | But this is a different context. ^_^ |
23:19 | <devsnek> | rkirsling: yeah it just seems to me that the controversy of the control flow is mostly coming from people who won't look at languages with block expressions as evidence that this isn't confusing |
23:21 | <rbuckton> | The biggest issue with `throw` expressions was that `do` was possibly going to be a thing, and that they'd have to be in `Expression`, so things like `const x = throw a, b = c` would be illegal, since `throw a, b = c` has a meaning as a staetment (i.e., you'd need to write `const x = (throw a, b = c)` or `const x = (throw a), b = c`). |
23:21 | <TabAtkins> | Ok thinking about the break/continue case, I can definitely see how something like `while(...) { for(var i = 0; i < do { continue; }; i++) { ... } }` is confusing - I don't know whether I'd expect it to continue the `while` or the `for` |
23:21 | <devsnek> | i don't think break/continue should be allowed in loop heads |
23:22 | <Bakkot> | devsnek I've used such languages a fair bit and I agree with rkirsling that they are not that strong of evidence |
23:22 | <rbuckton> | that even lead me to propose `ParenthesizedExpression: ( Statement )` on the `do` proposal issue tracker. |
23:22 | <devsnek> | like i wouldn't even put the restriction on do expressions |
23:22 | <devsnek> | i'd put it on the entirety of the head |
23:22 | <TabAtkins> | yeah, just having a restriction against their use in loop heads works for me, it's just another special-case restriction to learn. probably reasonable tho, imo. |
23:23 | <devsnek> | on an interesting note, back when v8 had do expressions because they used them internally, if you put break/continue in loop heads it would segfault |
23:24 | <devsnek> | Bakkot: yeah but like *why* |
23:24 | <devsnek> | i mean i can see why you might say using haskell or something is not a great comparison to how js people would approach it |
23:24 | <devsnek> | but these are not niche fp languages |
23:24 | <Bakkot> | because in languages in which everything is an expression you are not surprised when you can return in expression context, and this is not true for languages where not everything is an expression |
23:25 | <Bakkot> | like I just don't agree that you can generalize from rust to js |
23:25 | <devsnek> | what does "surprised" mean |
23:25 | <Bakkot> | or scala to js or whatever |
23:25 | <Bakkot> | they are different styles of programmnig |
23:26 | <Bakkot> | devsnek in this context, it mostly means "likely to miss or misunderstand what the code does when reading it" |
23:26 | <rkirsling> | it's not about niche-ness |
23:27 | <devsnek> | i'd actually be surprised if most people who use rust know that return is an expression |
23:29 | <Bakkot> | anyway I am not entirely sure what to do here |
23:29 | <rkirsling> | same... |
23:29 | <Bakkot> | I've heard from people that they are not willing to advance this if it allows return/break |
23:30 | <Bakkot> | and wsdferdksl says he is not willing to advance without |
23:30 | <Bakkot> | so |
23:30 | <rkirsling> | ljharb is in the former camp right? |
23:30 | <rkirsling> | so then we have a standstill? |
23:31 | <rkirsling> | I don't understand why it would be necessary initially |
23:31 | <Bakkot> | seems like |
23:32 | <rkirsling> | really vexing seeing how pattern matching is depending on this |
23:32 | <devsnek> | i think pattern matching depends on the consensus around how the completions are handled, not the literal do expression? |
23:33 | <devsnek> | and stuff like if loops/returns/etc are allowed |
23:36 | <shu> | ljharb is opposed to any return? |
23:37 | <devsnek> | if i were a more assertive i'd probably block on the lack of return |
23:38 | <shu> | and you would ban do expressions in loop heads? |
23:38 | <devsnek> | no i would ban break/continue in loop heads |
23:38 | <ljharb> | i think allowing `return` is a big problem, yes |
23:38 | <shu> | devsnek: ok |
23:39 | <ljharb> | it's very confusing; people won't universally intuit whether it returns from the containing function or from just the do expression, and allowing flow control to change in more places makes understanding the language harder, especially in the edge cases. |
23:39 | <shu> | devsnek: and you are also opposed to the "conservative MVP, relax later if demand arises" plan, like waldemar? |
23:40 | <ljharb> | i do agree that it could be added later if it ended up being a sticking point, but the value of do expression for me doesn't include return/break/continue, or loop completion values. |
23:40 | <devsnek> | shu: i don't enjoy that type of plan but to be clear i'm not blocking here |
23:40 | <shu> | ok |
23:42 | <ljharb> | (also, for me, "exactly replaces IIFEs" is definitely more than enough to warrant its syntactic weight, but i recognize everyone doesn't agree with that) |
23:42 | <devsnek> | I think at the very least, the limitation makes it more difficult to refactor code because you have to start refactoring control flow in addition to value flow |
23:44 | <rkirsling> | I mean |
23:44 | <ljharb> | devsnek: do you have some examples? my suspicion is that such a refactor would make the code much clearer |
23:44 | <ljharb> | meaning, it'd be an improvement even without do expressions |
23:44 | <devsnek> | 1s |
23:44 | <ljharb> | ty |
23:44 | <rkirsling> | sometimes you explicit *don't* want to let people use a thing as a drop-in replacement |
23:45 | <rkirsling> | I'm not saying that's for sure the case here but |
23:45 | <rkirsling> | that is a valid stance for a proposal to take |
23:45 | <rkirsling> | *explicitly |
23:46 | <rkirsling> | just thinking, y'know, maybe it's a good thing that you don't have a subcommunity arise that's all |
23:46 | <rkirsling> | "protip: wrap your modules in do {}" |
23:46 | <devsnek> | ljharb: https://gist.github.com/devsnek/4ca441da666caa9eff80877a97e858dc |
23:47 | <rkirsling> | is quix the nestle version of quux |
23:47 | <ljharb> | devsnek: i mean, i'd model that as `const x = do { /* foo/bar/baz */ }; if (x) { doSomethingWith(x); } else { return quix; }`, but it's tricky to talk about contrived examples |
23:47 | <devsnek> | i feel like that code, albeit with more realistic conditions, exists exactly as written in lots of code bases |
23:48 | <devsnek> | and your refactoring moves the domain of x to include the control flow |
23:48 | <ljharb> | in the refactoring, it separates "pick a value, and process it" from "return a value" |
23:49 | <ljharb> | it's subjective ofc, but that seems cleaner to me |
23:49 | <devsnek> | i mean like, what if `x` could be zero |
23:49 | <devsnek> | or what if x could be null |
23:49 | <devsnek> | or what if x could be undefined |
23:49 | <ljharb> | ok so let's say `x` can be any value, since the others have obvious answers: |
23:49 | <devsnek> | the point is that i now have to think about that or just not take advantage of an otherwise useful feature |
23:50 | <ljharb> | actually yeah for this example where the context isn't present, i'm not sure what i'd do |
23:50 | <devsnek> | i think "don't use do expressions" is a valid answer |
23:50 | <ljharb> | but the do expression refactoring you *want* there isn't really an improvement |
23:50 | <devsnek> | it just makes me sad |
23:50 | <ljharb> | yes, me toop |
23:50 | <ljharb> | but i think you shouldn't use them there anyways |
23:50 | <ljharb> | because it isn't adding clarity. it's just making a series of statements *also* have the implications of expression position. |
23:52 | <devsnek> | I think the code would be clearer with and even be idiomatic with do expressions and return |
23:52 | <devsnek> | at least based on how people use this functionality in other languages |
23:53 | <ljharb> | i'm not sure one can reliably draw conclusions about idioms in JS from idioms in other languages, but i think i understand your point |