2020-05-04 [14:40:35.0000] whenever we get a chance can we move https://github.com/tc39-transfer/proposal-compartments ? 2020-05-08 [05:07:01.0000] could someone transfer https://github.com/tc39-transfer/proposal-intl-duration-format whenever possible? :D 2020-05-14 [08:24:47.0000] have we had a "vote" in recent memory on a proposal? [08:24:52.0000] do we even have a process? [08:32:51.0000] ecma does [08:33:13.0000] tc39 itself in general is allergic to voting [08:33:46.0000] i also cannot recall where we actually voted on proposal advancement [08:35:19.0000] shu: that is why I ask [08:36:54.0000] I'm interested in taking up Collection normalization again, but not if I can't call a vote if we get stuck on naming again [09:14:17.0000] my understanding of "can't" has always been social pressures and political capital cost [09:14:44.0000] so you _can_, if that's the cost you're willing to bear [09:15:12.0000] it was a pure block, no discussion last time [09:15:47.0000] the statement was that I could change the name to what Waldemar wanted or I could not advance I even gave a presentation on why we shouldn't change that name [09:16:10.0000] so... need to be able to call a vote if we cannot even discuss it [09:49:52.0000] bradleymeck: i talked to waldemar after that, and we came up with a compromise that you rejected, iirc [09:50:35.0000] ljharb: the double property/reject if both form doesn't work since the argument was about reusability and reusing a Map would always reject [09:50:46.0000] that was only for Set [09:50:56.0000] the problem is people treating these things as if they can be passed between the 2 Set/Map types [09:51:09.0000] yes, that is where waldemar's objection came from [09:51:26.0000] which somehow naming the set property to keys() satisfies but not values() [09:51:29.0000] but just like anything else in committee, delegates' concerns are all valid even if you don't agree with them [09:51:36.0000] which is why I gave a presentation on why to use values() [09:51:43.0000] sure, and i happen to agree with your position [09:51:47.0000] ljharb: indeed, but I would like to call a vote [09:51:51.0000] but the compromise was "for Set, you can pass key xor value" [09:51:54.0000] if we cannot [09:51:59.0000] i would vote no on principle, a vote is a process failure [09:52:02.0000] even for something i want [09:52:13.0000] it'd be better to never have it than to have to vote on it imo [09:52:19.0000] key xor value causes the problem that was the argument [09:52:36.0000] i will call a vote if we get to that point, i just want to know the process [09:53:05.0000] for now we can continue discussion but it is perfectly valid to call a vote in our process just unclear how [09:53:09.0000] i think only chairs get to "call a vote" [09:53:15.0000] unclear [09:53:20.0000] it's valid for committees to have votes and to set their own process [09:53:23.0000] ours is "no votes, just consensus" [09:53:30.0000] that is not true [09:53:30.0000] so it takes the chairs to override that [09:53:37.0000] thats informal? [09:53:43.0000] which part [09:53:49.0000] the no votes, just consensus [09:54:02.0000] i mean, i don't think this is even productive. if you have to rules lawyer to get your proposal in, it's not a good proposal [09:54:15.0000] if someone is immovable, then that's that [09:54:16.0000] because of property naming [09:54:23.0000] because of *literally any reason* [09:54:43.0000] you can call my proposals not good if you want [09:54:46.0000] that doesn't change them [09:54:57.0000] discussion changes them [09:55:19.0000] right now we have a hard blocker where 2 people are blocking on a bikeshedding issue [09:55:29.0000] i believe a bikeshed level issue is perfectly good to call a vote on [09:55:50.0000] if compatibility concerns can be shown thats different [09:56:28.0000] i love your proposal [09:56:34.0000] but i don't think *any* proposal is worth a vote [09:56:58.0000] it's not just a bikeshed issue tho. his concern is the runtime interchangeability, which even if you (and i) don't think that's sensible, isn't just about naming [09:57:17.0000] and again, waldemar compromised, so at the moment, you're the only one refusing to do so [09:57:51.0000] the compromise does not address the issue raised so it should not be taken to address the issue [09:58:11.0000] that would be just taking the change to move it forward [09:58:22.0000] waldemar thinks it addresses waldemar's issue [09:58:23.0000] even if the reason isn't sensical and it persists the issue [09:58:34.0000] i believe it causes the issue [09:58:41.0000] ok but it was waldemar's issue [09:58:51.0000] and the compromise causes the issue raised [09:58:59.0000] only if you treat maps and sets interchangeable [09:59:01.0000] so it isn't really a solution even if it is a political standpoint [09:59:04.0000] which you and i both won't be doing [09:59:19.0000] treating sets/maps as reusing that object bag was the issue [09:59:20.0000] if waldemar's the only one who will run into it, and he's happy with the compromise, why does it matter if you think it solves it for him or not? [09:59:49.0000] because it causes the API to go from partial reusability to a very odd non-reusability matrix [10:00:11.0000] it's either "for maps, you can pass key and/or value" and "for sets, you can pass key xor value" [10:00:17.0000] so you can reuse any object with key xor value [10:00:22.0000] and you can't reuse any object with key and value [10:00:42.0000] which would be true with your proposal anyways, if set didn't take "key" [10:00:45.0000] and it causes more confusion on the issue of what does what, things like {...ObjWithKey, ...ObjWithValue} would both be valid in isolation but not when merged in that object bag [10:00:53.0000] (silently not mapping the keys isn't "reusable", that's a footgun) [10:01:10.0000] sets don't have keys so šŸ¤· on that point [10:01:12.0000] iow, i'd say even if Set only took value, it should still throw on key [10:01:24.0000] means the "reusability" of the options bag would be the same either way [10:01:35.0000] it's just about whether you can use *either* name with set, or just one [10:01:46.0000] we don't have any precedent on that eager throwing in the spec due to reuse nor any standard API that I know of [10:02:25.0000] adding a one off design pattern is very confusing [10:02:32.0000] throwing when you pass conflicting things? [10:02:37.0000] i'm pretty confident Intl has tons of it, for one [10:02:57.0000] also i'm quite sure we have a few in 262, let me hunt them down [10:02:59.0000] throwing when both are mutually exclusive yes, not when you provide a value that wouoldn't be used [10:03:12.0000] ah [10:03:30.0000] well, fair, but if people think it's sensible to reuse the options bag across types, then i think it's a hazard we don't want to create [10:03:42.0000] iow if there's no protections, i'd want the option names to have no overlap [10:03:51.0000] iow if map uses "value" then set can't, and vice versa [10:04:14.0000] i was fine with renaming it elements but that was another discussion about the names needing to be reused [10:04:28.0000] for sets* [10:04:42.0000] so we got dragged back into only having toKey or toValue [10:04:54.0000] right, so this is in no way bikeshedding [10:04:54.0000] we even showed all those languages that call them elements [10:05:01.0000] this is about "is it meant to be reused, or not" [10:05:12.0000] the demand was it must be reused [10:05:14.0000] if it is, then imo it needs to either work as intended, or throw [10:05:25.0000] otherwise people will reuse it and get the wrong answer [10:05:41.0000] reuse was not intended but familiarity was [10:05:55.0000] the demand of reuse is the problem and there is no room afforded [10:06:09.0000] so, I would like to present on the issues, and be able to call a vote [10:06:43.0000] i'm unclear on if the vote will be anything more than "must we allow reuse of these objects" [10:07:12.0000] the vote wouldn't be on advancement [10:07:45.0000] why would we vote on anything that's not advancement [10:07:57.0000] it makes no sense to me to vote on silencing someone's concerns [10:08:13.0000] progress is not more important than enfranchisement [10:08:21.0000] ljharb: just because a topic prevents advancement does not mean we should advance something if that topic is removed from the discussion [10:08:55.0000] right but no topic can ever be removed from discussion entirely (separate from, moving the venue between plenary and elsewhere) without effectively oppressing those who wish to discuss it [10:09:03.0000] they still have the right to vote and present their case to sway the vote in either direction [10:09:23.0000] they have the right to block advancement forever even if they don't persuade anyone else, that's how tc39 operates [10:09:35.0000] they are welcome to discuss things, but not mandate things [10:09:42.0000] ljharb: that is not in our by laws [10:10:11.0000] i can mandate we never advance any proposal indefinitely [10:10:24.0000] but that doesn't mean the committee must never move JS forward [10:14:33.0000] i think it does and also should mean that [10:15:00.0000] well we don't have consensus on that heh [10:15:04.0000] lol [10:15:17.0000] we used to, and previous consensus lasts forever until new consensus changes it [10:15:30.0000] again, i think if you have to resort to rules lawyering then you're basically trying to destroy the process that's kept things working since ES4 failed [10:15:52.0000] but as a test, i can do this for the next few meetings but this mimics what happened in Munich [10:15:52.0000] and i think if it happens, it will open the gates to many more such votes. [10:15:56.0000] how so [10:15:59.0000] correct [10:16:03.0000] which would be bad [10:16:14.0000] there weren't any votes in munich i can recall [10:16:42.0000] me breaking consensus on purpose for political reasons as a means of using our process against itself [10:17:05.0000] i mean, i could [10:17:43.0000] right but why would you want to [10:17:44.0000] but as it stands there is little actual discussion if a mandate is placed down since there is no counter argument nor balance to a mandate/demand [10:17:57.0000] how is *this proposal* that important to be worth risking the entire way tc39 works [10:18:00.0000] ljharb: because thats how oour process works and I want to show something about the process itself [10:18:10.0000] so you're setting fire to everything to make a point? [10:18:23.0000] ljharb: indeed, but to me votes are not necessarily as risky [10:18:24.0000] i don't think the devil needs an advocate [10:18:45.0000] i think the way we discuss things has become increasingly black and white and it isn't good [10:18:48.0000] it is a *good thing* that any proposal can be forever blocked by even one person, and many bad proposals have been prevented that way [10:18:57.0000] ok so then, have that discussion in good faith [10:19:08.0000] you don't need to attempt to manipulate everyone into understanding your point to do that [10:19:14.0000] i intend to, but with the ability to vote determined [10:19:27.0000] i am not seeking to manipulate anyone on my proposal [10:19:36.0000] if you are even attempting to bring about a vote, you are [10:19:49.0000] how so? we are allowed to bring votes [10:20:00.0000] what is allowed is irrelevant [10:20:11.0000] we're allowed to do lots of things. the social contract sits above that. [10:20:11.0000] but ignoring the issues of how we reach consensus is bad [10:20:26.0000] sure. and destroying the consensus process leaves those issues ignored [10:20:55.0000] destroying it seems like it might be the only way to bring balance to aspects of it [10:21:10.0000] since we cannot have any affect on demands otherwise [10:21:26.0000] so, showing demands consistently is a way to highlight that [10:21:45.0000] we'll never have it again if it's destroyed. [10:21:56.0000] and the "balance" we have *is* our consensus process [10:22:19.0000] i think you are sorely underestimating the damage that will be caused by moving to votes [10:22:25.0000] that doesn't seem balanced if single party can hold hostage the rest [10:22:31.0000] that is the balance [10:22:38.0000] convince everyone, or it doesn't deserve advancement [10:22:45.0000] so it is fair that I prevent all progress [10:22:48.0000] ? [10:22:49.0000] yep [10:22:50.0000] go for it [10:23:00.0000] better to prevent all progress forever than to let *one* bad proposal in [10:23:21.0000] (obviously, someone who obstructs in bad faith repeatedly would likely find themselves removed from the committee) [10:23:37.0000] i do not find it to be in bad faith, i just have to present arguments for each [10:23:39.0000] but in this case, as in most others, the lone objector is doing it in good faith. [10:24:37.0000] if you *have* those arguments, then you should definitely present them, always [10:24:43.0000] good faith is not the sole quantity needed for meaningful discussion [10:24:45.0000] if that means nothing proceeds, then good! you blocked bad things [10:24:51.0000] no, but it's the foundational one [10:24:57.0000] i mean, all i have to do is demand things really [10:25:10.0000] which isn't hard [10:25:21.0000] i mean we block on growing the STDLIB too large [10:25:38.0000] just stating that something adds too much complexity is semi-common [10:26:12.0000] this is all tangential though [10:26:54.0000] there was a fun Monk episode about a juror who was always voting the opposite of the rest to intentionally prevent a conclusion [10:27:12.0000] i see it as somewhat similar, preventing a conclusion in itself may be the point [10:27:13.0000] I remember in the modules group [10:27:23.0000] it would turn to a vote without consensus [10:27:32.0000] in which case why bother having the consensus check [10:27:58.0000] well without 2 way communication consensus breaks down [10:28:26.0000] my stand is that this issue has reached the end of 2 way communication. I got angry enough that I wanted to drop the proposal for quite some time [10:29:22.0000] satisfying one blocking point doesn't mean no new points come up due to that [10:29:46.0000] how far does the idea that a set is a map of T => null go in js [10:29:57.0000] for example with my complaint about how we cannot take that compromise due to it causing the exact issue that it tries to stop [10:30:18.0000] devsnek: not very far in the spec itself [10:30:36.0000] lol fair, I meant observably [10:30:47.0000] different method names at least [10:30:52.0000] not very far since values are the "keys" [10:31:15.0000] it kinda is like a T => T [10:31:55.0000] observably they are quite similar but it isn't like you can call Map methods on a Set nor are the APIs the same for get/set ops [10:32:23.0000] they just have a similar collection interface [10:32:50.0000] not necessarily generic to those 2 types, if we introduced a RadixTree or something it could have the same level of overlap probably [10:44:04.0000] if you consider Arrays our Queue/Stack collections it gets a bit weirder too [11:01:23.0000] ftr, again, i agree that trying to reuse between Map and Set doesn't make much sense [11:01:40.0000] but the compromise waldemar and i came up with is something that allows him to do it, and doesn't interfere with the rest of us who won't be [11:01:51.0000] so i'm still hopeful that's what we can go with [11:21:58.0000] it causes the issue it sought to avoid, we should not go with it [11:26:44.0000] i don't agree [11:26:49.0000] and neither does the only person with the issue, waldemar [11:27:06.0000] it seems pretty ridiculous that you're going to block a compromise because you don't think it solves "not your issue" [11:27:16.0000] i think it causes a new issue? [11:27:21.0000] of the same nature [11:28:02.0000] it isn't that it doesn't solve the issue requested, it is that it causes the issue requested [11:29:39.0000] i stand somewhat in the same boat of don't pass through proposals if they may be bad here [11:30:28.0000] that design would make part of the proposal have a problem from my viewpoint, oddly enough the exact same problem that is the reason to adopt the design [11:30:47.0000] only if you're attempting to reuse an object bag that has both key and value in it [11:30:53.0000] which can't ever work in any design [11:31:13.0000] the difference is that in the compromise, it throws for that case - in your preferred proposal, it silently does the wrong thing. [11:31:44.0000] since it can't ever do the right thing, it's just a question of whether it's a hazard, or a helpful exception [11:31:57.0000] for some reason you're arguing for it being a hazard. [11:33:07.0000] i'm arguing a variety of things, notably that the exception isn't helpful nor is the xor like behavior [11:33:24.0000] and those come from that design choice [11:33:42.0000] and that design choice comes from a mandate of reuse [11:34:46.0000] i think a vote to silence anyone's mandate will lead to a world where anyone's can be silenced, and i simply don't think it should be on the table. if you call for a vote for this, i'll call for another one asking to never again permit us to do so. [11:35:07.0000] (even it's allowed in the first place, which i suspect/hope it's not) [11:36:31.0000] not to silence, but to force a choice. it may not go in my favor [11:36:47.0000] modules wg stuff in node certainly didn't always go in my favor [11:37:06.0000] yes, i'll then be calling for a vote to disallow ever again forcing a choice [11:37:17.0000] every block matters, or none of them do [11:37:23.0000] even the ones i think are stupid [11:37:45.0000] we can argue about that certainly [11:48:27.0000] ljharb, I don't think ECMA's rules give us enough flexibility to vote on never voting [11:49:06.0000] one of the things - really the main thing - that you get from joining ECMA is the ability to vote on things [11:50:31.0000] not never voting [11:50:38.0000] never voting on silencing blocks to consensus [11:51:05.0000] even if we vote we don't need to have these be reusable that doesn't give us consensus [11:51:07.0000] but also, tc39's consensus rules mean you don't actually need to vote to have an impact [11:51:25.0000] bradleymeck: voting to allow advancement without consensus is the problem [11:51:36.0000] whether you're asking for advancement yet or not isn't the point [11:51:37.0000] it doesn't allow advancement [11:51:43.0000] then it doesn't mean anything [11:51:45.0000] it constrains design [11:51:49.0000] then it's just a straw poll [11:51:59.0000] how so? you have eliminated a design space [11:52:00.0000] the only thing we make decisions on is advancement [11:52:12.0000] that isn't true, we also vote on by laws and various other things [11:52:16.0000] ok sure [11:52:20.0000] but "design space" isn't part of that [11:52:26.0000] the design space is always whatever we all think it is [11:52:28.0000] we had a bunch of this regarding the allowance of the incubator calls at all [11:52:34.0000] which are about designs being done [11:52:43.0000] because there was concern about advancement happening there [11:52:58.0000] not just advancement but decisions [11:53:05.0000] design has already been happening outside plenary, and will continue to do so no matter who wishes otherwise [11:53:34.0000] and the only decisions the committee makes about proposals is advancement [11:53:41.0000] design decisions aren't binding [11:53:43.0000] agreed, but design is often a central part of our meetings about if a design is something we want to approach [11:53:46.0000] sure [11:53:59.0000] design decisions aren't binding why? [11:54:01.0000] but the outcome of that doesn't bind anything [11:54:04.0000] because they can change at any time? [11:54:17.0000] i mean, we could change the JS spec anytime [11:54:21.0000] decorators had lots of design decisions, that were presented to the committee, that when asking for stage 3 advancement got rejected [11:54:35.0000] design decisions are just attempts to make advancement more persuasive [11:54:39.0000] sure, but they got constrained designs in order to ask for that [11:54:49.0000] sure. from consensus. [11:54:54.0000] since consensus is required for advancement [11:55:10.0000] voting to "unconstrain" a design is voting to not require consensus for advancement [11:55:16.0000] otherwise it doesn't mean anything [11:55:26.0000] sure, but consensus on advancement is not the same as design constraints [11:55:44.0000] i'm not voting to unconstrain, unconstrain doesn't make sense to me [11:55:48.0000] they're pretty tightly related [11:55:51.0000] we have 2 competing design constraints [11:55:53.0000] sure [11:56:04.0000] and the options are either, pick one, or, deadlock [11:56:22.0000] that is my summation of the scenario, correct [11:56:25.0000] any vote would be to force one of those three options through advancement, which would be overriding consensus [11:57:03.0000] it doesn't force it through advancement? if it cannot advance it cannot advance [11:57:52.0000] i can keep bringing it to the committee but to my knowledge Waldemar doesn't participate out of plenary that I've noted [11:58:11.0000] ljharb I don't think ECMA's rules give us enough flexibility to vote on not voting on any particular topic, if a member wants to call for a vote [12:01:23.0000] i mean sure, but whatā€™s the point of voting on something that doesnā€™t actually change anything [12:02:02.0000] i can call for a vote on the committeeā€™s favorite color, but itā€™d just be a waste of time [12:02:06.0000] it seems like it does change what can be discussed to me at least [12:02:13.0000] everything can always be discussed [12:02:17.0000] a vote canā€™t change that [12:02:36.0000] otherwise every ā€œbanned topicā€ will just be another call for a vote, over and over [12:02:43.0000] a vote can certainly change what affect discussions can have [12:02:56.0000] but it canā€™t stop me calling for a vote [12:03:06.0000] so we can vote on the outcome of the same decision a thousand times in a row [12:03:17.0000] if a discussion cannot affect the design that means you have to evaluate the existing design to see if it is +/- [12:03:30.0000] could remain - [12:03:52.0000] thatā€™s a straw poll, something that delegates have considered harmful in the past when requested [12:05:35.0000] it doesn't seem like a straw poll since it does constrain things [12:06:14.0000] the proposal for example may lose its utility or capability that makes it worth advancement by making such a choice [12:06:39.0000] but currently we are arguing that a capability must be included regardless of the rest of the proposal [12:07:00.0000] any vote hurts the proposal's viability [12:07:17.0000] but it seems to me a path towards more progress than no vote [12:09:22.0000] understanding why no progress is being made could be useful, but that wouldn't by itself lead towards progress [12:09:49.0000] hence me wanting to know how to properly call a vote before investing in something that doesn't appear to have a path forward in the status quo without a vote [12:10:06.0000] progress could simply be we don't want such a proposal [12:12:54.0000] then again i've had talks with people about voting that make me feel that my opinion may differ. i was shocked to learn abstain was treated as a nay regarding spec publication [12:17:45.0000] sure, because ā€œno progressā€ is fine, ā€œprogressā€ may not be. [12:17:57.0000] this is a standard, not a product [12:18:24.0000] progress of dropping a proposal is fine [12:18:45.0000] progress can still happen even if the standard doesn't adopt things [12:35:35.0000] indeed. so why is it that important that you need a vote to make progress? [12:37:36.0000] i feel a great desire to move this proposal, if I move it such that we don't want to see it again that is preferable to the current state in my perspective. [12:37:49.0000] such a feeling might not be shared or considered important by others [12:38:27.0000] your desire to move it is outweighed, though, by your belief that the compromise i've mentioned is a bad idea [12:38:45.0000] moving it isn't simply forward towards advancement to me [12:38:53.0000] then withdraw it [12:39:15.0000] the compromise causes issues as I've stated in my perspective and repeating that you gave me a choice isn't going to remove my concerns about it [12:39:15.0000] i'd much rather see this proposal that i strongly desire withdrawn, than see a vote on it [12:39:27.0000] i'd rather see a vote and go from there [12:40:01.0000] tbh this just seems spitefully stubborn to me; you don't like someone else's intransigence, so you'll be just as intransigent. [12:40:24.0000] i'd be fine using toElement [12:40:28.0000] but that was also blocked [12:40:43.0000] we all have to do this all the time, decide between "forever stalemate", or, be the first one to cave [12:41:01.0000] i don't think that is a healthy perspective [12:41:18.0000] whether you think the way the committee has always operated or not is healthy doesn't give you license to disrupt it. [12:41:32.0000] if you want a different process, let's discuss proposals for one in good faith [12:41:48.0000] it is not a disruption, it is still part of our current form of governance [12:42:04.0000] that voting is technically allowed in no way means voting is a part of how we choose and have chosen to operate [12:42:14.0000] the only reason we vote on the spec itself is because ecma makes us [12:42:56.0000] again, you're focusing on a literal evaluation of rules, and i'm saying that's irrelevant in the face of the more important governance, the social contract. [12:43:10.0000] which is vague and nuanced and undocumented but still is how things are done [12:43:16.0000] i do not agree with the social contract being the highest priority [12:43:33.0000] i agree that votes are not what we desire to do [12:43:39.0000] but they are something we are allowed to do [12:43:46.0000] *technically* yes [12:43:46.0000] and i think we should do in this situation [12:44:08.0000] but in any context, i'd say winning a debate on a technicality is a dishonorable way to win [12:44:18.0000] even if it's necessary at times [12:44:26.0000] i do not see it as such, but you can see it as dishonorable if you wish [12:44:48.0000] i'm more concerned about the precedent it definitely will set, then about this specific topic [12:45:49.0000] well we are in a situation of stalemate like you said and I find it compelling enough to call a vote to break out of it [12:46:06.0000] repeating the various options doesn't seem to get us a direction to go with [12:48:15.0000] convincing me to not call a vote would be difficult given my options of how the API is being pulled in different design directions, helping me phrase a question to give to the committee would be helpful and likely be a different meeting than me discussing the state of the proposal [12:48:21.0000] why this stalemate and none of the previous ones? [12:51:09.0000] my personal desire for this proposal and/or being relieved of it is higher and the design constraints themselves appear to be in conflict rather than semantic problems [12:52:00.0000] I do not want to give it up as I fear that the xor design would be pushed forward which I find to have its own issues [12:52:13.0000] so I don't think abandonment is a discrete option I'd like to take either [12:52:25.0000] if you don't destroy consensus by calling a vote, you don't have to be a champion to ensure that doesn't happen [12:52:27.0000] we have passed things in the past due to absence of objectors and I have no desire for that [12:52:48.0000] when objections have been made clear in the past, the absence of that objector generally doesn't mean the objection fades [12:53:06.0000] iow, i don't think you'd have to be present for your objection on this proposal to stand [12:54:11.0000] that has not been true to my memory [12:54:24.0000] we don't actively even track those when calling a vote [12:54:27.0000] for consensus* [12:56:26.0000] no, but people bring them up in good faith [12:56:31.0000] i certainly have, at least [12:58:34.0000] mind you i might never even call a vote in this but i would want to know how to properly do so 2020-05-19 [02:50:56.0000] I want to drag up an old discussion: https://twitter.com/bmeurer/status/938260338704900096 [02:51:01.0000] Did anything ever happen with this? [02:51:42.0000] more context: https://twitter.com/bmeurer/status/938651499420422144 [02:55:14.0000] I see some arguments around SES and webcompat, wondering if there is more documentation around this [09:03:18.0000] i think if it was web compat to get rid of species, a lot of people would love to [09:03:39.0000] but imo if we can't get rid of it somewhat close to 100%, then it's better to keep the consistency [09:13:31.0000] i would love to get rid of species [09:14:56.0000] let me see if v8 has any usecounters here already... [09:15:35.0000] ystartsev: if you are also serious about removing species, i suggest that all the browser vendors coordinate on shipping counters/telemetry to get a better picture [09:15:57.0000] usually the argument for doing extra legwork is it's not worth it and we all got better things to do [09:16:14.0000] but species is worth removal because of the high security hazard borne out by past experience [09:16:24.0000] shu: ok, that sounds like a good idea. [09:16:31.0000] i need to understand the web compat issues [09:16:43.0000] can you tell me more about the security hazard? i'm only familiar with "people think it's icky and unnecessary" [09:16:56.0000] ljharb: valerie from project zero gave an invited talk at tc39 once [09:17:03.0000] project zero had a field day with project zero [09:17:06.0000] but we were discussing it also and it looks like we are supporting this for a very limited use case, but it introduces a lot of performance issuse and complexity [09:17:23.0000] the security hazard follows directly from the complexity it induces in JITs [09:17:38.0000] because JITs are optimistic optimizers, they have to manually encode all failure modes to bail out [09:17:42.0000] species is not something that's easy to get right [09:17:48.0000] and when you get it wrong, that often becomes exploitable [09:18:01.0000] interesting, ok. i must have missed that one [09:18:08.0000] shu: was it the godaddy one? [09:18:17.0000] err, i mean project zero had a field day with species, not project zero :) [09:18:19.0000] or maybe europe last year [09:18:23.0000] ljharb: i don't remember, let me grep the notes... [09:18:29.0000] oh thanks, i could do that too i suppose [09:18:35.0000] my recollection is more than 2 years ago [09:18:48.0000] ah k, no worries [09:19:06.0000] the main problem is array species over other species [09:19:17.0000] because so much work goes into optimizing array access [09:20:35.0000] hm maybe there were no notes for this [09:20:39.0000] am i misremembering... [09:21:41.0000] ah i misremembered the name of the researcher, my bad: Natalie Silvanovich [09:22:16.0000] ah i remember natalie's presentation, but i didn't recall species as a big part of it as much as indexed prototype access [09:23:05.0000] subclassing was also big part of it [09:26:40.0000] ljharb: https://docs.google.com/presentation/d/11fkQeEisoszNGF8SrautVT1ltSnsQBWRxJ4usoc-g_o/edit#slide=id.g2b34aaab4a_0_10 look at slide 4 [09:26:43.0000] trail of tears [09:27:21.0000] we should just have a script that auto-removes features once it accumulates more than N CVEs and has less than M% uptake in the wild [09:28:31.0000] haha [09:28:54.0000] ime CVEs are mostly false positives, so that might be a bit too hair-trigger :-p [09:29:05.0000] but yeah, let's exterminate the species [10:23:16.0000] \o/ [10:23:20.0000] should i put it on the agenda? [10:24:46.0000] ystartsev: sure, happy to collaborate on it [10:25:10.0000] ok [10:25:29.0000] lets set up a call late this week or early next week shu ljharb ? [10:27:07.0000] do we need a call? [10:27:17.0000] well, maybe not [10:27:22.0000] (i mean it seems like we're already all on the same page, i meant more like be happy to help do slides) [10:27:24.0000] just trying to think of how to organize it [10:27:27.0000] ah ok [10:27:29.0000] well [10:27:42.0000] yeah that sounds good [10:27:43.0000] has it gotten any more CVEs since that presentation [10:28:06.0000] dunno, worth asking about [10:43:20.0000] ystartsev see https://github.com/tc39/ecma262/issues/1313 [10:44:05.0000] I would also love for the committee to get a coherent position on Symbol.species because the current state of things leaves us discussing it unproductively every time it comes up. e.g with Set.prototype.union [10:45:29.0000] ystartsev: also in the space of gauging backwards-incompat changes, i added a counter to v8 to measure use of the vars redeclaring catch bindings [10:46:11.0000] Bakkot: it seems like what ystartsev and i are thinking of is an even more radical version of domenic's suggestion in that issue, is that right? [10:46:32.0000] Domenic's proposal includes "Consider removing it from any existing methods where doing so would be web-compatible", so it's covered by it [10:46:33.0000] but yeah [10:47:01.0000] oh i think v8 already has species use counters, let's see... [10:47:12.0000] it has things with species in the name [10:47:22.0000] i have no idea what they imply though [10:47:58.0000] also the charts seem broken [10:49:36.0000] hm indeed the charts seem broken [10:50:08.0000] i guess *all* charts are broken? [10:50:10.0000] oh, no [10:50:17.0000] use counters seem like they'd be messed up by polyfills [10:50:27.0000] the regex `Symbol.match` one was [10:50:44.0000] i remain convinced that 100% of the usage of Symbol.match on a non-regex was core-js feature-testing Symbol.match [10:50:54.0000] Bakkot: polyfills of @@species? [10:51:02.0000] V8SloppyMode was reporting 120% of page loads on may 1st [10:51:12.0000] shu yeah [10:51:29.0000] _i am technically on family time now so i will look at this tomorrow_ [10:51:29.0000] or things testing its existance [10:51:39.0000] shu: https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js#L215 https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js#L486-L502 [10:51:43.0000] oh, i misunderstood [10:51:53.0000] messed up in the sense of false positives [10:51:57.0000] yes [10:52:17.0000] shu: Bakkot i was thinking something along the lines of domenic's suggestion, but this was raised in spidermonkey discussions and I wanted to see what was possible. It is a pain point and seems to have limited use cases, and a huge cost [10:52:20.0000] if you can find a way to delete core-js and es5-shim/es6-shim from use counters, we'd get much more deleteable results i suspect [10:52:23.0000] the problem of the data being busted right now is worse :) [10:52:42.0000] ljharb: i think we scrub that level of info from the data [10:53:12.0000] ystartsev: agree 100% on huge cost [10:53:23.0000] like the amount of slow paths and extra guards that v8 has here is really not worth it [10:53:34.0000] yeah the perf impact for us is huge, [10:53:47.0000] sure it's "done" now, but it has cross-cutting concerns for future features as well [10:54:05.0000] _gotta duck out_ [10:54:10.0000] have a good night [10:59:20.0000] shu: yeah i think you're right, which is unfortunate because it means there's no way for me to actually fix Symbol.match [11:00:02.0000] i'm wondering if the chart for these species use counters is busted because there is literally *no* data [11:00:09.0000] like, they have never been hit [11:32:27.0000] can you ask the owners to read the data from the database directly? [11:33:59.0000] shu: they have proper readings on the main popularity page [11:34:55.0000] devsnek: Bakkot: i'm reading the data directly right now in the google-internal page [11:35:01.0000] i am kind of confused [11:36:39.0000] so the popularity page says it's the % of page loads that use the corresponding feature at least once... [12:31:31.0000] i feel like i need a data scientist for this [12:37:41.0000] the most conservative view i've been able to distill is that Array @@species in particular have decreased in time but still is around ~0.006% of all page views, which is actually moderately risky [13:40:03.0000] shu: is there any sort of domain masking behind the scenes to know how many domains are affected? [13:41:07.0000] also i'm curious about what makes this a conservative vs normal view [13:41:48.0000] bradleymeck: conservative because it's just based off page view hits [13:42:31.0000] bradleymeck: there is info on domains affected: bottom of https://chromestatus.com/metrics/feature/timeline/popularity/1391 [13:45:33.0000] that counter is specifically for modifying Array[Symbol.species] [13:53:26.0000] shu: quick get/set trap on some of these and a lot seems to be from a Zones polyfill? [13:54:24.0000] sec just moving to set trap [13:55:10.0000] i couldn't parse your last two sentences :) [13:56:00.0000] shu: there appears to be a semi-popular library common across a variety of these sites [13:56:24.0000] ah, now i got it, Zones like domenic's old zones proposal? [13:56:29.0000] like that ambient context thing? [13:56:44.0000] fascinating [13:57:10.0000] i'm going to start a doc documenting what web compat data we have now to gauge risk, since page views alone makes it look risky, but my hunch is that it isn't [13:57:22.0000] bradleymeck: are you also interested in killing off @@species? [13:57:49.0000] shu: i once got asked in a JS meetup what I regret most about JS things that landed, I said @@species [13:58:02.0000] my man [13:58:17.0000] unclear on origin, but salesforce has a different lib doing typed array detection to polyfill a Node API oddly [13:59:33.0000] TYPED_ARRAY_SUPPORT is the token that is shared around all of this regardless of the minification... checking [14:03:37.0000] shu: thats a lot of code on github using this pattern, i'm surprised it is that low of a counter [14:03:59.0000] but one of the main libraries in question at least on github glance https://github.com/feross/buffer/commit/753c064753a174455701cabd9e9feadff7fc768d removed that code semi-recently [14:05:14.0000] what is Buffer? [14:05:27.0000] that use counter is specifically for the Array constructor, not all uses of @@species [14:09:43.0000] polyfill of node buffers [14:10:16.0000] its automatically used by webpack and such [14:11:38.0000] shu: https://github.com/zloirock/core-js/blob/6e3106817aa46919273b80d6f961e75a65967d22/packages/core-js/internals/set-species.js is being hit a lot too, but trying to read through core-js minified stuff is making my head hurt [14:13:43.0000] bradleymeck: https://unminify.io/ will probably make it a lot more readable [14:14:42.0000] bradleymeck: "hit a lot" meaning? [14:14:42.0000] Bakkot: i pretty printed it, does that do more? [14:15:15.0000] bradleymeck yeah it does stuff like `foo && bar()` -> `if (foo) { bar(); }` [14:15:18.0000] shu: E.G. https://www.bmw-m.com/en/index.html , `a("./$.species")(Array)` always gets shimmed? [14:15:40.0000] but reading that code is... very abstract [14:16:27.0000] what are you using to define the set traps and make sure that gets loaded at page start? [14:17:20.0000] replacing Object.defineProperty and putting a getter/setter on Array[@@species] [14:17:53.0000] i'm asking the more mechanical question: how do you get that to run before any other scripts run? [14:18:01.0000] i'm assuming something in devtools lets you do this? [14:18:54.0000] shu: https://gist.github.com/bmeck/9633a2459ffe87b62feff1304a342db4 [14:19:01.0000] i put a local override in and refresh [14:19:11.0000] just at top of page html [14:19:16.0000] ah, neat [14:20:54.0000] i wonder if firefox has something like local overrides [14:22:11.0000] wouldn't be too bad to implement :ponder: [14:22:46.0000] honestly i should just write an extension to be more thorough than a local override, probably missing plenty of iframe shenanigans [14:27:38.0000] why is core-js a million 2-line files [14:27:39.0000] what is this [14:29:20.0000] :jazz hands: [14:34:20.0000] my question is really why does it shim it if it exists [14:34:25.0000] yes indeed [14:35:41.0000] shu: does that usage counter take into account if the value is unchanged? only descriptor bits? [14:36:04.0000] it does [14:36:05.0000] `if (DESCRIPTORS && C && !C[SPECIES])` [14:36:45.0000] bradleymeck: it's not that smart, that use counter logs any time @@species is passed as the property key to a set or define on the Array constructor [14:37:42.0000] devsnek: sitting at a debugger statement where Array[@@species] === Array right before it defineProperties it to a weird get() {return this} [14:38:58.0000] weird [14:39:00.0000] https://usercontent.irccloud-cdn.com/file/hLWcbCL6/replacing-species-anyway.png [14:39:30.0000] bradleymeck: so using your local override i've been pondering libertypr.com [14:39:37.0000] i think it is bundling a very very old version of core-js [14:40:38.0000] bradleymeck: at 0.7.0 of core-js, you have this file: https://github.com/zloirock/core-js/blob/9ed55e682ff0a9814b6bb0c15c8c058bdfb8d954/src/%24.species.js [14:40:39.0000] so, the weird thing is it is replacing it with ~ the spec [14:40:55.0000] these names match up to the strings i see in the libertypr.com sources [14:41:01.0000] it is effectively not doing anything [14:41:23.0000] i have no idea what $.FW is but it's always defining a @@species with a getter that returns "this" [14:41:25.0000] so... awesome [14:42:24.0000] shu: thats the spec behavior tho [14:42:36.0000] https://tc39.es/ecma262/#sec-get-array-@@species [14:42:53.0000] bradleymeck: i'm saying core-js is explicitly installing a getter regardless of if C[@@species] is already set [14:42:58.0000] very old core-js is, anyway [14:43:12.0000] which is what these sites are bundling, i guess, and that's what's hitting a lot of the counters [14:43:32.0000] i think we're just violently agreeing? [14:43:38.0000] this is "good" in that the shim is doing something useless [14:43:42.0000] and is not a compat risk [14:43:49.0000] probably, i'm kind of confused/angry/relieved [14:44:09.0000] that's just this one site [14:44:27.0000] shu: i'll script out the whole list and handle iframes if you really want that data [14:44:36.0000] i think if we do enough manual legwork and see that most of these counter hits are in fact benign [14:44:39.0000] but šŸ¤· [14:44:56.0000] i am willing to make the case internally to try this backwards breaking thing [14:45:05.0000] what would the ideal use counter be testing for? [14:45:07.0000] would be good to nail down the exact semantics of our check we want [14:45:13.0000] yeah [14:45:35.0000] that {return this} function body XD [14:45:40.0000] i feel like it's not on the "set" but on the "get" [14:46:02.0000] probably, if you do a get on an Array subclass but it isn't the `this` [14:46:14.0000] or ... perhaps if it isn't Array? [14:46:33.0000] yeah i think the actual counter is too expensive to ship [14:46:35.0000] it's something like: [14:48:05.0000] trap every call to get @@species in a built-in function. if `this` in the get is one of {Array,Promise,...}, count a use if the return value of the get isn't the built-in constructor, else count a use (i.e. the subclassing case) [14:48:53.0000] thats probably a lot of checks given all the usage of array fns [14:50:22.0000] bradleymeck you have `args[1] =a== Symbol.species` [14:50:27.0000] which seems like... not what you want [14:50:52.0000] Bakkot: for testing when they replace Symbol.species? [14:51:03.0000] note the `=a==` [14:51:13.0000] ah, probably not [14:51:33.0000] oh, not in the gist [14:51:45.0000] thats me poking around and accidentally typing in devtools [14:52:12.0000] https://gist.github.com/bmeck/9633a2459ffe87b62feff1304a342db4/edit is the code i run to breakpoint it [14:52:16.0000] good good [14:53:04.0000] shu: is there any point in crawling those sites to manually test that counter? [14:53:53.0000] mtg, gimme 20 mins [14:54:08.0000] ill be making dinner, will reply async [14:54:18.0000] unsure if meeting or magic the gathering [14:54:34.0000] do i strike you as a mtg player [14:55:06.0000] you could probably make a comic sans deck [14:55:25.0000] everyone in this channel is a possible mtg player [15:13:21.0000] bradleymeck: by crawling those sites to manually test, do you mean one of us scripts this? [15:21:03.0000] I have stuff already in place with minimal mods to run tests like this [15:21:29.0000] shu: yes [15:22:08.0000] bradleymeck: i am a noob at scripting the browser, but i would like to try this for the sites in the data set [15:23:22.0000] Sure, just let me know all relevant stats you want I'll revive the crawler we use [15:23:39.0000] ideally this has enough smarts to even know if it looks like an old core-js shim [15:24:01.0000] It will be slowish so a few extra counter points isn't that expensive [15:24:29.0000] like having $.species on the stack [15:24:33.0000] Just fn src of the getter enough? [15:24:50.0000] bradleymeck: i will spend the rest of the day writing up a google doc capturing what i know and next steps and share it with you and yulia [15:24:56.0000] $.species gets minified sometimes but we can count it [15:24:59.0000] we can work out the crawler details from there [15:25:02.0000] K [15:31:06.0000] if you make this crawler reusable enough that i can use it for other feature tests, i would be very happy about that [15:51:36.0000] I'll ask, I don't see why not [15:58:52.0000] there was a bigquery db somewhere [15:59:02.0000] with a lot of useful data [15:59:08.0000] it might've been google's [16:19:59.0000] do you mean HTTP Archive? that's google's [16:20:07.0000] that's where those urls came from [16:21:02.0000] but what i understand bradleymeck to be proposing is something that does more than crawl, like it'd try to script a browser to actually load the front page with a user script and observe some behavior? [16:21:34.0000] (because if not, then yeah, we'll just run bigquery oh HAR) [16:40:12.0000] Our internal http-interceptor uses debug protocol on a browser instance, not parsing HAR 2020-05-20 [01:12:45.0000] ^ Ditto about the crawler bradleymeck [15:00:30.0000] Should https://github.com/tc39/proposal-intl-numberformat-v3 be listed in https://github.com/tc39/proposals/blob/master/stage-1-proposals.md ? [15:12:20.0000] davepoole: it's listed here: https://github.com/tc39/proposals/blob/master/ecma402/README.md [16:43:52.0000] i love how SAB has @@species [16:44:19.0000] why, please, go ahead and subclass SAB 2020-05-21 [17:26:37.0000] bradleymeck: Buffer seems like it might be a big issue here, or at least the Buffer polyfill [17:31:08.0000] I could believe it, but I also am skeptical of it's actual usage [17:31:57.0000] The only big API people use on it is slice from node side which is what it is emulating [17:34:08.0000] bradleymeck: slice is already overridden; i think usage of .map and .filter on Buffers should be rare [17:34:31.0000] bradleymeck: so that leaves .subarray, which is the same semantics as Buffer#slice in node at least [17:34:42.0000] any intuition on whether people use subarray over slice? [17:35:20.0000] mmmm, i think slice is the most common, but no clue it only takes 1 super popular package to skew results [17:36:01.0000] well, for node itself i guess it's "fine" so far as its buffer.js is updated in lockstep with V8 releases [17:36:04.0000] i think we could see usage % of that polyfill and then go back and do a more in depth check of what methods are being used of it [17:36:30.0000] oh? how do we see that? [17:37:49.0000] shu: we can check Node's gzemnid DB to scan the npm registry then do popularity queries [17:37:54.0000] but for old deploys it won't help [17:38:17.0000] i am more interested in a crawl of the pages with the buffer polyfill on w/e browser domain [17:38:32.0000] hm [17:38:43.0000] i am not good enough for http archive but it seems possible to craft some kind of query [17:38:52.0000] err, good enough to craft a query for http archive [17:39:33.0000] maybe MylesBorins has experience enough here if you can craft the hueristic to look for [17:39:45.0000] i know he has done some bigquery stuff before [19:43:02.0000] shu: the buffer polyfill is pulled in any time literally any npm module references `Buffer` [19:43:29.0000] tape, or deep-equal, or qs, i forget which, has to some kind of crazy hack to have an `isBuffer` impl without forcing the entire buffer polyfill into people's bundles [19:44:05.0000] indeed [19:44:14.0000] the question is whether they use the inherited methods that create new Uint8Arrays [19:44:30.0000] s/they/there is significant [20:08:11.0000] idk why one would map or filter a buffer [20:41:58.0000] yeah that's my hunch too, it comes down to subarray [20:44:33.0000] subarray is popular [20:44:41.0000] well idk if its popular in those projects [20:44:49.0000] but people use it to pass to textdecoders and stuff [20:44:52.0000] or textencoders [20:44:54.0000] one of those [21:36:35.0000] passing to TextDecoder would be fine as itā€™s just treating the subarrayed Buffer as a Uint8Array [21:36:52.0000] unless this is some Node-specific TextDecoder that takes Buffers [21:43:58.0000] no its standardized [09:17:15.0000] rkirsling! thanks, I wasn't sure what the expectation was. :) [12:40:52.0000] bradleymeck: ystartsev: littledan: fyi i wrote up a taxonomy of subclassing (thanks to domenic): https://github.com/syg/proposal-rm-builtin-subclassing#taxonomy-of-subclassing [12:41:56.0000] i'm still poking around on if there are any actual usages except feature detections before finalizing a detection script [12:48:08.0000] we need more proposals with `rm` in the name [12:49:58.0000] I like the 抟 [12:50:21.0000] :) [12:50:48.0000] why is delegating to `this.constructor` not sufficient [12:51:01.0000] what does "sufficient" mean? [12:51:11.0000] said another way, why did @@species ever exist [12:51:27.0000] because MS tried to ship just delegating to `this.constructor` and it broke stuff [12:51:29.0000] devsnek: well I've uncovered all sorts of hellish stuff with false positives [12:51:34.0000] yea ^ [12:51:42.0000] aw [12:51:55.0000] Array.prototype.map.call(window, String, 1) is a thing apparently [12:52:00.0000] IDK WHAT IT MEANS [12:52:04.0000] what are you doing [12:52:15.0000] to be clear: broke stuff that expected, pre ES6, to always return e.g. an Array [12:52:36.0000] [].slice.call(arguments) is also a big thing, same for NodeList [12:52:42.0000] lots of those [12:52:50.0000] ok and for the static promise methods [12:53:10.0000] i feel like people rely on those doing delegation to `this` [12:53:20.0000] those were added in ES6 and were given the delegation treatment out of consistency [12:53:34.0000] are there actual subclasses of Promise that depend on the delegation in the constructor methods? [12:54:18.0000] i'm fairly sure i've seen that [12:54:21.0000] but i'd have to double check [12:54:32.0000] i haven't really, citations would be good [12:55:02.0000] wowsers, I'd finished reading through this before but I didn't realize about Type III [12:55:09.0000] extending Promise is super rare with a bunch of regexp checks against httparchive [12:56:00.0000] Type III and IV are the "delenda est" types but unfortunately Type II already incurs a big cost :( [12:56:09.0000] yeah [12:56:18.0000] dan proposed an alternative in issue #1, would be interesting to think through if we can support Type II somehow without the burden [12:59:12.0000] shu: there's another category, not yet relevant, which is whether built-in methods delegate to property lookups on their _arguments_, rather than looking into their slots directly (e.g. would (new Set).union(myFakeSet)` look up `Symbol.iterator` on `myFakeSet`) [12:59:50.0000] ah interesting [13:00:26.0000] is that really a species concern? [13:00:35.0000] or just a protocol concern [13:00:45.0000] no, not really, but neither is type IV in the above taxonomy [13:01:03.0000] well, is it a *subclassing* concern [13:01:19.0000] I have more feelings about this one because you can't work around it by overriding enough methods, which you can for all the other types [13:01:58.0000] the reason Type IV is included is because actions on builtin regexps are unreasonably difficult to optimize because there are hooks on via `this.exec` or whatever [13:02:46.0000] Bakkot: i can squint and look at your type and sweep it under the rug as "not harmful" in the way that RegExp[@@match] isn't so bad if you just look at it as a protocol that String uses, and not RegExp built-ins themselves use [13:03:40.0000] Bakkot: union(arg) accepting any iterable arg is reasonable and not too much burden for implementations [13:03:55.0000] conceptually you basically specced a union that takes Sets, and an overload that takes iterables [13:04:35.0000] you have a single decision point of going to the slow path that's easy-ish to stay on [13:05:17.0000] shu: `difference` is maybe a more interesting case, because there you want to invoke `.has` on your argument, not `[Symbol.iterator]` [13:05:22.0000] ah [13:05:32.0000] yeah that's harder [13:05:35.0000] still a protocol, just using a named property instead of a symbol one [13:06:01.0000] (I guess a third way is to add `Symbol.has`) [13:07:00.0000] i think my preference here is to be to require explicit casts via Set() [13:07:06.0000] s/to be// [13:07:15.0000] i actually prefer constructor hooks, a la bradley's map proposal [13:07:30.0000] remind me what that is? [13:07:32.0000] then no methods need to be overridden ever, you'd just provide different hooks [13:07:44.0000] like `super(iterable, { toValue() {} })` etc [13:08:14.0000] hmm, seems scary [13:08:17.0000] for example, i could see Map and Set accepting a hook that lets you use something besides SameValueZero for comparison [13:08:27.0000] shu: :(, that means you can't use a subclass without big-O penalties [13:09:00.0000] Bakkot: yeah, i can live with a protocol [13:09:16.0000] ljharb historically "you can't add functionality on top of the built in things, you just have to trust the language designers to have added all the things you might need already" has not been a good philosophy, I think [13:09:29.0000] oh totally agree [13:09:32.0000] but might ask there be explicit in-spec fast paths then for passing actual Sets [13:09:32.0000] and i think you should be *able* to add new things [13:09:49.0000] but i also think that all the use cases of *overriding* existing things could be done with hooks [13:10:08.0000] shu: I feel like engines could just do the actual property gets, confirm they're the built-in ones, and then go to the fast path [13:10:16.0000] no? [13:10:26.0000] if that's so I wouldn't think the spec would need to add the fast paths [13:10:48.0000] Bakkot: i was thinking the fast path would have no observable get of .has [13:11:01.0000] Bakkot: it'd consult the internal slots of the Set only [13:11:14.0000] ljharb of course they could be done with _enough_ hooks, but, like, I don't think we should trust that we can add the things one might reasonably need [13:11:55.0000] ljharb as another example I think it is perfectly reasonable to make a thing which is not a Set at all under the hood, but conforms to the interface, which could be passed as an argument to Set.prototype.union [13:12:04.0000] Bakkot: i totally agree that hooks would never be sufficient [13:12:15.0000] i don't agree with that last point tho [13:12:28.0000] things that accept arraylikes, versus things that accept arrays, are different things [13:12:31.0000] shu that would make me sad but it wouldn't be the end of the world [13:12:58.0000] ljharb Arrays are magic; they are not a good example to follow. [13:13:18.0000] ok, things that accept thenables are different than things that accept promises [13:13:27.0000] or toStringables vs strings, etc [13:13:29.0000] Bakkot: isn't this the same reason RegExp subclassing is bad now? maybe difference reasonly only has one such override point with `.has`, but it's a death by thousand cuts kind of thing [13:13:44.0000] hm something went wrong with the input field there [13:13:59.0000] Bakkot: at any rate it's also kind of that ^ that it's fine if "the interface" is one method, but not fine if it's N [13:15:16.0000] shu I think the tradeoffs are different, basically. I don't think there's that much utility in making a fake regexp, and there people care about absolutely maximum speed, whereas there is a lot of utility in making a Set-like, and the speed is not quite so much of a concern [13:16:03.0000] ljharb I basically do not understand what analogy you are trying to make [13:16:10.0000] hm, ok [13:16:23.0000] Bakkot: crucially, a lot of utility in making a Set-like by actually subclassing Set and overriding e.g. has [13:16:27.0000] not a completely custom Set-like [13:16:46.0000] (there's also utility in doing that and not having `Set.prototype.has.call` provide different behavior) [13:17:41.0000] shu two things: 1.) if you do that, then the fast-path has to use the userland has, and 2.) I don't agree actually; I think the "wraps a Set" vs "extends Set" distinction is basically an implementation detail and either approach is reasonable [13:17:59.0000] ljharb I don't think users should think about Set.prototype.has.call basically ever [13:18:46.0000] shu s/the fast path has to use the userland has/there cannot be a fast-path which avoids observable .has lookup/ [13:20:02.0000] Bakkot: hm, i'd have to think more about the "speed is not quite so much of a concern" [13:20:13.0000] ofc none of this is an issue if speed is not a concern [13:20:37.0000] well, not quite true [13:20:52.0000] but this would all be decidedly less concerning, at least [13:23:17.0000] Bakkot: reading through the current Set code i remain leaning towards another way to provide custom 'has' functionality than overriding the method [13:23:41.0000] Bakkot: one can reasonably expect Set#delete or Set#add to invoke Set#has, but it does not [13:24:04.0000] > one can reasonably expect Set#delete or Set#add to invoke Set#has [13:24:06.0000] ... can one? [13:24:15.0000] by contrast, the set constructor itself does invoke Set#add [13:24:28.0000] that is certainly a good point [13:24:55.0000] (which falls under your type 4 taxonomy) [13:25:32.0000] shu: but also, as I say I am more concerned with invoking these methods on _arguments_ than on `this`; for `this` you can always get around it by overriding all the methods [13:27:19.0000] i can certainly see the argument that different data structures have different expectations of being subclassable piecemeal [14:26:03.0000] shu: btw you mentioned trying to deal with a single method as an experiment, but I think for us it's ArraySpeciesCreate as a whole that results in greatest implementation complexity [14:27:08.0000] rkirsling: yeah, good point, should've been more precise in what i meant [14:27:52.0000] (mind you I'm not used to digging into this particular area so there could be more stuff that's just not jumping out as obviously, but most of the rest just seems to be reflecting the spec itself, whereas our DFG has watchpoints for array species) [14:27:58.0000] rkirsling: it'd be good to look at the diff of an implementation of a single builtin under two scenarios: both types II and III removed, and only type III removed [14:28:28.0000] yeah that's fair [14:28:30.0000] rkirsling: for V8 at least, the stuff that looks out for species looks out for more than species, despite the name, which might be a gotcha [14:28:58.0000] ahh yeah, could be [16:07:57.0000] TabAtkins: wow, that's the most positive subdiscussion I've seen in the pipeline repo in recent memory [16:08:02.0000] #yay [16:10:32.0000] yeah it's weird how heated people get [16:13:32.0000] rkirsling which? [16:14:15.0000] last two comments at https://github.com/tc39/proposal-pipeline-operator/issues/167 [16:15:14.0000] makes me kinda excited [16:15:19.0000] let's do this [16:16:25.0000] TabAtkins: is the style you prefer the `x => await => y` form where x and y are functions? or is it a different one [16:16:40.0000] That's F#-style, so no [16:17:02.0000] hm, ok [16:17:22.0000] I'm going to be advocating for plain-jane Hack-style, where the RHS is just "any expression", and there's a binding for the # variable over it (bound to the LHS). [16:17:24.0000] littledan's frameworks outreach call today seemed to prefer that one iirc [16:17:26.0000] that's what point (6) is about [16:17:39.0000] littledan is going to be advocating for that, yeah [16:17:51.0000] so you'd do `await #` if that's the semantic you wanted? [16:18:04.0000] Put the await wherever you need it, yeah. [16:18:07.0000] (i don't like # as the placeholder choice there but obv that's a stage 2 debate) [16:18:15.0000] (Rather than being forced to put it by itself on a pipeline step) [16:18:19.0000] right [16:18:43.0000] `val |> async(#) |> foo(await #)` if that's the clearest way to express your intent, for instance [16:18:58.0000] and for those who prefer the F# style, you could immediately invoke "the function you used in F#" to use it in "hack-style"? [16:19:04.0000] `val |> asyncFn(#) |> foo(await #)`, rather [16:19:18.0000] Yeah, you just call it like you would in normal JS. [16:19:46.0000] If normal JS would have you do `let x = foo(1,2)(3)`, the hack-style pipeline does `3 |> foo(1,2)(#)` [16:19:51.0000] `|> await` is certainly the part that makes me frown the most about the other approach [16:20:11.0000] your point (7) is strangely compellingly worded for being as obvious as it is though [16:20:21.0000] TabAtkins: and expressions are lazily or eagerly evaluated? [16:20:27.0000] TabAtkins if you present on this, can you contrast to just writing `$ = val; $ = asyncFn($); $=foo(await $)`? [16:20:33.0000] rkirsling: It's apparently not obvious! I've polished it over time talking with other people! [16:20:50.0000] :) [16:20:55.0000] good work [16:21:00.0000] ljharb: eagerly, it's *exactly* as if you'd taken the LHS and put it in the RHS in place of the # [16:21:16.0000] (module the fact that the LHS is only executed once even if you use # multiple times) [16:21:33.0000] TabAtkins wait that would be very surprising to me [16:21:37.0000] lazily seems the obvious thing [16:21:44.0000] yeah that surprises me too [16:21:45.0000] Bakkot: Basically that exact example is the main *competitor* to pipeline ^_^ [16:21:53.0000] wait now i'm surprised [16:21:56.0000] wait what does lazy mean in this context [16:21:58.0000] that's the same in every pipeline [16:21:59.0000] if I don't hit a step in the pipeline, I don't expect to see side effects from the hitting that step [16:22:00.0000] `console.log(1) |> await # |> console.log(2)` [16:22:07.0000] OH [16:22:11.0000] i would expect 2 not to log until after the tick [16:22:14.0000] ok yeah [16:22:14.0000] yeah I think there was a misspeak? [16:22:15.0000] that's lazily [16:22:26.0000] (i believe) [16:22:49.0000] Yeah, LHS is executed, *then* pipeline body is. [16:23:02.0000] You literally can't execute the RHS until you're done with the LHS. [16:23:07.0000] right [16:23:13.0000] TabAtkins re "that exact example is the main *competitor* to pipeline" - right, so, contrasting to the main competitor seems like it would be valuable in your presentation [16:23:16.0000] its like normal evaluation [16:23:19.0000] presumably they're parsed eagerly but evaluated lazily [16:23:21.0000] right [16:23:24.0000] except with a different delimiter [16:24:06.0000] i'd be interested to see some codebases where pipelining comes in handy [16:24:10.0000] Bakkot: Yup, explaining the benefit of pipeline over "just write JS without pipeline" is of course a necessary piece of this ^_^ [16:24:17.0000] i don't think i've ever had something that felt ungangly and in need of a pipeline [16:24:27.0000] ungainly* [16:25:16.0000] TabAtkins well, it's more dramatic for Hack style than F# style, since in F# style you are composing functions directly, whereas in Hack style you're just having a binding created for you - that is, Hack style is much closer to that sample than F# style is [16:25:28.0000] The benefit actually ends up *relatively* small; it's not a world-changer like arrow-function syntax. But it does let you write some common code patterns in a cleaner way, and importantly, lets you get the benefit of doing complex manipulations of a value via multiple statements, but in an expression context. [16:25:41.0000] I think anywhere you have 2+ nested calls it could be potentially nicer [16:25:46.0000] devsnek: react HOCs is a big one [16:25:57.0000] devsnek: currently it's `withA(withB(withC(withD(Component))))` [16:26:07.0000] yuck [16:26:12.0000] "lets you get the benefit of doing complex manipulations of a value via multiple statements": mm, sometimes, but only if you don't need intermediate values multiple times; do expressions seem like a much more general solution to that problem [16:26:16.0000] like trying to extend multiple things? [16:26:20.0000] devsnek: `Component |> withD |> withC |> withB |> withA` is much clearer [16:26:25.0000] devsnek: it's not extending, it's composing/wrapping, but yes [16:26:37.0000] HOC is a "higher-order component" [16:26:55.0000] seems like a weird pattern [16:27:12.0000] Bakkot: Yup, cut the gordian knot of do exprs and I'd be okay with dropping pipelines ^_^ [16:27:25.0000] devsnek: it's also how every single usage of redux in the react world worked, prior to hooks. it's a common pattern. [16:27:53.0000] i've never really done any frontend stuff [16:28:19.0000] because i hear that patterns like HOC are a thing [16:28:23.0000] lessee, from the HOC documentation: [16:28:25.0000] https://reactjs.org/docs/higher-order-components.html [16:28:36.0000] i really want to move do expressions forward [16:28:36.0000] const CommentListWithSubscription = withSubscription( [16:28:36.0000] CommentList, [16:28:37.0000] (DataSource) => DataSource.getComments() [16:28:37.0000] ); [16:28:41.0000] > the HOC doc [16:28:41.0000] FTFY [16:29:07.0000] devsnek: just `do` it [16:29:11.0000] would be `const CommentListWithSubscription = CommentList |> withSubscription(#, DataSource=>DataSource.getComments());` [16:29:19.0000] but people think that control flow inside a block that is part of a do expression is not good [16:29:50.0000] devsnek some people (like me) think that, but other people disagree [16:29:56.0000] I can *definitely* see how confusing that would be with another withX() wrapper or two [16:29:57.0000] devsnek completion values are also a sticking point [16:30:12.0000] devsnek though, it occurs to me you could just require the last statement in the `do` be an expression, so it'd be obvious... [16:30:25.0000] iirc completion values were less of a blocker and more of a "fine assuming we make sure completions in the spec are clean" [16:30:35.0000] devsnek ehhh: https://github.com/tc39/proposal-do-expressions/issues/21 [16:31:22.0000] i wouldn't like to force that [16:31:27.0000] devsnek: i mean, it'd be useful in express middlewares too, i'd imagine [16:31:37.0000] isn't express middleware flat [16:31:43.0000] `app.use(x); app.use(y)` [16:31:44.0000] atm yes [16:31:52.0000] Bakkot: Forcing that means I don't get the nice clean "turn if() into an expression by wrapping it in a do{}" functionality :( [16:31:55.0000] (ftr i also think control flow in do expression blocks is bad) [16:32:04.0000] TabAtkins: yeah i want that too lol [16:32:32.0000] TabAtkins hm, true [16:32:37.0000] in any case my argument was that people use repls [16:32:45.0000] which have the same semantics as do expressions [16:33:02.0000] and aside from block/object parsing, they seem ok with how those work [16:33:34.0000] people also use completion of scripts with the node vm module [16:33:54.0000] people are OK with repls because they don't care what the completion value of a declaration or a loop is [16:34:07.0000] but it tells them what it is [16:34:08.0000] ^ that [16:34:11.0000] sure [16:34:15.0000] and they don't go on twitter raving about it [16:34:16.0000] but that doesn't mean they pay attention to it [16:34:16.0000] devsnek yeah but that doesn't mean they know [16:34:17.0000] afaik [16:34:38.0000] lol the completion value of `console.log` is undefined, and that actually *does* confuse a ton of people, they ask on irc a lot [16:34:39.0000] I will say that I've written plenty of for loops in my repl and never once realized consciously that it even has a value [16:35:15.0000] github puts an enormous green checkmark on the highest rated comment now [16:35:20.0000] like it solves the issue or smth [16:35:34.0000] alternative possibility: the last statement cannot be a loop or declaration [16:35:44.0000] devsnek: huh, link? [16:35:46.0000] not being a declaration makes sense [16:35:49.0000] devsnek: highest _rated_? [16:35:52.0000] defining "last" is a little weird though [16:35:53.0000] https://github.com/tc39/proposal-do-expressions/issues/21#issuecomment-359160212 [16:35:59.0000] but i would use loops too [16:36:06.0000] I do not see a giant checkmark [16:36:09.0000] nor do I [16:36:12.0000] devsnek ... would you? why? [16:36:14.0000] devsnek: i do not see that. github chrome extension? [16:36:19.0000] devsnek: maybe you're using "refined github" [16:36:24.0000] i am using refined github [16:36:26.0000] why would anyone ever want the completion value of a loop? [16:36:28.0000] it could be that i guess [16:36:28.0000] it does a bunch of weird things, that must be one of them [16:36:43.0000] Bakkot: because they can have values [16:36:45.0000] and i want to use that [16:36:52.0000] devsnek specifically when? [16:36:56.0000] when do you want to use that? [16:36:59.0000] idk [16:37:02.0000] :| [16:37:14.0000] sometimes you have to factor a loop out [16:37:18.0000] to use `return` from the body [16:37:21.0000] fwiw a _lot_ of people get confused by loops in React not making an array [16:37:22.0000] or assign to a variable [16:37:27.0000] like, endlessly they are confused by this [16:37:33.0000] Bakkot: completion value of a loop is *basically* the return value of a .reduce() [16:37:34.0000] "loops in react not making an array" what? [16:37:36.0000] s/in React/in JSX/ [16:37:43.0000] what does a loop in jsx mean [16:37:52.0000] https://stackoverflow.com/questions/22876978/loop-inside-react-jsx [16:38:22.0000] that's just people not understanding the basics of imperative programming [16:38:34.0000] That said, if I'm reducing like that, I already need to declare a var to hold the intermediate results, so I might as well just list that var's name *after* the loo pto get it returned [16:39:05.0000] that seems pretty JSX-specific, in that it's conflating things that wouldn't be conflated in a templating language [16:39:38.0000] In `let sum = do{let sum = 0; for(const x of vals) sum += x; sum};`, the `; sum;` at the end isn't killing me [16:39:44.0000] anyway if we make sure completions in the language are clean [16:39:47.0000] I think a lot of people will be surprised that `do { for (i = 0; i < 10; ++i) i }` does not give you an array with [0, ..., 9] [16:39:56.0000] and people generally don't do weird stuff [16:39:59.0000] i don't think it will be a problem [16:40:13.0000] like there's always that one person who writes jsfuck [16:40:37.0000] Looking back at the hoc docs, they give an example of using multiple hocs at once as: [16:40:38.0000] https://github.com/tc39/proposal-do-expressions/issues/14 is the issue for loops in particular [16:40:40.0000] `withRouter(connect(commentSelector)(WrappedComponent))` [16:40:47.0000] Bakkot: let them be surprised, they might learn how imperative programming works [16:40:48.0000] and already I'm having trouble reading that. [16:40:53.0000] devsnek :( [16:41:03.0000] devsnek that seems like... not a good design principle [16:41:06.0000] `WrappedComponent |> connect(commentSelector)(#) |> withRoute(#)` [16:41:08.0000] i mean [16:41:35.0000] i don't think do expressions exacerbate that misunderstanding [16:41:38.0000] devsnek: specifically, there is nothing about "imperative programming" which means that has to return a single value and not an array [16:41:50.0000] Bakkot: I do disagree with the OP there though [16:41:50.0000] we could define do expressions in a way which makes that return an array [16:41:51.0000] it still doesn't make any sense to me that a loop has a completion value. [16:41:52.0000] you're doing something and not putting the value anywhere [16:42:09.0000] devsnek I mean that is true for any do expression [16:42:21.0000] the whole point of using completion values is that you are not putting the value anywhere [16:42:21.0000] like i get that its confusing for n=1 [16:42:24.0000] it just gets picked up for you [16:42:28.0000] as TabAtkins said, why wouldn't you expect it to be the reduce result? why would you expect it to build you a thing implicitly? [16:42:32.0000] devsnek: why would you have a loop with n < 2 [16:42:48.0000] devsnek: actually i find it confusing with n > 1 [16:43:01.0000] ljharb: i get that people are surprised about completions [16:43:08.0000] but if you evaluate it x times [16:43:12.0000] where x is not one [16:43:13.0000] like, if there is no array, where would it come from [16:43:21.0000] rkirsling: the array thing i don't find reasonable [16:43:31.0000] i don't understand the logic of where all those values are doing [16:43:33.0000] going* [16:43:33.0000] (altho the for..of part kind of makes sense to me) [16:43:53.0000] to me it feels like someone copy pasted some code without understanding it [16:44:10.0000] isn't that stackoverflow's growth model [16:44:22.0000] it feels like the kind of question we get in discord.js support server [16:44:41.0000] I don't think that "the completion value of a loop is an array holding all of the completion values of each step of the loop" is a totally unreasonable thing to think [16:44:51.0000] it isn't, but like, there is no particular reason for it not to be [16:45:02.0000] yeah but at that point you have some idea of completion values [16:45:14.0000] ... yes? [16:45:15.0000] and? [16:45:21.0000] diy list comprehension, yo [16:45:22.0000] insofar as users have no conception of completion values, sure lol [16:45:23.0000] the jsx thing has nothing to do with completions [16:45:37.0000] ok pretend I never brought up JSX [16:45:48.0000] i'm down to talk about making the loop produce an array [16:45:54.0000] ehh [16:45:58.0000] I don't really think it should [16:45:59.0000] but i don't think anything here is beyond comprehension [16:46:06.0000] i also don't think it should [16:46:07.0000] ^ pun intended? [16:46:11.0000] lol ross [16:46:14.0000] my actual position is that we should not expose to users the completion value of a loop [16:46:20.0000] I will concede that https://github.com/tc39/proposal-do-expressions/issues/14#issuecomment-359529937 gives me pause [16:46:21.0000] ^ +1 [16:46:33.0000] yeah I think I can agree with that sentence too [16:46:35.0000] ok to rephrase [16:46:42.0000] i'm ok talking about what the completion value of a loop should be [16:46:54.0000] but i don't think a loop having a completion value is inherently a bad thing [16:47:04.0000] right, and my position is the negation of that last sentence [16:47:13.0000] whether its undefined or an array or the last expression or whatever [16:47:48.0000] I am cool with all the non-obvious statement cases being defined as producing undefined. So long as if() and try/catch give me their final values, everything else can take a hike as far as i'm concerned [16:48:01.0000] TabAtkins: the if block? [16:48:07.0000] yeah [16:48:10.0000] TabAtkins: blocks having a completion value of their last statement's makes sense to me [16:48:12.0000] any blocks [16:48:20.0000] but not loop bodies [16:48:21.0000] my position is, I would like us to only allow do expressions for which the completion value is going to be obvious - so, you should not be able to end a do expression in a loop (or a declaration, which is also weird) [16:48:33.0000] i agree with tabatkins [16:48:45.0000] sounds like we have a compromise point [16:48:50.0000] that being [16:48:55.0000] the loop is allowed to be the last item [16:48:59.0000] but it just always gives undefined [16:49:02.0000] oh. i don't think that was what tab said [16:49:03.0000] wait whoa why is `do {} while (false)` different from `{}` [16:49:04.0000] (I'm also fine with "everything works exactly as if you just plugged it into eval()", fwiw.) [16:49:17.0000] rkirsling: because it's a loop and `{}` is not [16:49:19.0000] devsnek accurately summarized me, yeah [16:49:20.0000] yes [16:49:27.0000] that is my question [16:49:36.0000] TabAtkins would you also be ok with, ending a do expression with a loop is a syntax error? [16:49:37.0000] that's part of the es2015 completion reform [16:49:41.0000] yeah [16:49:51.0000] Bakkot: i would be against that [16:49:53.0000] rkirsling basically "things are sometimes empty, sometimes not, at runtime" was held to be confusing [16:49:56.0000] rkirsling: i'm saying that's why it's different. loops make 0, 1, or N completion values, blocks make 1. there's no ambiguity about blocks, there is with loops [16:49:57.0000] idk how strongly exactly [16:49:58.0000] devsnek why? [16:50:19.0000] ah [16:50:29.0000] right, you might not even enter a loop body [16:50:34.0000] that's a good point [16:50:54.0000] it feels wrong to limit things like that [16:51:02.0000] maybe i can be convinced [16:51:13.0000] i can't be convinced about control flow though, that's a must [16:51:15.0000] devsnek fwiw this is the sort of limitation we could relax later [16:51:18.0000] devsnek :( [16:51:20.0000] it feels wrong but it's not unthinkable [16:51:30.0000] devsnek control flow is also a thing which could be relaxed later [16:51:38.0000] nah my use case doesn't work without it [16:51:41.0000] well [16:51:43.0000] there are other use cases [16:51:46.0000] loops would be puntable where non-loop block-based constructs aren't [16:51:50.0000] sometimes we add things which do not meet your particular use case [16:51:50.0000] that is ok [16:51:58.0000] i mean my motivation for possibly furthering the proposal [16:52:04.0000] ah, fair [16:52:09.0000] is to allow control flow in expression positions [16:52:15.0000] yeah [16:52:26.0000] that's something i feel pretty strongly shouldn't be allowed [16:52:28.0000] Given that the point of a do-expr is to *return a value*, I don't see a signfiicant difference between "ending with a loop returns undefined" and "ending with a loop is a syntax error". [16:52:39.0000] TabAtkins: yeah i see both sides [16:52:43.0000] ^ I like this phrasing [16:52:44.0000] ok I might try to present the minimal form of do expressions [16:52:46.0000] TabAtkins: it's also to have statements in expression position [16:52:47.0000] i just don't like limitations [16:52:48.0000] The latter will catch programming mistakes earlier; the former will allow me to spin a loop for side effects at expression context. [16:52:49.0000] TabAtkins: which doesn't require a value [16:52:51.0000] which basically ban anything confusing or contentious [16:53:03.0000] i find your banning of contentious items contentious [16:53:06.0000] lol [16:53:07.0000] ljharb what expression positions don't require a value? [16:53:22.0000] Bakkot: i mean, there must *be* a value - like undefined - but it doesn't have to have meaning [16:53:23.0000] yeah the whole point of expression context is "here comes a value, beep beep" [16:53:24.0000] devsnek sure, but the alternative appears to be "do expressions stagnate forever", so... [16:53:44.0000] combining "make everything an expression" and "for side effects" just hurt my head [16:53:48.0000] `void do { ā€¦ }` is a totally fine way to run side effects in expression positions. [16:53:51.0000] (or maybe it was my heart) [16:53:55.0000] where "fine" is that dog meme [16:53:58.0000] yeah like [16:54:01.0000] ljharb I mean to say, when would that come up? I feel like "I am forced to be in expression position, but I don't care what the value is" is fairly rare [16:54:01.0000] its weird [16:54:08.0000] Bakkot: true [16:54:11.0000] but that's what i like about js [16:54:26.0000] Bakkot: but i think ending with a loop, and not a value, is equally rare [16:54:36.0000] Bakkot: or will be in an expression position, i mean [16:54:48.0000] ljharb well, I think some people will expect it to get an array, is the thing [16:54:52.0000] and try it, and get bit [16:54:55.0000] fair [16:55:09.0000] I mean, I would say it's on par with the early error for ** [16:55:22.0000] what if the completion value of a loop is a string containing info for the mailing list [16:55:40.0000] ā€¦ maybe still better than "last value" [16:55:51.0000] :-p [16:56:23.0000] "congrats you're the 10,000th caller! what do you think this should do" [16:56:33.0000] "side effects in expression context, don't care about the value" can still be done with `do{ for(){...}; 0}` [16:56:34.0000] lol [16:56:43.0000] my main thing is thinking about how generated code can use do expressions [16:56:54.0000] that's my primary use case for them anyway [16:56:55.0000] TabAtkins: very true. [16:57:06.0000] devsnek: generated code can also generate boilerplate to capture whatever return value you want [16:57:19.0000] yeah but that's extraordinarily difficult [16:57:31.0000] what sort of generated code [16:57:36.0000] generated code has a lot of freedom to just do things in a different way [16:57:38.0000] like babel codemods [16:57:41.0000] put an IIFE there, rewrite control flow, whatever [16:57:42.0000] i don't mean compiler output [16:58:29.0000] devsnek: how is it difficult? add `let completion;` to the top, and `completion =` in front of the last value in the loop body, and `completion;` after? [16:58:33.0000] TabAtkins re the "reduce" thing, one other case is, you are searching for an item and want that item [16:58:37.0000] in which case it's more awkward [16:58:40.0000] ljharb: i was talking more about control flow [16:58:45.0000] this is the example in https://github.com/tc39/proposal-do-expressions/issues/34 [16:58:50.0000] under "for loop" [16:58:58.0000] rewiring the values is pretty easy [16:59:19.0000] rewiring the control flow is also pretty easy [16:59:31.0000] ah yeah, without a `break with` that rewrites the completion value, you gotta do the "declare a temp, for(), temp" thing [16:59:33.0000] yeah just fork regenerator [16:59:57.0000] generators are way more powerful than the break-continue-return kind of control flow we're talking about here 2020-05-22 [17:01:37.0000] `let value = do { let t; for(const v of values) { if(pred(v)) { t=v; break; } }; t}` [17:01:47.0000] i don't hate having to do that [17:01:52.0000] but i much prefer using the completion value [17:01:56.0000] vs `let value = do { for(const v of values) if(pred(v)) break with v; };` [17:02:25.0000] actually break with and continue with are good ideas [17:02:51.0000] oof [17:02:55.0000] no no wait [17:03:09.0000] loops complete with undefined unless you use `break with` [17:03:28.0000] continue with makes no sense pretend i didn't say that [17:03:36.0000] `break with` is at least explicit [17:04:05.0000] seems we have options [17:04:32.0000] options are kind of the problem because we don't have a good way to choose between them [17:04:56.0000] options which aren't blocking each other [17:05:06.0000] I am hoping there is a minimal subset which just bans everything people disagree about and is still useful for some cases [17:05:41.0000] is there a demand for `return` to refer to the function scope though? [17:05:46.0000] yes [17:05:54.0000] that's my primary use case [17:05:57.0000] oh. [17:06:16.0000] lol [17:06:42.0000] it would be exceedingly confusing for `return` to not mean that imo [17:07:37.0000] to me it just seems [17:07:40.0000] you have some logic [17:07:57.0000] depends on how you're conceiving of this magical statement-to-expression space [17:07:59.0000] you refactor it to use a do expression [17:08:15.0000] now all of a sudden you have to restructure your control flow [17:08:21.0000] because you can use break/continue/return inside it [17:08:35.0000] can't* [17:08:57.0000] hmm that's not a bad point [17:09:32.0000] ugh the further this discussion goes on though, the more unsure I become about the feature [17:09:50.0000] like, I love "everything's an expression" but [17:10:30.0000] does that imply that I actually have a convincing use case for "a block that turns all your imperative logic into an expression when all is said and done"? [17:10:51.0000] i would use it all over the place to structure things [17:11:05.0000] it's like the big brother of empty lines between things [17:11:38.0000] as like, local functions without call overhead? [17:11:46.0000] i mean like [17:12:05.0000] when you have a bunch of lines of code, you generally group them with empty lines [17:12:20.0000] often in rust people also scope them using block expressions [17:12:23.0000] and i really like that pattern [17:12:32.0000] wait what why [17:12:47.0000] why waste syntax if it's no better than newlines [17:13:11.0000] oh ,you're saying like [17:13:28.0000] irc needs multiline support [17:13:54.0000] "there's no need for this to go out of scope yet but doing so clarifies the fact that I'm only using it *right here*" [17:14:07.0000] yeah [17:14:14.0000] its just clean [17:14:21.0000] you end up at the end with just the variables you're actually using [17:14:30.0000] and then said "paragraph" or "stanza" or whatever you wanna call it _has_ a result [17:14:37.0000] oh eah [17:14:39.0000] yeah [17:14:41.0000] they produce results [17:14:52.0000] so that'd give the block purpose in Rust [17:14:57.0000] but in JS we'd need a new thing [17:14:59.0000] okay [17:15:04.0000] yeah in rust you can do `let x = { 5 };` [17:15:13.0000] that is, while abstract, not unconvincing [17:15:22.0000] right [17:15:32.0000] rust has way better semantics around that though [17:15:47.0000] so then even like [17:16:45.0000] https://gc.gy/57811604.png [17:17:37.0000] const result = do { [17:17:37.0000] const myNamedBoolArg = true; [17:17:37.0000] foo(data, myNamedBoolArg); [17:17:37.0000] }; [17:17:52.0000] yeah you could do that [17:18:09.0000] kinda superfluous but yeah, documents itself, perhaps [17:19:11.0000] honestly the most op pattern is if expressions [17:19:55.0000] we could replace do expressions with `if (true) {}` if expressions :P [17:19:58.0000] I kind of resent Rust's lack of ternary but yeah, if you have any nontrivial branches then if exprs are pretty darn great [17:20:10.0000] lol [17:23:45.0000] anyway so: does anyone here _object_ to, do expressions, where you cannot have your last statement be a loop or declaration, and break/return/continue are banned? [17:23:50.0000] I know this does not meet devsnek's use case [17:24:02.0000] but hope that it is useful enough anyway [17:24:44.0000] if I represented myself I would object [17:25:41.0000] on what basis? [17:25:52.0000] on not having control flow [17:26:04.0000] I know it doesn't meet your use case; is your position that it is not worth having if it does not meet your use case? [17:26:20.0000] I'm imagining a lot of humans would want to use it [17:26:24.0000] it's not like adding this without allowing break/return prevents relaxing that restriction later [17:26:28.0000] given my refactoring point above [17:26:42.0000] so I'm worried it wouldn't be useful enough without control flow [17:27:40.0000] I personally would still find it very useful [17:27:55.0000] maybe someone with a zillion followers on twitter can make a poll [17:28:01.0000] I think it's worth presenting [17:28:02.0000] I think most of the pipeline proposal's use cases would be met by this, also [17:28:17.0000] oh god not a Twitter poll [17:28:28.0000] seems useful for pipeline yeah [17:28:40.0000] also to do `let x = try { foo() } catch { null }` which is very common [17:28:49.0000] ime [17:29:11.0000] if we get do expressions do we drop the throw expression proposal [17:29:24.0000] tbh if we go back to the pipeline discussion though and the refactorings TabAtkins was showing above, I really do think the `#`-chasing leads to comprehensibility [17:30:06.0000] if the spec requires the hash to be bright red when displayed [17:30:32.0000] :stare: [17:30:56.0000] Bakkot: I'd feel better about it if pipelines advance [17:31:05.0000] devsnek: ... why? [17:31:09.0000] but like I said I don't think I'll actually block either way [17:31:21.0000] I'm mostly interested in this as an _alternative_ to pipelines [17:31:21.0000] because people won't use control flow in them [17:31:29.0000] oh interesting [17:32:02.0000] yeah I guess that was mentioned above [17:32:12.0000] like instead of `x = a |> b(0, #) |> await #` ro whatever, you'd write `x = do { let $=a; $=b(0, #); await #}` [17:32:20.0000] s/ro whatever/or whatever/ [17:32:27.0000] also s/#/$/g [17:32:49.0000] but I kinda thought avoiding locals was the point [17:32:53.0000] are there real world examples of that [17:33:16.0000] HOC with await or something [17:33:47.0000] (not the point of the proposal but the reason why existing approaches don't suffice, I mean) [17:34:09.0000] rkirsling I think the main reason for avoiding locals is so that you can remain in expression position, and also not pollute your local scope [17:34:29.0000] some people (pointfree people) have a principled objection to locals, but I don't think that's the dominant party [17:34:53.0000] hmm okay [17:34:59.0000] I do see your point [17:39:39.0000] devsnek: `console.log(filter(parse(await fetch(extractRemoteUrl(await readDB(makeQuery('some query'))))));` is the sort of thing I write a lot [17:39:49.0000] well, obviously I break it up into multiple lines with locals [17:39:51.0000] but you get the idea [17:39:54.0000] not HOCs or whatever [17:39:58.0000] just normal chasing data around [17:40:23.0000] is that code real [17:40:31.0000] it looks *plausible*, at least [17:40:36.0000] I've written code like that ^_^ [17:40:37.0000] I've never seen code like that [17:40:39.0000] I don't think [17:40:43.0000] it is not literally copied from one of the proprietary code bases I work on, no [17:41:00.0000] if things like it exist I'll believe you [17:41:01.0000] but it is very much the sort of thing I write in them, except I would make intermediate variables so a human could read it [17:41:03.0000] my python instincts these days would probably force me to break that up into multiple assignments, but still [17:42:12.0000] I just have never seen them so i would like to get a sense of what real world code looks like [17:50:18.0000] agree that it looks plausible [17:50:26.0000] Bakkot: are you taking up do expressions again [17:50:47.0000] (regardless of whether it'd get past code review, tehe) [17:52:10.0000] shu: maybe [17:52:20.0000] okay [17:52:28.0000] shu: mostly I would like them discussed if we talk about pipelines again [17:52:40.0000] i do not think pipelines are a good idea currently [17:52:42.0000] because I think they are better than pipelines and also mean you don't need pipelines [17:52:58.0000] great [17:57:08.0000] shu: what do you think about control flow in do expressions [17:58:19.0000] control flow that breaks out of do expressions? [17:58:44.0000] like a return in a do expression? [17:58:55.0000] yeah [17:59:07.0000] return returns the outer function that is [18:00:13.0000] that seems like a bad idea [18:00:26.0000] :( [18:00:47.0000] what's the motivation for having that behavior? [18:02:16.0000] oh i see some backlog, you're worried about a refactoring hazard? [18:02:21.0000] yeah [18:02:29.0000] i mean i also have a use case for returning in them [18:02:36.0000] but more generally the refactoring hazard seems annoying [18:03:18.0000] i can imagine code like `let x; try { x = z() } catch { break }` exists [18:03:22.0000] or similar with if/else [18:03:57.0000] my opinion is those patterns are more harm than good [18:04:23.0000] those patterns = to expect to wrap them in an expression and keep the same behavior [18:04:34.0000] yeah i mean [18:04:41.0000] adding a block around code doesn't change control flow [18:05:04.0000] i don't get why adding `let x = do` at the front of the block is so controversial [18:05:05.0000] why is that comparable here? [18:05:24.0000] aside from the break inside while loop head [18:05:27.0000] i get why that is weird [18:05:51.0000] s/while loop/loop/ [18:06:18.0000] because in an algol-like language there are certain (fairly strong imo) properties that tend to hold of statements and expressions [18:06:49.0000] and one of them is generally that expressions evaluate beginning to end without affecting the control flow of the surrounding context, whatever that is [18:06:54.0000] i've never used algol [18:06:55.0000] sometimes you have exceptions that aren't too confusing [18:07:04.0000] well, c-like then [18:07:08.0000] i guess [18:07:33.0000] i don't see any strong reason to have a separation [18:07:41.0000] dunno what to tell ya [18:07:45.0000] most people i think do [18:07:46.0000] like some things obviously don't make sense as expressions [18:08:13.0000] like variable declarations [18:08:33.0000] what property do you get from strong separation of expressions and control flow [18:09:05.0000] the property of not having to think about control flow if i'm reading an expression position [18:09:33.0000] anywho gotta run [18:09:36.0000] aight [18:11:17.0000] fwiw i think the property i like is a little stronger than the expression/statement split, it's more about having clear scopes where control flow has effect [18:11:45.0000] e.g. break doesn't work in expression contexts now, to suddenly make it work is a very big ask [18:11:45.0000] I can agree insofar as control flow _within_ seems okay, it's control flow _through_ that gives pause [18:11:50.0000] right [18:12:06.0000] put another way, control flow in JS is delimited in certain ways today [18:12:21.0000] to change that is a *huge* ask and break in mental model that i'd fight against [18:12:38.0000] in languages with undelimited continuations, that shit is hard to wrap your head around for similar reasons [18:12:39.0000] i don't quite understand what that mental model is [18:12:44.0000] and why people end up using delimited continuations [18:12:47.0000] maybe i'll read some algol stuff [18:13:10.0000] i don't know if algol is a good starting point [18:13:33.0000] i just really don't understand the separation of statements and expressions [18:14:37.0000] but i'm pretty sure you have a mental model of what return does, right? the mental experiment i recommend is 1) ask if you also think presence of call/cc or setjmp/longjmp make reasoning about return hard, and 2) if you find the difficulty comparable, but to a lesser degree, with allowing returns in expressions [18:15:17.0000] what is cc [18:15:39.0000] https://en.wikipedia.org/wiki/Call-with-current-continuation [18:15:49.0000] one of the other major paradigms for control flow [18:16:07.0000] that's probably not a good example, return-in-expressions aren't undelimited [18:16:08.0000] well i will say [18:16:10.0000] look at shift/reset instead [18:16:17.0000] reasoning about longjmp is very difficult [18:20:37.0000] is it funny that I know about call/cc but am having to look up longjmp [18:21:59.0000] (I mean it's sort of what I was expecting but still) [18:22:24.0000] i knew about longjmp but not call/cc [18:22:27.0000] call/cc is weird [18:22:57.0000] i find call/cc and longjmp to be a completely different universe of complexity compared to returning from inside a do expression [18:23:30.0000] call/cc is yield on steroids, basically [18:23:44.0000] idk why all the websites have to make it sound so complex [18:23:53.0000] well i mean it is complex [18:24:17.0000] but i feel like these concepts are always explained in the most difficult terms instead of the easiest terms [18:24:54.0000] in any case, call/cc and longjmp are both dynamic [18:25:22.0000] and involve non-local control flow [18:25:47.0000] i don't really see a comparison between them and allowing break/return/continue inside do expressions [18:30:13.0000] hah, good old Oleg [18:30:14.0000] https://en.wikipedia.org/wiki/Call-with-current-continuation#Criticism [18:30:30.0000] call/cc makes sense if you don't use the word "continuation" [18:31:13.0000] its like when people explain monads [18:40:36.0000] I usually just think of "continuation" just as "return target" but then it makes "current continuation" a bit more confusing [18:41:24.0000] i posted the block-expression control flow vs call/cc thing in a programming language design discord [18:42:59.0000] people are angry that they would be equated [18:50:50.0000] i did not equate them [18:51:43.0000] i don't understand what the comparison is [18:52:10.0000] the point was a broad one: you have expectations when reading "return" of what it does, and those expectations must be thrown out when you see setjmp/longjmp [18:52:43.0000] similarly, to a lesser degree, people's expectations of "return" will need to be re-calibrated if they are allowed in do expressions in JS [18:53:02.0000] aside from "i don't expect there to be a return value in this syntactic position (because that's true of any statement)" what is the expectation there [18:53:16.0000] as i said before, that expressions do not affect control flow [18:53:51.0000] (wow I forgot that you can't throw from a ternary in JS) [18:54:05.0000] throw expressions is a proposal [18:54:33.0000] shu: out of curiosity have you used any languages with this feature before [18:54:37.0000] like rust or smth [18:55:15.0000] i have used rust, but an earlier version and not since 1.0 i don't think [18:55:21.0000] like I was saying though, I think it's very different when "everything is a statement" [18:55:28.0000] dammit [18:55:32.0000] s/statement/expression/ [18:55:33.0000] also i'm curious about if yield and await violate your expectations [18:55:56.0000] like, the thing that creates confusion or weird expectations is the do block [18:56:13.0000] we have this barrier between worlds and it's tricky to decide upon its properties [18:56:24.0000] if there's no barrier, there's nothing to be confused about [18:56:30.0000] i just don't understand this expectation or why maintaining it matters [18:57:11.0000] i don't think i've ever seen a rust user be confused about it anyway [18:57:19.0000] maybe that's because they're too busy being confused about lifetimes [18:57:28.0000] there's nothing _to be confused about_ in Rust [18:57:54.0000] wdym [18:58:01.0000] `do { ... }` raises the question of "just how much is this thing like a function scope" [18:58:09.0000] i don't understand why it does [18:58:35.0000] https://www.irccloud.com/pastebin/aJYvqDl4/x.rs [18:58:49.0000] so here's an example from rust [18:59:33.0000] devsnek: yield and await do not violate my expectations, since they produce values usable as expressions [18:59:43.0000] they don't have to [18:59:45.0000] they might never return [18:59:46.0000] devsnek: if you shorten it to that extent then it could go either way though [18:59:54.0000] devsnek: right? [19:00:09.0000] how is that control flow different [19:00:39.0000] than return and break, which transfer control and do not return a value? [19:00:56.0000] yield and await both transfer control [19:00:59.0000] yield and return abstract their control flow in such a way that should execution resume, you're back at where you were, with a new value (that you may use or not) [19:01:00.0000] and might not return a value [19:01:09.0000] err [19:01:11.0000] yield and await [19:02:02.0000] shu: what if i told you return could resume but it never does [19:02:22.0000] i don't understand what that means [19:02:33.0000] it would still fire the finally around it though? [19:02:36.0000] why does being able to resume change the control-flow-ness of an operator [19:02:48.0000] try { return } finally { ... } [19:03:04.0000] bradleymeck: talking about whether control flow should be allowed in do expressions btw [19:03:06.0000] i think its just a mental model of the control flow being a valid expression itself [19:03:59.0000] foo(return) doesn't make any sense, and that gets confusing in foo(do { return }) [19:04:28.0000] if return parsed as an expression it could make sense [19:05:07.0000] it could parse in the same position but it would never have a value generated for that position [19:05:23.0000] right its a never type [19:05:27.0000] i don't actually care about such a thought myself, but it seems to come up [19:05:36.0000] same as a function that always throws [19:06:39.0000] but thats in a different "frame/scope", so often not thought of when reading the code (even if it is a valid point) [19:07:09.0000] devsnek: i feel like you are not receptive to what i have said, and that's okay. you asked what i thought of control flow in do expressions [19:07:19.0000] shu: no i just want to understand [19:07:25.0000] i think control flow in do expressions is fine-ish, finally {} can get confusing if you cancel ending the frame [19:07:26.0000] sorry if that didn't come across well [19:08:32.0000] finally is a good point about how people can understand odd control flow [19:08:38.0000] it seems like you don't have any different expectations of expressions and statements wrt control flow [19:08:43.0000] i do [19:09:34.0000] the existence of odd control flow in the language now doesn't have generalize to "therefore allowing them in expressions doesn't change expectations" [19:09:36.0000] my only concern is from half finished statements: `while(...) { foo(sideEffect, do {continue}); }` currently statements are the points to observe non-throw control flow [19:09:53.0000] if that's all it comes down to i would say keeping that expectation doesn't matter that much [19:09:56.0000] so, you have to walk expressions for throws but not for other things [19:10:07.0000] await being an expression because it needs to return a value did require some extra restrictions [19:10:23.0000] like disallowing it in parameter expressions [19:10:38.0000] devsnek: that's an opinion, not an argument? [19:14:12.0000] shu: right i meant, there's no point in trying to draw a conclusive decision from just an opinion [19:14:31.0000] who... is trying to do that? [19:15:05.0000] well i was trying to do that [19:15:08.0000] until you clarified [19:15:47.0000] i was trying to get to a point where i could make a decision based on what you were saying [19:17:15.0000] i missed that context, thought you just wanted my thoughts. a decision on? [19:18:38.0000] i was trying to figure out the importance of control flow in do expressions [19:18:50.0000] or lackthereof [19:19:13.0000] it seemed like your own opinion is pretty strong already, that they should be allowed [19:20:53.0000] i'd be equally curious of why we couldn't enable control flow later. though i bet in general just banning them directly inside of params wouldn't be terrible [19:25:29.0000] you don't really have to explicitly ban them inside params or anything [19:26:23.0000] like theoretically loop heads and function params are already barriers to their relevant control flow [19:29:45.0000] devsnek: is the PL discord public? [19:30:06.0000] Bakkot: #lang-dev on the rust community discord [19:30:29.0000] (a channel about developing weird programing languages using rust, not about the development of the rust language) [19:31:54.0000] thank [19:32:11.0000] anyway I am going to be proposing do expressions with control flow disallowed [19:32:19.0000] since I think everyone agrees on that subset [19:32:48.0000] someone with more willpower than me can fight the control flow fight later [19:32:55.0000] all of it? or just abrupt completions? [19:33:07.0000] rkirsling break/return/continue crossing the do{}, specifically [19:33:12.0000] cool [19:33:13.0000] those are the only things people fight about [19:33:16.0000] yes [19:34:15.0000] if and try seem enough for a presentation [19:39:06.0000] i missed a log, but do expressions do not obviate the need for pipelines for me. [19:39:22.0000] they would be a solution, but not an ergonomic one for the use cases i have. [19:40:54.0000] ljharb do you have examples of those use cases? [19:41:02.0000] i have the HOC one above [19:41:36.0000] those are in modules where the result is just export defaulted; local vars would work fine, but that looks way worse than the )))) versiĆ³n already, let alone the pipeline one [19:41:48.0000] oh wow someone's proposing spaceship operator [19:41:58.0000] the desire is to have a chain of functions, just like youā€™d have a chain of OO methods [19:42:15.0000] do expressions only satisfy the ā€œstatements in expression positionā€ part, which imo is not something i care about for pipeline [19:42:26.0000] devsnek: Hemanth and i yes [19:42:40.0000] ljharb hmmm [19:42:52.0000] devsnek: well, weā€™re proposing that we solve a problem. Spaceship is just what we think solves it best ;-) [19:43:16.0000] bradleymeck: for the arbitrary module names slides, you can have cjs facades, even autogenerated [19:44:01.0000] ljharb: you should lead with s/a - b/a <=> b/ for array sorting [19:53:47.0000] I do not understand the relationship between <=> and Array.prototype.compare [20:01:40.0000] Bakkot: the latter is comparison for arrays. The former is a comparison protocol for everything. [20:02:00.0000] if the array method and the operator both exist, then Iā€™d expect the method to delegate to the symbol on array.prototype [20:04:59.0000] there's a standard c extension which allows expression blocks [20:05:02.0000] and it allows control flow [20:05:28.0000] it also allows crashing compilers pretty regularly [20:05:32.0000] c has a lot of extensinos [20:05:35.0000] *extensinos [20:05:36.0000] ugh [20:05:37.0000] woords [20:05:39.0000] wooooooords [20:05:43.0000] *extensions [20:05:56.0000] if you're looking for an example which allows control flow, ruby's blocks are probably more relevant [20:06:13.0000] so far every example i find allows it [20:06:39.0000] every language allows reflection on private things too :-) we can be better [20:07:10.0000] most languages just don't allow statements in expression position at all [20:07:10.0000] yeah but people don't say its a mistake [20:07:28.0000] the languages which do tend to have that as their philosophy, so it makes sense to allow control flow there also [20:07:42.0000] we are grafting this feature onto a language which already has an expression/statement dichotomy [20:07:46.0000] so our situation is somewhat unique [20:07:52.0000] c has the same issue [20:08:08.0000] point taken about crashes but still [20:08:11.0000] I would seriously not use GCC-specific extensions as precedent for anything ever [20:08:32.0000] they are 100% added because they solve a specific use case someone had, not coherently designed to be a reasonable feature [20:08:38.0000] ^ [20:08:48.0000] clang supports it too [20:09:04.0000] I mean that's not unusual though [20:09:10.0000] clang strives to be GCC compatible [20:09:37.0000] msvc doesn't support it [20:09:50.0000] but msvc is also kind of broken in general [20:12:59.0000] I mean...maybe so but I don't think this exemplifies that in any way [07:59:03.0000] devsnek: will you be doing an update on iterator helpers? [08:03:40.0000] ystartsev: no :( [08:04:16.0000] ystartsev: did you see the conversation in #tc39-implementers [08:04:17.0000] devsnek: since we are starting to implement, it would be great to have a discussion about the generator stuff you and jorendorff were trying to figure out [08:04:19.0000] yes [08:04:23.0000] ok cool [08:04:35.0000] would you be ok if i started a conversation about that? [08:05:09.0000] wdym by conversation [08:13:20.0000] devsnek: primarily, a clarification of the positions of the editors and the champion (so, you) regarding how generators should be used in the spec [08:13:39.0000] this is so that we can move forward with the implementation. it wouldn't be stage advancement, just discussion [08:13:43.0000] oh i meant like what medium [08:13:54.0000] plenary discussion? [08:13:57.0000] oh, as an agenda topic [08:13:58.0000] yep [08:14:06.0000] sure, sound fun [08:14:12.0000] sounds* [08:14:20.0000] cool. i will add it [08:14:34.0000] and maybe make some slides based on your discussion with jorendorff [08:14:44.0000] šŸ‘šŸ» [08:14:48.0000] thanks for working on this [08:15:27.0000] sure, happy to help! [11:47:29.0000] can anyone give my eyes some help, i wrote up https://gist.github.com/bmeck/5f195c4ae08009db4f3eefdc8bb360c9 to see if anything is using Symbol.species on their pages for Arrays and TypedArrays, but *nothing* is hitting that code except a coreJS eager feature detection. I feel like I definitely did something wrong [11:53:30.0000] bradleymeck: it should work for this example right? [11:53:34.0000] https://www.irccloud.com/pastebin/KlTA1VIh/ [11:54:33.0000] yea, i see the bug I hit [11:55:02.0000] coreJS makes species a regular function not a constructor so when I was patching that to figure out the noise ratio i broke everything else [11:55:25.0000] `species().foo` should be in a try catch [11:55:46.0000] well technically we could always use new? [11:56:42.0000] ystartsev: the goal is that we detect that code, yea [11:57:08.0000] well that we detect when the species in the subclass is not the builtin* [11:58:07.0000] cause if the behavior changes to always use the builtin we aren't concerned with the subclass species being the builtin [11:58:48.0000] yes [11:59:00.0000] sorry the code snippit was wrong, shouldn't be set to array [11:59:49.0000] thanks for the sanity glance [12:03:19.0000] its hitting for me, ill post the snippit in case i did something wrong [12:04:18.0000] can you see this? https://gist.github.com/codehag/2aaa571b6286f7f2cc28d01736c7e708 [12:04:20.0000] i'm just skeptical of these sites that are extending builtins via some regexps showing things like `extends Array` but never hitting any species usage [12:04:34.0000] i can see it, let me run it [12:04:44.0000] one thing that is surprising to me is that we are not seeing angular show up [12:05:38.0000] https://github.com/angular/angular/commit/58b29f1503a180fdfb8feb73a30d0c4448afad9a [12:05:44.0000] i feel like we should see that? [12:06:12.0000] yea that gist hits the trap [12:06:30.0000] oh! good [12:06:38.0000] oh wait, my gist, yea that makes sense [12:06:58.0000] idk if angular hits it, but if you have a specific site i can visit to verify that would be good [12:07:08.0000] lemme look [12:07:22.0000] angular vs angularjs still confuses me a bit [12:08:13.0000] ystartsev: i did disable Promise detection is likely why? I can re-enable it [12:09:08.0000] this project hits it... don't know much about it [12:09:09.0000] https://github.com/microsoft/ApplicationInsights-node.js [12:10:29.0000] or this is better: https://zonejs-basic.stackblitz.io/ [12:11:52.0000] i can't understand the angular code [12:12:28.0000] it seems to be trying to follow the @@species protocol but doesn't depend on the native Promise.then, since it also patches then [12:13:59.0000] ystartsev: that page does not fire it, i've been trying to poke it to see if the detection is slightly off [12:14:14.0000] it doesn't use the builtin at least [12:15:07.0000] interesting [12:15:43.0000] might be a good example though, shows how species is not being used as expected anyway [12:16:12.0000] i have no problems with user libraries themselves using @@species as their own subclassing machinery [12:16:16.0000] this is another example, they have a few https://stackblitz.com/edit/zonejs-throttle?file=index.js [12:16:27.0000] they don't have the implementation tradeoffs of native engines [12:16:30.0000] yeah it looks like that is pretty much what angular did [12:16:32.0000] out of 1k sampled sites out of 400k, all 26 traps were from coreJS so i was losing my mind [12:17:02.0000] shu: you mentioned that we should formulate a bigquery for this [12:17:12.0000] ystartsev: bradleymeck has already done great work there [12:17:16.0000] oh great [12:17:20.0000] ok, because i wasn't sure where to start [12:17:30.0000] ystartsev: though if you want to start playing with it, either send *me* queries to run, or wait until i can figure out how to get you GCP credits [12:17:35.0000] because it turns out it is expensive af [12:17:48.0000] i have no idea how to forumate them, i would need to do some reading [12:17:48.0000] i have the output if you want, but its mostly just 20mb of pages in a CSV we need to actually validate against [12:17:57.0000] ystartsev: it's SQL [12:18:05.0000] that may not solve your problem :) [12:18:06.0000] oh, thats straight forward [12:18:12.0000] i don't really know SQL, so that was my problem [12:18:23.0000] its basically prolog but all caps right? [12:18:31.0000] select * from websites where breakage=true [12:18:39.0000] it doesn't have to use caps i don't think [12:19:01.0000] bradleymeck if you have the data and the queries i would love to take a look [12:19:17.0000] maybe we can make a doc about it for how-we-work [12:20:06.0000] ystartsev: DO NOT RUN the query I'm about to post, it is a bit pricey we found out [12:20:07.0000] the angular story is really interesting because it tells us that people don't subclass the way we thought they would, and it gives more of a reason to remove this [12:20:23.0000] :| gotcha [12:20:24.0000] https://www.irccloud.com/pastebin/Oyd05gui/dont_run_this [12:20:31.0000] we have saved output of it [12:20:47.0000] cool [12:21:10.0000] ah gosh i need to stop working on this, its super late [12:21:19.0000] i am going to _call it a day_ [12:21:24.0000] but i am very excited about this [12:21:26.0000] cya! enjoy the break [12:21:54.0000] how big is the dataset [12:22:46.0000] not as huge as I thought, our first naive query was like 6k and this one is up at around 400k [12:22:59.0000] after you dedup the page hrefs [12:42:37.0000] bigquery should rename FULL JOIN to EXPENSIVE JOIN [12:59:31.0000] shu we got another coreJS noise flag apparently with https://github.com/aldehydkrotonowy/source-code/blob/6bf6ff94a485bedb02218978a62dd2881c0c54d6/core-js/packages/core-js/internals/fix-regexp-well-known-symbol-logic.js#L22 [13:00:19.0000] gah, linked to wrong line, but yea that file also does eager detection [13:03:39.0000] https://github.com/zloirock/core-js/blob/master/packages/core-js/internals/fix-regexp-well-known-symbol-logic.js#L80 is the actual line, reading [13:05:19.0000] this code shouts too much [13:14:13.0000] shu: it looks like if the detection fails it replaces the builtins with its own there [13:19:06.0000] it is odd though, i only saw it because they use {} and call ({})[RegExp.prototype[Symbol.split]]('') [13:20:44.0000] https://github.com/zloirock/core-js/blob/master/packages/core-js/internals/fix-regexp-well-known-symbol-logic.js#L70-L73 sets the species for the ordinary object, but idk why, they don't seem to check the return value to be the same [14:03:09.0000] bradleymeck: i am on PTO today since Google gave everyone off, let's pick it up on tuesday. feel free to send me a gist or an email with the cases you find [14:03:19.0000] k [14:08:24.0000] another trap fires for Promise.then in https://github.com/zloirock/core-js/blob/717ff8bca8e68508ef6cef7eb673d0b39265739a/packages/core-js/modules/es.promise.js#L76 it seems [14:09:43.0000] a false positive or? [14:10:32.0000] unclear... the code is really abstract everytime i have to cross ref all these files for corejs [14:10:44.0000] it looks like it replaces Promise if it is wrong [14:11:06.0000] we likely should make a test/script to just punch away the globals ourselves and see what breaks [14:11:31.0000] "see what breaks" is tricky, turns out [14:11:39.0000] since almost all pages are throwing random errors all the time [14:12:03.0000] maybe a custom build of firefox or chrome that has prints in these @@species sections [14:12:05.0000] and also have try-catch suppressing half of the errors [14:12:28.0000] anyone with sentry on their page [14:12:38.0000] will slurp up errors without you ever seeing them [14:14:35.0000] Bakkot: I'm more concerned with only the scope of these coreJS detection mechanisms [14:14:42.0000] the whole page is too big to reason about [14:15:20.0000] i'm already patching stuff in devtools, idk, you can't slurp up errors without me seeing them [14:16:04.0000] so far, all things i've read in the output are from coreJS [14:16:14.0000] which is kind of impressive? [14:16:24.0000] but it replaces builtins with its own stuff [14:17:09.0000] is it babel that inserts corejs [14:20:18.0000] often [14:20:21.0000] but not always [14:30:01.0000] a lot of these though are semi-easy to detect, like they construct a promise subclass that has fulfill and reject as the same function identity [14:31:23.0000] the real issue is wading through all the core-js history to see if the minified code matches up [14:31:36.0000] which at this point i'm just starting to assume it is all this feature detection [14:32:58.0000] i had to start labelling which kind of detection it is coming from, the only one i'm a bit scared of is the latest core-js i have to detect via the result of new species(...).constructor.name === 'FakePromise' [14:33:18.0000] but that gets minified out [14:33:50.0000] detecting species().constructor is typeof 'object' might be saner? 2020-05-23 [17:08:17.0000] so if species doesn't work core-js will polyfill it with a impl that does make it work, https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.js#L256 [18:50:47.0000] bradleymeck: make it work purely in user land? [19:50:40.0000] It does, but has a minor bug with promise.finally polyfills detection not caring about species [20:09:54.0000] fascinating [20:10:53.0000] so if engines turn off subclassing sites might break not because they depend on it but because the corejs polyfill will suddenly kick in for promises [20:12:53.0000] maybe it's still okay as long as the polyfill is spec-perfect? [20:13:33.0000] bradleymeck: what's the bug in promise.finally? the polyfill doesn't appear to touch it [20:13:40.0000] and finally calls .then so [20:14:24.0000] Separate file, basically just checks if it can be called with 2 arg params [20:15:37.0000] If it can't (such as missing) it replaces it with a species thing [20:15:45.0000] rkirsling: yeah one can hope [20:16:20.0000] https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.finally.js#L20 [20:18:32.0000] whatā€™s the use case of corejs today [20:18:47.0000] es6 has been a few years [20:18:53.0000] my understanding is that it gets injected by babel [20:19:03.0000] to polyfill modern features and fix bugs [20:19:37.0000] iā€™m curious about the es6 era stuff, which are arguably no longer modern [20:20:43.0000] well i mean if you're targeting ie8 [20:21:11.0000] i think babel-preset-env will stick in stuff like import { Promise } from 'core-js' [20:23:07.0000] does anything get dropped from it? [20:23:37.0000] wdym "dropped" [20:24:01.0000] has any feature been removed from corejs because of widespread native support? [20:24:25.0000] or is its mandate to shim all post es5 features? [20:25:06.0000] oh i have no idea [20:26:04.0000] it looks like it might even polyfill the JSON global? [20:26:16.0000] which would be what, pre es5? [20:26:43.0000] shu: there's still a large case for es6 polyfills [20:26:49.0000] shu: and there's still large usage of older browsers. [20:27:14.0000] and no, neither core-js, nor any of my stuff in the es-shims family, have or ever likely will "drop" anything [20:27:30.0000] altho i'm sure there's stuff that hasn't been gotten around to yet [20:31:44.0000] ljharb: how much older are we talking? [20:31:59.0000] all my shims work in IE 6 [20:32:15.0000] (up to the limit of the engine; obv getters/setters requires native support, etc) [20:32:28.0000] as far as usage, IE 9 is still frequent enough to warrant shimming [20:32:28.0000] MS had that eradication campaign years ago though [20:32:41.0000] yeah IE9 I'll believe [20:32:42.0000] don't south korean banks have to use ie9 or 11 or smth [20:32:42.0000] they didn't support newer IE on old enough windows to make that useful [20:32:49.0000] IE 6-8 is largely dead because of SSL stuff [20:33:26.0000] SK banks are heavy users of activex is what i recall [20:34:12.0000] still can't shake how weird it is to have such technology be gov't-mandated [20:34:26.0000] it happens in the US too [20:34:32.0000] ljharb: how do you run ie6 to check support? [20:34:37.0000] we used to have to maintain FIPS compliance in node's crypto module [20:34:53.0000] shu: either via browserstack, or via the windows VMs that microsoft has distributed for that purpose for years [20:35:21.0000] i see [20:35:45.0000] I mean compliance is not gonna be avoidable but it was literally "you have to use IE" no? [20:36:23.0000] (unless that was just the effect of whatever the law actually said) [20:37:01.0000] i'm def not an expert on SK law [20:37:43.0000] but i believe they had to use certain software to be in compliance (activex things) and that only works in old ie [20:37:54.0000] a lot of the use of IE9 is employers who mandate it, which is in some ways similar [20:38:34.0000] ljharb: just for your own packages, you donā€™t plan to drop eg ie6... ever? [20:39:14.0000] or until MS makes it impossible to even run, or other considerations? [20:40:49.0000] shu: i don't see much value in doing so. it's already both necessary and relatively trivial to swap out packages in the ecosystem as part of your build process when your supported browsers no longer need them [20:41:17.0000] the other thing is, the delta between "works in IE 6" and "works in IE 9", or "works in IE 11" is actually pretty small [20:41:29.0000] also it's not just IE. "old android" is a massive offende [20:41:29.0000] r [20:41:38.0000] pre 4.4? [20:41:40.0000] and Opendoor had significant traffic from Safari 6. [20:41:43.0000] devsnek: yes [20:41:45.0000] :( [20:41:59.0000] airbnb could afford to drop IE 9, because its marginal income per visitor was tiny [20:42:11.0000] but opendoor could earn 100k from any *one* visitor [20:42:18.0000] and safari 6 was like 2-3% of all traffic [20:42:43.0000] compelling [20:43:04.0000] also, tons of people are on "not latest" chrome and firefox [20:43:10.0000] "autoupdate means everyone is up to date" is a huge lie [20:43:14.0000] that is certainly true [20:43:16.0000] https://gc.gy/57910391.png [20:43:24.0000] i was wondering more about being 5+ years out of date [20:43:29.0000] devsnek: rimshot [20:43:34.0000] my working assumption is usually 5 years [20:43:38.0000] shu: 5 years ago, zero browsers were fully ES5 compliant. [20:43:43.0000] shu: let alone ES6 [20:43:57.0000] shu: the last 2-4 years has been amazing for compliance tho [20:44:06.0000] my internal doc is called ā€œoperation extinctionā€ [20:44:15.0000] lol [20:44:27.0000] ever since browsers transitioned to the evergreen idea its been fantastic [20:44:29.0000] nothing like finding a kind of genocide that makes everyone happy [20:44:40.0000] moving to new systems like turbofan to make shipping features easier [20:44:48.0000] devsnek: post-auto-update tho, there's still *tons* of people who don't update [20:45:07.0000] ljharb: iā€™m aware of that [20:45:10.0000] autoupdate doesn't work if their hard disk is full of viruses and photos :-p [20:45:21.0000] who are the folks who have not updated software in 5 years [20:45:31.0000] my grandma was using 5 year old firefox [20:45:33.0000] turns out, lots of people that own a home and want to sell it [20:45:33.0000] until a few days ago [20:45:40.0000] when i told her she should update it [20:46:19.0000] well iā€™m sure we have stats for this but i am too lazy to get my laptop [20:46:26.0000] i also often talk to older folks that don't know how to update, and also think machines shouldn't be replaced more often than every 7-10 years [20:46:49.0000] hardware replacement is synonymous with downloading new software for them? [20:47:01.0000] lol no, but i mean that they're also on older machines [20:47:09.0000] that don't often support newer OS's, and thus browsers [20:47:38.0000] when things don't support far enough back, it doesn't encourage users to update, it just encourages them not to stir the pot [20:47:58.0000] nobody wants to fix what ain't broke [20:48:24.0000] (also, when certain website just don't work, they think it's their fault, and are embarrassed to ask for help and thus find out that it's not their fault, they just need to update) [20:48:36.0000] so iā€™m not really asking for anecdotes for people who donā€™t update software, i know that is true [20:48:40.0000] lol k sorry [20:49:23.0000] i guess i am surprised that half a decade of not stirring the pot still gives people enough working parts they can do useful things, like go to airbnb.com [20:50:04.0000] but really, i shouldnā€™t be [20:50:21.0000] i wonder how far back google.com works [20:50:38.0000] i think the main page should work for basically anything [20:50:49.0000] mosaic or bust [20:51:14.0000] well you do get cut off by tls [20:51:34.0000] in another 20 years i should like to commission a study on if the web platform was one big moral hazard [20:52:04.0000] lol [20:54:28.0000] snort [20:58:41.0000] shu: I think there's a lot of people on > 5 year old phones, esp. outside of America [20:59:37.0000] ah, and once the OEM stops support and no more over the air updates, software is frozen? [21:00:43.0000] a lot of the cheap ones never get updates in the first place [21:01:11.0000] this is why android is moving to the modular setup where they can push security updates and stuff through the play store [21:02:16.0000] shu yup [21:02:36.0000] and as devsnek says "OEM stops support" is often very soon after the phone is released [21:03:18.0000] even flagship droids can have spotty updates [21:03:34.0000] economics of it makes sense [21:04:05.0000] well its only a problem because they all feel the need to add their weird patches into the kernel [21:04:16.0000] then lo and behold updating those patches is hard [21:05:05.0000] iā€™ve heard funny stories from the art (android runtime) vm team about working around buggy OEM vms that crash on specific opcode sequences [21:05:35.0000] so you need to generate certain magic incantation gadgets for certain phones [21:05:38.0000] aw man [21:07:33.0000] reminds me of https://twitter.com/XMPPwocky/status/1261130110003843073 [21:08:32.0000] :( [21:14:44.0000] I genuinely hate machines [21:14:44.0000] lol [21:16:28.0000] that is an amazing thread [21:46:57.0000] ljharb: braces had nothing to do with what that guy was saying :- [21:47:00.0000] :-/ [21:47:13.0000] the `if` was purely incidental [21:49:52.0000] lol maybe but i can't understand the thesis of an essay that has spelling and grammar errors, they're too distracting [21:51:21.0000] I mean it's pretty inflammatory to suggest that dropping braces isn't a valid style choice though [21:52:05.0000] i don't see why, that's what caused heartbleed [21:52:19.0000] i'd say it's a pretty bold claim to say that omitting them is safe [21:52:21.0000] there's nothing hard to read about a two-line code example that doesn't use braces on a if [21:52:36.0000] I don't know what to say [21:53:01.0000] it's webkit style to always drop them for a one-line body [21:53:02.0000] i'll hide my comment tho, since they edited the result [21:53:21.0000] rkirsling: sure. from what i recall, webkit's style isn't what i'd call consistently readable anyways :-) (that's subjective, ofc) [21:53:36.0000] it's not uncommon to drop them for a *same*-line body tho [21:53:43.0000] I mean it's extremely consistent so I don't know why you wouldn't call it readable [21:53:49.0000] consistency alone does not readable make [21:53:51.0000] consistency is the important part [21:54:07.0000] it's a minimum, but not sufficient, requirement [21:54:33.0000] I mean this isn't about what one would recommend a codebase do [21:55:31.0000] it truly had nothing to do with anything here... [21:55:48.0000] sure, agreed [21:55:54.0000] i just couldn't tell because the if statement distracted me [21:56:37.0000] I actually thought the density of the original example was the strength of it [21:57:08.0000] for me, the modified version makes the point clearly, and i totally missed it in the original one ĀÆ\_(惄)_/ĀÆ [21:57:13.0000] i.e. "it would be easy to get lost reading this without making the placeholders explicit" [21:57:33.0000] now I'm not sure it's making a point at all [21:57:35.0000] tbh i still can't remember which name goes with which style, nor have i totally made up my mind as to which form i prefer [21:57:54.0000] though (8) is its own valid point [21:57:56.0000] and those threads are often full of people who perceive every comment as a threat to their preferred style [21:58:20.0000] he's arguing for the latter, not the former [21:58:39.0000] gotcha [21:58:39.0000] which is why I said the point got lost in the cleanup [21:59:32.0000] hm, maybe so [21:59:41.0000] clearly i missed the point in both cases, then [22:02:05.0000] Bakkot: you know who else loves utf16... [22:55:44.0000] shu: is it javascript [22:56:11.0000] I feel like if JS loved UTF-16 it would have had UTF-16 in it somewhere, instead of the unholy thing we have [08:41:43.0000] ljharb: re: https://github.com/tc39/proposal-promise-any/issues/38 [08:42:11.0000] it looks to me like everyone has said the things they have to say and everyone except you still wants it to be an own property [08:42:24.0000] would you be willing to let it go so that the proposal can ship? [08:42:31.0000] cc mathiasbynens ^ [09:10:11.0000] No, Iā€™d like it discussed in plenary. It already has consensus as it is. [09:33:25.0000] OK, I guess we can put something on the agenda. [09:33:33.0000] I don't know what the benefit of that discussion will be though. [09:33:55.0000] What benefit do you see in having the discussion there? [09:34:10.0000] Except that we can put it to a vote if discussion fails again, I guess. [10:24:02.0000] i also believe that discussion wonā€™t be a good use of plenary time [10:30:12.0000] ljharb: without new insight, and i know your position on voting, itā€™s unclear to me too what you want that agenda item to do [14:00:06.0000] gather opinions from those not present in the github thread [14:01:05.0000] mark gave consensus for the current approach, and seems to have changed his mind in the thread; as have others; i'm interested to know what the broader committee thinks about own data vs prototype accessor properties in a case like this [14:01:43.0000] there's a lot of places in es6 that changed to be prototype accessors, and i'd been under the impression that was an intentional philosophical trend [14:05:20.0000] in particular, changes in stage 3 generally are supposed to be those that arose from implementor or user feedback, that weren't considered previously. it was reopened with what seems to me like stage 2 design considerations (ones i don't agree with). i don't recall seeing any strong argument that a change is more implementable than the current spec - if i missed one, can you point me to it? [14:32:06.0000] do any of the accessors we currently have return mutable structures [14:34:39.0000] nope, they all happen to return primitives atm [14:36:38.0000] everyone seems on board with primitive properties being accessors on the prototype; the own primitive properties are that way because legacy. this is just the first time an object property on an instance has come up afaik [14:53:42.0000] I am not really on board with primitive properties being accessors on the prototype if there is not some underlying state they reflect which is otherwise available [14:54:09.0000] I think it makes sense to use prototype accessors iff the information they give you is reflected elsewhere [14:54:18.0000] if the property itself is all the data there is, I do not [14:54:21.0000] (as I said in the thread) [14:56:38.0000] ljharb: also fwiw I am the one who asked for stage three with accessor on prototype, and I regret doing so [14:57:12.0000] what do you mean by "reflected elsewhere"? [14:57:17.0000] regex flags is an accessor, for example [14:57:43.0000] I mean that the information they give you, or some of that information, is available by other means [14:57:48.0000] regex flags, for example, also affect behavior [14:57:54.0000] right [14:57:56.0000] so there is _underlying_ state which they reveal [14:58:00.0000] so it makes sense for them to be accessors [14:58:13.0000] imo the list of errors is underlying state for AggregateError objects [14:58:25.0000] it's the only thing that differentiates it from the other error types [14:58:52.0000] it is not underlying [14:58:56.0000] there is no other way that information is reflected [14:59:02.0000] that _is_ the state [14:59:13.0000] compare, for example, the .name own property of functions [14:59:37.0000] sure. but having a name doesn't make it a function [14:59:47.0000] ... what? [14:59:56.0000] you can delete the property and it stil [14:59:59.0000] it's still a function [15:00:04.0000] ... ok? [15:00:09.0000] what does that have to do with anything? [15:00:16.0000] so "errors" is the essence of an aggregate error instance [15:00:24.0000] otherwise it's just a normal error with a property on it [15:00:32.0000] are we suddenly aristotelians? [15:00:41.0000] no idea what that means [15:01:02.0000] I guess it's Plato not Aristotle really [15:01:02.0000] https://en.wikipedia.org/wiki/Theory_of_forms [15:01:59.0000] anyway my point is that it seems very strange to me to insist that things "have essences" distinct from... what they are [15:02:10.0000] an aggregate error is a thing with errors, yes [15:02:15.0000] that is why it has an errors property [15:02:19.0000] right [15:02:31.0000] but that doesn't mean it needs to be an accessor [15:02:35.0000] but in JS, things are generally things because of slots (i'm sure there's counterexamples) [15:02:44.0000] a function is a function because of [[Call]]. `name` is incidental [15:03:19.0000] errors are weird in that there's no inherent difference between all the existing error types, and i don't want to add another weird error type [15:03:54.0000] wait, you are the one who is trying to add another weird error type [15:04:14.0000] to me this makes it a normal instance instead of a weird one [15:04:16.0000] you just said you were opposed to AggregateError being a normal error with a list of errors attached [15:04:21.0000] right [15:04:24.0000] because that's weird [15:04:27.0000] what [15:04:30.0000] objects have properties in javascript [15:04:33.0000] that is the normal state of affairs [15:04:38.0000] slots are not the normal state of affairs [15:04:43.0000] right but those properties are not their brand [15:04:49.0000] things are what they brand check to be [15:05:05.0000] otherwise they're just objects with properties that you're duck typing [15:05:52.0000] I am not on board with the philosophy that brand checks are good, but leaving that aside for the sake of argument: OK, so that means you are introducing _a new brand check_, which is to say you are introducing _a new, distinct kind of object_ [15:06:05.0000] as opposed to just having the one kind of error [15:06:39.0000] yes. Aggregate errors are a new distinct kind of object [15:06:47.0000] not unless we choose to make them so [15:06:54.0000] we do not need to make that choice [15:06:59.0000] we did not make that choice for other error types [15:07:03.0000] I don't think we should do so for this one [15:07:43.0000] i think we should have [15:07:55.0000] and tbh i donā€™t think that was an active choice, it was just legacy [15:08:20.0000] I can call up my dad and ask I guess [15:08:28.0000] that would be very interesting history to know [15:08:30.0000] but I am reasonably confident that it was not just legacy [15:08:46.0000] if thereā€™s actually a philosophy behind it then that should inform this, and Iā€™d love to know it [15:09:09.0000] I'll ask next time I talk to him, I guess [15:09:11.0000] but I don't think it's actually all that important [15:09:21.0000] the language is what it is [15:09:23.0000] absent one, i consider it a mistake (accidental or intentional), and i donā€™t want to worsen it by adding yet another error type [15:09:34.0000] you are the one adding another error type! [15:09:43.0000] I am so confused by your claim that you are not adding another error type! [15:10:02.0000] "things are what they brand check to be" - you [15:10:05.0000] lol, ok let me try again [15:10:18.0000] error types, unlike other types, lack proper differentiation between themselves [15:10:33.0000] i donā€™t want to add another error type that isnā€™t properly differentiated from the others [15:10:50.0000] why [15:11:08.0000] why not instead say that, consistent with the above, there is just one "type" of error from the brand check perspective [15:11:21.0000] and that to add a new brand would be to split that type into two [15:11:23.0000] for no reason [15:11:28.0000] i see that argument [15:16:02.0000] i mean, i donā€™t agree itā€™s for no reason. But i concede that it would result in two clouds of errors, one of improperly distinguished ones, and the other with aggregate error. And especially if we never add new error types, one might see that as a wart instead of as an improvement. [15:21:27.0000] that is roughly my position, yes. actually mine is somewhat stronger: my position is that it is in general bad to make things brand-check distinguishable unless there is some reason to do so other than liking things to be brand-check distinguishable [15:21:31.0000] entities should not be multiplied without necessity, and all that 2020-05-24 [20:27:43.0000] reminder about https://github.com/tc39/ecmarkup/pull/186 fwiw (maybe Bakkot is in the ecmarkup zone? :D) [21:03:56.0000] merged, sorry for the delay [21:04:43.0000] thanks! 2020-05-25 [03:47:10.0000] ping mathiasbynens do you think there is enough detail in the slides? [03:47:55.0000] Do you need any help with the slides also? we have an interest in seeing this resolved [07:40:38.0000] separate subject: how do people feel about https://theonline.town/ for hallway track? [07:40:46.0000] it is 2d, so a lot less cpu intensive than hubs [07:40:49.0000] but it has the same idea [07:43:19.0000] example: https://theonline.town/C186k8irbxJ5fSSL/foo [09:09:33.0000] ystartsev: the detail is in the 100+ comment thread. i'm really hoping the slides + comments in speaker notes are sufficient [09:11:19.0000] ystartsev: it was mostly/only ljharb opposing own data property at the time, with other people not really caring very strongly either way (although V8 and leobalter voiced a weak preference the other way around) [09:11:55.0000] ystartsev: now that ljharb withdrew his concern + we have additional data from more implementers + SES folks, i really think we're good to go [09:13:08.0000] TL;DR i think everyone who cares strongly already participated in the thread, and there's now agreement there, so let's just get that consensus ratified in plenary [10:55:58.0000] mathiasbynens: for the argument processing order one it is probably worth having a slide about what the differences in behavior are [10:56:13.0000] because I expect us to discuss that, and I expect it will be a lot easier to discuss if there's a slide to point at [12:13:04.0000] ystartsev: the 2D part sounds really nice :D [14:21:59.0000] Bakkot: yep, Shu wanted to present that part and he'll put something together [14:22:05.0000] ah, cool cool 2020-05-26 [09:03:55.0000] incubator call? ping ljharb shu [09:04:25.0000] leobalter: also [09:04:49.0000] ystartsev: i am in the call [09:05:13.0000] ystartsev: are you in a different call? [09:05:21.0000] yes [09:05:24.0000] it looks like we have 2 [09:05:35.0000] ystartsev: i am in https://meet.google.com/sao-fyma-sxe [09:05:36.0000] ystartsev shu I've been waiting forsomeome to allow me in the call [09:05:44.0000] this is a different link that what we have [09:05:48.0000] we are on our way [09:05:48.0000] I'll ping caridy [09:18:55.0000] oops, i didnā€™t have it in my calendar [09:18:59.0000] is it now? [09:36:58.0000] apparently google meet's web app doesn't show presented screen contents; i had to switch to the ios app to see it :-/ [14:55:43.0000] ljharb: I'm going through our next agenda, and I'm curious about something in Ergo checks for private fields. What's the benefit to this instead of instanceof? [14:58:30.0000] davepoole: instanceof is brittle, and can be faked with `Symbol.hasInstance` [14:59:12.0000] davepoole: also it doesn't work cross-realm for builtins (not that that applies to private fields) so i reflexively am repulsed by it in code review :-) [14:59:40.0000] davepoole: iow any use case for the "private" in private fields also needs it to be robust, which means anything forgeable is out [15:00:06.0000] gotcha, thanks! [15:52:32.0000] devsnek: https://github.com/tc39/proposal-record-tuple/issues/65#issuecomment-634321864 is pretty rude. [15:53:28.0000] hm? it seemed like a reasonable compromise to me [15:54:44.0000] you're asserting that the semantics littledan and erights and and I have been arguing for are broken. [15:54:48.0000] they are different from the semantics you want [15:54:58.0000] I mean, they are [15:55:04.0000] :| [15:55:12.0000] no [15:55:16.0000] they are different from the semantics you want [15:55:46.0000] and also don't compare numbers correctly [15:55:57.0000] according to === [15:56:03.0000] so we could just add a new thing [15:56:38.0000] we are discussing how to compare structures. IEEE does not mandate a particular semantics for comparing data structures containing numbers. [15:56:53.0000] there is no objective notion of "correctness" to appeal to here. [15:57:03.0000] there are different possible semantics, with different justifications. [15:57:11.0000] not the structure, the numbers in the structure [15:57:15.0000] asserting that your preferred semantics are the only correct semantics, and all other semantics are broken, is rude. [15:58:10.0000] "if it doesn't work on numbers" [15:58:17.0000] I'm not entirely sure how to phrase it [15:58:44.0000] I disagree with this kind of categorical phrasing like "it doesn't work on numbers" [15:59:16.0000] if === does your behaviour [15:59:29.0000] we still need the one that compares them how numbers are supposed to be compared [15:59:33.0000] yes I think I know what you're getting at and I disagree [15:59:53.0000] we shouldn't provide it at all? [15:59:58.0000] (gotta run to a meeting) [16:01:13.0000] littledan: you don't think that js should include a comparison that compares the numbers according to their spec [16:01:20.0000] and should leave that to userland [16:02:17.0000] well, I don't have a very strong reason why it'd be fatal; we could put it on Record. [16:02:49.0000] well it should be more general [16:02:55.0000] I'd want to use it in place of === [16:03:02.0000] yeah, it'd work on Tuples as well [16:03:06.0000] and all values I guess [16:03:10.0000] cool [16:03:42.0000] but, I don't really understand where you'd want to use it, beyond simple point/complex number examples. I don't understand why you'd want to use it in place of === in general. [16:04:00.0000] id want to use it everywhere for everything [16:04:08.0000] why? [16:04:16.0000] because the semantics you're proposing don't work [16:04:30.0000] unless you're memoizing things I guess [16:04:38.0000] but I can't imagine that's the common case here [16:06:44.0000] in any case I reached the point where I want to stop arguing about this more than I want js to be a good language so I'll just make an eslint rule for whatever method we add [16:38:27.0000] yeah sorry I guess I'm fine with stopping arguing too... what do you mean by an eslint rule? [16:39:57.0000] littledan: to say that occurances of === should be replaced with Object.strictEquals or whatever it is called 2020-05-27 [03:06:54.0000] I guess it's possible to implement such a rule whether Object.strictEquals is built-in or defined in user code. I'm still not really convinced that you want those semantics all the time (and continued assertions of "it's broken" aren't so persuasive to me), but if JS programmer does what to write those checks for their code, sure, they can go for it. [03:08:08.0000] I feel like we might've added edge cases or functions in the past when there were specific requests made, but that that's not really the best design method in general. For one example, I'm not sure if `BigInt.asIntN` is all that useful, even if it had a role in selecting BigInt over Int64--we could've just chosen BigInt without adding that function. [09:47:28.0000] Bakkot: I'm really happy you're bringing do expressions back to the game. on slide 10: I believe it's ok w/ loops and it does not create anything we don't know. `for (let a of 'abc') a;` completes to 'c' already, this should not be "bad". It's just a pre-existing fact [09:48:02.0000] leobalter: it's a fact very few people are exposed to currently, and which many people have expressed surprise at in the context of this proposal [09:48:14.0000] on slide 11: declarations is as bad as declarations in blocks. [09:48:32.0000] ? [09:48:36.0000] declarations in blocks are fine in general [09:48:40.0000] do you mean, in do-expressions? [09:49:35.0000] the idea is that the prohibition on loops and declarations ending a do-expression would be applied recursively in the last statement(s) of the block, so that all of `do { let x; }`, `do { { let x; } }`, `do { if (foo) { let x; } else { 0; } }` etc would be a syntax error [09:50:14.0000] https://www.irccloud.com/pastebin/cKAO7oSY/ [09:51:24.0000] ah, that's specifically because of B.3.3 hoisting, which I am also proposing to prohibit in do-expressions [09:51:41.0000] that code would give you an error in a module, which I think is reasonable [09:51:50.0000] (or any other strict context) [09:51:57.0000] I believe this is a concern for userland, a linter should worry about it [09:52:09.0000] hmm [09:52:24.0000] I don't think there is any reason someone would want to end a do-expression with a declaration currently. [09:52:29.0000] I'm not objecting to anything but expressing a preference, to be clear here [09:52:40.0000] so I don't see a benefit to allowing it [09:53:20.0000] I agree no one want to end a do-expression with a declaration, but I'd keep the semantics equivalent for blocks. We are just capturing the completion result [09:53:58.0000] it's not allowing it, it's actually not creating special rules to disallow it [09:54:39.0000] strong agree with leobalter but i think you knew that already [09:54:41.0000] most of these problems will be taken care of in strict mode / module code [09:54:49.0000] my general philosophy is that if there is a place where a syntactic construct would always be surprising, we should just disallow that syntax [09:55:04.0000] always be surprising or undesirable, I should say [09:55:04.0000] also `do {}` should just be undefined [09:55:24.0000] `do {}` being undefined I am on board with [09:55:34.0000] I'll start writing that instead of `void 0` [09:55:52.0000] lol [09:55:52.0000] I am really happy to see do expressions in the agenda, I'm a big supporter of this feature [09:56:04.0000] as for disallowing certain syntax [09:56:27.0000] i think its just kind of awkward at the statement level cuz you have to start worrying about what happens if you comment out a line [09:56:56.0000] hmm, that's a fair point [09:57:23.0000] this is also a big thing: `do { throw 'foo' }` we solve the lack of throw expressions [09:57:47.0000] but not the tendency of people to throw strings :P [09:58:09.0000] don't ask me to form a full example in irc chat [09:58:14.0000] haha [09:58:28.0000] i think the main reason for throw expressions was concise bodies [09:58:31.0000] for declarations, the other option is to change the completion value for the declaration to be the RHS (or undefined) [09:58:42.0000] at which point you might as well just drop the `do` and use a non-concise body [09:58:48.0000] or in the case of class or function declarations the original value of the binding (because they are hoisted), though that's... awkward [09:59:16.0000] devsnek: throw expressions also make sense in default parameters and a few other cases [09:59:16.0000] i think undefined makes the most sense [09:59:23.0000] oh fair point [09:59:40.0000] I think if someone writes `do { function f(){} }` they should either get an error or `f` [10:00:07.0000] yeah i'm fine with making function declarations return the relevant function [10:00:16.0000] wait are function declarations mutable [10:00:19.0000] yeah [10:00:20.0000] and hoisted [10:00:25.0000] aw man [10:00:34.0000] so that one is awkward; probably you want to do the original value of the binding, I guess? [10:00:38.0000] which is weird [10:00:39.0000] yeah [10:00:47.0000] well i don't think binding fits into it [10:00:56.0000] this is part of why I want to disallow declarations here :P [10:01:18.0000] its more like function declarations know the function instance they create [10:01:24.0000] without going through the binding [10:01:36.0000] i think we need to just very carefully go through completions [10:01:37.0000] yeah, same thing [10:02:22.0000] the surprising completions are mostly just declarations and loops [10:02:50.0000] it is maybe a bit surprising that the completion of a `try { } finally { }` comes from the `try` and not the `finally`, but not that surprising I think. [10:03:12.0000] once you know what the deal with finally is [10:03:14.0000] should do expressions blocks always run in strict mode? [10:03:39.0000] well there is precedence with classes [10:04:28.0000] leobalter: it's a little tempting, but the last time we discussed it people did not like having strictness change within a function body [10:04:42.0000] as opposed to the boundary of a function [10:04:56.0000] or class [10:05:02.0000] given static initializers [10:05:10.0000] classes are functions basically [10:05:38.0000] yeah i meant, since they appear to be within something shaped like a function `name parens block body` [10:05:48.0000] since they don't* appear [10:12:47.0000] I am still leaning towards banning declarations as the last statement in a do, I think [10:12:49.0000] they are just too surprising [10:13:07.0000] unless we can change their completion semantics to be less surprising [10:14:11.0000] I think with destructuring any possible thing is surprising [10:16:50.0000] would just having it be the RHS really be surprising, even with destructuring? [10:16:57.0000] that's how assignments work (... I hope) [10:36:15.0000] Bakkot: it can have more than one rhs [10:36:33.0000] `let a = 1, b = 2` [10:45:52.0000] eh, `a = 1, b = 2` completes to `2`; seems fine to me to do the same thing when there's a `let` in front of it [10:46:32.0000] and to give `undefined` when there's no initializer, though that one seems not useful (but at least not surprising) [10:46:59.0000] no initializer on the last declarator, that is [10:53:32.0000] Bakkot: the debugger statement is also kind odd [10:54:13.0000] it just returns whatever the host wants [10:54:18.0000] does anywhere not return undefined? [10:54:28.0000] i don't think so [11:05:35.0000] Bakkot: you could use `do { throw x }` in default params etc too tho, no? [11:06:01.0000] Bakkot: does the completion of a try/finally come from the finally if the finally has a `return`? [11:28:46.0000] ljharb re first question: yes, that's the point [11:29:23.0000] re second question: yes, or a `break`, which is actually relevant because `do { x: try {} finally {0; break x} }` would be legal under the proposal as I intend to propose it [11:29:43.0000] though, you know, don't write that code [11:33:27.0000] hard agree [12:34:46.0000] oh geez I can't believe I hadn't thought about putting function decls in a do block [12:36:19.0000] Bakkot: I think `do {}` has to be undefined though, right? how else can if-without-else work? (and only allowing if-with-else would be uncomfortable...) [12:36:43.0000] if-without-else has a completion value; it's `undefined` [12:36:53.0000] `0; if (false) ;` completes to `undefined`, not `0` [12:37:12.0000] but yeah I think undefined makes sense [12:37:18.0000] and `0; if (true) ;` ? [12:37:23.0000] also undefined [12:37:35.0000] ah k, but `0; if (true) 1;` would be 1? [12:37:39.0000] indeed [12:37:41.0000] sgtm [12:38:38.0000] I hadn't thought about that, but yeah, I think requiring that knowledge incurs the trivia cost jorendorff talked about [12:39:01.0000] probably best for the user to be correct for the wrong reason šŸ˜… [12:40:01.0000] hmm pipeline still needs to be added to the agenda [12:40:20.0000] hurry up TabAtkins, before it spills into the following meeting XD [12:41:31.0000] No it's going in the next [12:41:34.0000] Instead [12:41:41.0000] ohh I misunderstood [12:41:55.0000] sounded like you had your arguments all in order šŸ˜… [13:06:47.0000] I don't actually understand what's being proposed with the spaceship operator thing [13:07:08.0000] is it dependent upon operator overloading? [13:08:39.0000] rkirsling: it's going for stage 1, so it's just about solving a problem :-) [13:09:08.0000] rkirsling: but that solution would be `a <=> b` as sugar for `a[Symbol.compare](b)` or similar, which would return 0, a negative number, or a positive number [13:09:28.0000] I see [13:09:37.0000] rkirsling: the same semantics it has in ruby already [13:12:52.0000] but is that just following the suit of a general operator overloading mechanism in Ruby? [13:13:57.0000] not that intimately familiar with Ruby but I'm imagining something like `__add__ ` in Python [13:19:29.0000] yeah looks like it's the same thing except that Ruby allows `<=>` as a function name [13:19:35.0000] (how very Scala-like) [13:50:50.0000] well sure, it does just fall out of ruby's overall semantics [13:51:00.0000] but the specific use case is valuable; ie, a generic protocol to compare values [13:51:22.0000] strings have localeCompare, numbers have subtraction, other types don't have anything [13:52:02.0000] yeah no I'm not worried about it being a valid problem to solve [13:53:09.0000] I was just confused by what's being proposed, since it'd be weird to have a proposal depend on operator overloading and not be clear about that [13:55:56.0000] it very much does not [13:56:12.0000] instanceof already calls into a symbol protocol, as does == [13:56:15.0000] this is just another one of those [13:57:00.0000] `==`? [13:58:10.0000] doesn't it? with Symbol.toPrimitive? [13:58:17.0000] or maybe only if one of the types is a primitive, i forget [13:58:48.0000] I gotcha [13:59:17.0000] Symbol.parenthesized when [13:59:26.0000] either way there's precedent with instanceof [13:59:47.0000] wasn't that more about finding some way to describe instanceof behaviour [13:59:53.0000] on function instances or something [14:00:25.0000] i don't know the motivation, i know it made an unreliable operator useless :-p [14:00:43.0000] but that's because instanceof is something that often needs to be known robustly; comparison isn't [15:12:24.0000] I actually didn't realize Symbol.hasInstance existed until days ago [15:12:28.0000] what was the motivation there? [15:20:26.0000] masochism, presumably [15:22:20.0000] omg same [15:22:29.0000] and it's existed for a while too [15:22:32.0000] o.0 2020-05-28 [17:42:40.0000] say, wrt function impl hiding [17:42:58.0000] was adding a field to property descriptors ever suggested? [17:44:01.0000] rkirsling: for what [17:44:30.0000] I can only remember like "yeah directives are awful and should be a thing we did once ever but it's better than mucking further with function syntax" [17:45:24.0000] rkirsling: you mean like `define(o, 'methodName', {..., makeItHidden = true}`? [17:45:37.0000] no i don't believe it was since it wouldn't handle a simple fn.toString() [17:45:55.0000] but it seems like `hidden` as a souped-up version of `configurable: false` would be reasonable in theory [17:45:56.0000] ah [17:47:06.0000] or like `Object.hide()` I guess would be a similar idea [17:47:45.0000] i don't believe that exact api was mentioned but an accessor was talked about at some point [17:47:55.0000] hm sure [17:48:16.0000] how did you mean "wouldn't handle"? I'm sure I'm overlooking an important bit [17:49:02.0000] rkirsling: perhaps bradleymeck meant for local bindings [17:49:08.0000] rkirsling: how do you defineProperty a binding? [17:49:26.0000] ah right yeah [17:49:27.0000] yea, if you have a reference to the fn already somehow [17:50:10.0000] i have some vague recollections of discussions around the function author being the decider of whether it should be hidden or not [17:50:42.0000] so APIs that mutate the visibility of functions after the fact may be unsatisfactory [17:50:47.0000] I mean I guess you could argue that if you need a function to be hidden then perhaps it's acceptable to be required to declare it in this way and not that [17:50:53.0000] (i.e. not as a local binding) [17:51:15.0000] yeah I can see concern about after-the-fact [17:52:57.0000] a big implementation problem with visibility as a state of a *reference* instead of the function value is you'd have to then track that state on a per-reference basis [17:53:02.0000] that seems pretty gnarly [17:53:26.0000] oh hmm right [17:53:35.0000] I wasn't thinking of it in that way [17:53:56.0000] also the stack hiding directive no longer makes sense [18:07:10.0000] right. for some reason I hadn't thought of prop descriptors as describing the means of access and not the thing in itself, even though that sounds ridiculously obvious when I say it out loud [18:10:58.0000] out of a sampling of 2500 sites that I am now fairly confident about the coreJS detection happening for @@species, 100% of all traps are from coreJS [18:11:03.0000] thats nutty [18:11:09.0000] corejs!!! [18:11:21.0000] but it also means we likely need to instrument into coreJS itself since it replaces things [18:11:38.0000] that's some good data [18:11:46.0000] is that meme too dated now? have young'uns nowadays watched wrath of khan? [18:11:46.0000] I'm excited about this project [18:12:09.0000] bradleymeck: any insight into the vintage of corejs? i feel like it must all be pretty old [18:12:25.0000] i worry about some of the corejs stuff since userland would still be using it as if it were a @@species impl and we don't have numbers on users of corejs actually using things [18:12:34.0000] wait was the similarity to khaaaan there supposed to be obvious? šŸ˜… [18:12:40.0000] shu: i haven't tried to get that data [18:13:01.0000] i do know hatenablog is 2% of all usages of @@species pages and it uses an older one [18:14:17.0000] maybe we can dogeza them into updating [18:14:38.0000] idk, updating would still be emulating via a new polyfill [18:14:47.0000] i don't think updating actually fixes anything [18:15:35.0000] oh I meant "updating" in a general sense, but also I was half-joking [18:16:09.0000] i think the big thing would be getting babel to stop bundling it [18:16:22.0000] since that looks like what most of it is coming from [18:16:32.0000] most? all [18:17:43.0000] well likely not all but scraping is showing it to be used even if it isn't really needed so some build tool is doing it [18:19:25.0000] mhm [19:02:53.0000] I guess completion values for `break` are also pretty weird: https://github.com/tc39/ecma262/issues/1085#issuecomment-570464401 [19:16:43.0000] we should make a thing that generates random valid syntax and then asks whether the completion from it is reasonable or not [19:18:16.0000] you can call it YouCompleteMe [19:18:40.0000] "asks whether the completion from it is reasonable" requires knowing what "reasonable" means [19:18:51.0000] but it's easy to ask if engines are consistent, sure [19:19:01.0000] I did this when I implemented try-finally in my compiler [19:19:06.0000] found a lot of bugs [19:20:32.0000] https://github.com/shapesecurity/shift-codegen-js + a dozen lines of code for producing interesting ASTs will get you there [19:21:08.0000] Bakkot: I mean asks us [19:21:17.0000] that's pretty cool [19:21:17.0000] ahh [19:22:02.0000] I love fuzzers [19:25:51.0000] here's one for all the js values https://github.com/devsnek/fuzzy [19:25:54.0000] or most of them anyway [19:26:07.0000] Def needs some work though [19:26:14.0000] https://github.com/shapesecurity/shift-fuzzer-js does ~ all javascript programs [19:26:22.0000] bit out of date though [19:26:32.0000] also tends to generate duplicate bindings, which I need to fix [19:27:24.0000] ah, yours is the actual values, not programs [19:27:25.0000] neat [19:29:14.0000] yeah not as fun as generating code [19:29:23.0000] but it helped me write an etf library [19:30:28.0000] ... exchange-traded fund? [19:32:03.0000] erlang term format [19:32:14.0000] data serialisation [19:47:18.0000] are we writing prospectus for a new fund [19:52:32.0000] I was reminded recently that schwab's bond aggregate bond fund trades as SWAGX [19:53:06.0000] we should make a fund that tries to track JS companies, and then short it, and then intentionally stabotage the language [19:53:25.0000] I wonder if the ECMA member agreement anticipates that possibility [19:54:09.0000] well now, if you count ecma member companies as JS companies [20:02:34.0000] I'm not sure we can make anything worse than == [20:06:32.0000] rebindable syntax + sync XHR [20:06:52.0000] so that every `===` can be a main-thread-blocking network request [20:10:37.0000] innovative [20:11:04.0000] Bakkot: did you know that comparing two url objects in java by default does a synchronous dns resolution [20:31:42.0000] yeah [20:31:48.0000] also map lookups IIRC [21:09:04.0000] i mean, problems demand solutions [21:09:07.0000] i don't know what to tell ya [21:13:24.0000] problem: you want your URLs to compare as equal if they resolve to the same IP [21:13:27.0000] solution: stop wanting that [21:16:55.0000] when I was in grad school I had this comic hung on my wall: https://i.imgur.com/7LbRv4V.png [21:23:05.0000] lol [21:34:35.0000] i love it [21:44:32.0000] bradleymeck: corejs is not going to be possible to get any changes into, its maintainer is indisposed for 18 months [21:44:40.0000] bradleymeck: if that's what you meant by "instrument" [06:15:15.0000] ljharb: nah, i was just going to use the debugger to step into his code and muck around. since the sites are deployed we can't really change their code [07:14:55.0000] chairs, I'm not sure if the meeting agenda is getting a little overpacked; I'm fine to wait on the operator overloading discussion until next meeting if we are running out of slots [07:59:14.0000] littledan: i'd rather we drop from...import [07:59:23.0000] why not both? [07:59:26.0000] i have some prelim feedback that people aren't too keen oon the idea for now [07:59:34.0000] huh really? [07:59:40.0000] I always want to type `from...import` [07:59:46.0000] and i think there are better uses of time for now like op overloading [07:59:52.0000] well my topic is towards the end, so we can decide dynamically [08:00:06.0000] we can deprioritize from...import and see at the end which we have time for, or both [10:42:48.0000] seems better not to prematurely optimize the agenda :-) [10:45:12.0000] we can just skip everything before the needs consensus items [10:50:23.0000] editor's update is actually going to have some content which is not just routine updates this time [12:20:12.0000] @bterlson @bradleymeck can I get admin access to the https://github.com/tc39/proposal-compartments repo? I'd like to transfer 4-5 issues recently opened for Realms that I believe they apply to the compartments proposal. @erights is aware. [12:23:19.0000] leobalter: delegates are upgraded perms now [12:23:37.0000] does anybody have a concrete example of a function impl hiding use-case which involves "security-sensitive" code and not just library/polyfill code? I'm still unclear on how any reasonable sort of "confidentiality" is achieved if you can just open the resource directly as usual (or hell, even grep the specific places that would now be marked `"sensitive"`)? [12:24:17.0000] rkirsling: runtime fraud detection scripts that are dynamically updated over time, that runtime malicious scripts would thus be unable to dynamically adapt to [12:24:45.0000] rkirsling: iow yes, the malicious authors could download the code, but that drastically increases the window between "improved defense" and "improved attack" [12:24:59.0000] whereas if they can view the impl, they could try to write code to shorten that window [12:25:09.0000] (that's the understanding i have of one of those use cases, at any rate) [12:25:13.0000] ah okay, that's helpful [12:27:05.0000] bradleymeck: thanks! [12:28:27.0000] rkirsling: yea, its the diff of being able to exfiltrate source to find exploits vs not. fn impl hiding would lean towards people needing debugger access to get that kind of exfiltration [12:35:05.0000] thanks! [13:34:52.0000] bradleymeck: can you copy the link here, please? [13:34:59.0000] https://godaddy.zoom.us/j/92149833952 [13:43:27.0000] welp, V8 got its first bug report for "why isn't my finalizer running" [13:48:31.0000] Link? [13:50:10.0000] heh [13:52:04.0000] :D [13:53:48.0000] https://bugs.chromium.org/p/v8/issues/detail?id=10569 [13:54:34.0000] i'm waiting for the ones that involve `delete` [14:12:06.0000] tell them to try forcing a GC using Web Inspector and then see if it invokes [14:13:30.0000] will that mark or just sweep [14:31:45.0000] ystartsev: is avandolder actually implementing the iterator proposal rn? [14:41:00.0000] ah i found https://bugzilla.mozilla.org/show_bug.cgi?id=1568906 [14:41:02.0000] very cool 2020-05-29 [17:42:46.0000] could a node user enlighten me on the async contexts proposal, which seems to be largely lifted from the existing node api? [17:43:02.0000] by "automatic tracking through async tasks", how is that implemented exactly? [17:44:03.0000] any time a task or microtask is posted, the entered async local storage at the point of time of posting is remembered by the task? (is it COW?) [17:51:23.0000] shu: its like a linked list, each resource points to a parent resource [17:52:05.0000] sorry, i don't understand what that means [17:52:06.0000] shu: talks on async hooks may be more enlightening on underlying structure of the hooks used [17:52:20.0000] "this promise was created in this timeout which was created in this callback from this fs function which happened in the AsyncContext.run callback" [17:52:35.0000] it creates a new link like devsnek said in a kind of tree structure every time you queue a new async task [17:53:02.0000] ah, there's a linked list that functions remember at creation time? [17:53:02.0000] the link is by id not by a transition between actual references [17:53:19.0000] no, not functions, that tasks remember at creation time? [17:53:31.0000] shu: not a real linked list, but an ordering of events that allows you to create one [17:53:51.0000] shu: well the tasks when they go through various lifecycles keep the ids around [17:54:13.0000] each task gets an id and via tracking init/before/after events of each task you can create a graph [17:54:30.0000] i see [17:54:39.0000] are these ids tracked by node unconditionally? [17:54:49.0000] no, it is somewhat expensive [17:55:21.0000] so when an AsyncContext.start or whatever is called, it tells node to start tracking task ids through tasks' lifetime state transitions [17:55:39.0000] yeah, and then it stores the relationships in a map somewhere [17:55:45.0000] gotcha [17:55:49.0000] okay, that helps a lot, thank you! [17:55:54.0000] this was not at all clear from the explainer [17:57:23.0000] šŸ‘šŸ» [18:01:09.0000] shu: https://gist.github.com/devsnek/07a61aec7d9f40d1495048790dd30a8f [18:02:41.0000] what does that module do? [18:02:50.0000] it does the map linked list stuff [18:02:55.0000] it might actually be missing some edge cases [18:03:02.0000] but it should give a bit of a picture [18:05:09.0000] oh, it implements the async context [18:05:22.0000] cool, thanks [20:52:27.0000] devsnek: did you want to update https://github.com/tc39/ecma262/pull/1781 ? Otherwise I'll force-push up some commits myself [23:53:33.0000] ljharb: re: https://github.com/tc39/Reflector/issues/282#issuecomment-635795520, the pdf link points to the older candidate too [23:53:43.0000] whoops [23:53:44.0000] fixing [23:53:52.0000] clipboard fun [23:54:04.0000] yayyyyyyyy thanks for the fix [23:54:14.0000] thanks, should be fixed [23:54:20.0000] np, ty for catching it so fast [23:54:59.0000] i'm going to blame it on adobe acrobat stealing all my cpu :-p [00:10:16.0000] that is one packed agenda [00:19:04.0000] devsnek looks like you found the bug, but yes, we are implementing it now which is why we want to sort out the spec side of things [06:05:27.0000] what is Michael Ficarra's nickname on here? [06:09:01.0000] bterlson: could you please add Marja HƶlttƤ (marjakh) as a delegate so she can access the Reflector? (she works on V8) [06:26:26.0000] mathiasbynens: you can open an issue here and we will onboard her: https://github.com/tc39/Admin-and-Business/issues [06:27:13.0000] ystartsev: thanks, will do. fyi https://github.com/tc39/Reflector#readme still says to ping bterlson [06:28:54.0000] ooo thanks for the heads up [06:28:55.0000] will udpate [07:06:22.0000] ystartsev: cheers! [07:06:44.0000] ystartsev: btw, good luck with the stream later! i can't wait [07:20:14.0000] _internal screaming_ [07:20:16.0000] see you there! [07:20:17.0000] or [07:20:19.0000] rather [07:20:22.0000] you know what i mean [08:59:41.0000] ystartsev: michael ficarra is not on IRC except during meetings, alas [09:00:11.0000] he's probably reachable by email though [09:05:06.0000] ystartsev: is there a schedule somewhere for your future streams and tc39 q/a and whatnot [10:02:58.0000] devsnek: there should be a schedule here :https://www.twitch.tv/codehag/schedule [10:02:59.0000] and [10:03:25.0000] here: https://developer.mozilla.com/events/compiler-compiler-yulia-startsev/ [10:03:56.0000] that twitch link just shows me your last broadcast [10:04:48.0000] but the second link works, thx [10:49:07.0000] ystartsev: iterator slides are private [10:53:55.0000] devsnek: fixed [10:54:06.0000] thanks! [11:04:38.0000] ftr (unless the chairs want the notifications) yall don't need to make PRs to the agenda to add slides for anything that's not a stage advancement, or for schedule constraints, you can just commit directly to master [11:35:38.0000] ljharb: _i have done horrible things when pushing to master_ [11:35:59.0000] thats why i make prs :P [11:37:09.0000] haha fair enough [11:44:14.0000] Why does Set use `set` to add things and Map use `add`... ugh [11:44:26.0000] šŸ˜­ [11:45:08.0000] keith_miller to support subclassing [11:45:09.0000] Can we add a Map.prototype.set and a Set.prototype.add that are just aliases of the other? [11:45:18.0000] Bakkot: ? [11:45:19.0000] oh, wait, the different names [11:45:20.0000] keith_miller: they take diff arg signatures [11:45:20.0000] sorry [11:45:35.0000] keith_miller: also Map uses set and Set uses add, i think? [11:45:36.0000] I thought you were asking about why the constructors invoke the methods [11:45:37.0000] ljharb: No I mean Map.prototype.set == Map.prototype.add [11:45:49.0000] keith_miller: you set things in a map, you add things to a set [11:45:51.0000] Bakkot: Ah, on [11:46:03.0000] ljharb: You have it backwards :P [11:46:12.0000] you set things in a set and add things to a map [11:46:13.0000] lol [11:46:16.0000] `Set.prototype.add` is the method that exists right now [11:46:25.0000] lol i do not agree with your intuition [11:46:26.0000] oh nvo [11:46:30.0000] oh nvm [11:46:36.0000] I just want to have the same name [11:46:42.0000] a set is a list, you add things to it [11:46:43.0000] it is aggravating to have different names [11:46:47.0000] right but they're different methods [11:46:59.0000] you add one thing at a time to a set; you set a key in a map to have a value [11:47:00.0000] You can add things to a map? [11:47:04.0000] I also have to look this up almost every time [11:47:07.0000] ^ +! [11:47:11.0000] I'm adding a new key to my map [11:47:14.0000] yeah [11:47:22.0000] that doesn't make any sense to me [11:47:29.0000] without a value you're not mapping to anything [11:47:32.0000] I'd be cool with an add that returns a boolean if it's a new key or something [11:47:51.0000] you don't add properties to an object either, you set them to a value [11:47:52.0000] the functions can have different signatures, but it'd be nice to have a `Map.prototype.add` [11:48:07.0000] Oh, I'm not saying it has the same signature as Set.prototype.add [11:48:15.0000] i would argue that that's semantics, not necessarily how developers think [11:48:17.0000] if it has a different signature then it should have a different name imo [11:48:22.0000] drousso: i would argue those two should overlap [11:48:41.0000] I find it more confusing that I have to figure out which name is which lol [11:48:46.0000] fair [11:48:47.0000] 100% of the time [11:49:05.0000] i don't think this is as universal as "putting the usb plug in the wrong way" tho [11:49:05.0000] ^ ditto [11:49:11.0000] I think Map.prototype.add wouldn't be that confusing [11:49:18.0000] especially if it returns a bool [11:49:28.0000] i wish it returned a bool šŸ˜­ [11:49:33.0000] then it wouldn't be chainable [11:49:40.0000] I'm ok with that [11:49:48.0000] i've never once wanted to chain [11:49:57.0000] If you want the chaining you can use set! [11:50:01.0000] whereas i often want to know "did this exist before" in a single step [11:50:20.0000] heck that could be the difference between `Map.prototype.set` and `Map.prototype.add` [11:50:28.0000] err, `Set.prototype [11:50:32.0000] although the lack of chaining may be confusing between Set and Map [11:50:37.0000] the new method seems fine, but conflicting names isn't something i'd be ok with [11:50:47.0000] also, there's already some weirdness with `String.prototype.indexOf` and `Array.prototype.indexOf` [11:51:11.0000] Maybe we should add like item or something since that's what all the DOM containers have anyway? [11:51:18.0000] although item is an awful name [11:51:23.0000] drousso: wait, what weirdness? [11:51:36.0000] they share the same name, and yet they don't do the same thing [11:52:00.0000] drousso: in what way do they differ? [11:52:01.0000] drousso: Yeah, we should have Map.prototype.indexOf :P [11:52:12.0000] drousso: boy do i have bad news for you about natural languages [11:52:42.0000] keith_miller: i am proposing to add item did you see [11:52:44.0000] ljharb `Array.prototype.indexOf` finds an item in the array whereas `String.prototype.indexOf` finds a substring not an item [11:52:46.0000] well, tab is, i'm championing [11:52:52.0000] shu: !!!! [11:52:59.0000] shu i saw that and loved it [11:52:59.0000] keith_miller: relative indexing [11:53:00.0000] Wait, for array? [11:53:05.0000] drousso: ah, sure, that's fair [11:53:07.0000] keith_miller: all number indexables [11:53:09.0000] are we adding item to set and map? [11:53:12.0000] nah [11:53:14.0000] oh :( [11:53:16.0000] ah well [11:53:17.0000] drousso: but we're not trying to add a new thing named indexOf now :-p [11:53:26.0000] oh yes true [11:53:31.0000] shu: wait, strings too? [11:53:32.0000] shu: I wouldn't be opposed to adding an item to Map and Set [11:53:36.0000] for consistency [11:53:41.0000] ljharb that was more an example of "things with the same name doing different things" [11:53:45.0000] keith_miller: that... take integers? or just do something different? [11:53:50.0000] ljharb: strings, arrays, typedarrays [11:53:56.0000] strings are weird for .item because they have two notions of "the nth thing" [11:54:01.0000] I mean the array one presumably takes non-integers right? [11:54:04.0000] Or does it error? [11:54:13.0000] I would assume it toNumbers them [11:54:19.0000] keith_miller: yeah, it ToIntegers [11:54:19.0000] i like the proposal's semantics but am very questionable on the name "item" [11:54:36.0000] shu love the negative value semantics especially [11:54:44.0000] but also yeah, weird on strings wrt code units/points [11:54:55.0000] shu: So Map and Set presumably wouldn't do that... [11:54:56.0000] name has to be item for reasons [11:55:00.0000] but otherwise would be the same? [11:55:00.0000] see proposal [11:55:08.0000] e.g. it's get [11:55:11.0000] keith_miller: i'm open to that? i just haven't thought about it [11:55:14.0000] i saw, but i don't like those reasons [11:55:24.0000] ljharb: i'm gonna need a better reason than "i don't like it" [11:56:26.0000] shu: i haven't fully formed an opinion yet, but in general i don't like naming/semantics choices being made for us, especially when it's presented as "we accept this coercion, or the proposal is withdrawn" [11:56:33.0000] shu: But yeah, I support item. Even if I didn't the powers on high have told me to support it :P [11:56:50.0000] ljharb: that seems like one of those things you will should learn to live with [11:56:56.0000] the name choice _has_ been made for us [11:56:59.0000] it does already exist [11:57:01.0000] you can't unmake it [11:57:09.0000] not on arrays etc [11:57:15.0000] yeah, i think this is the reality of working on the JS platform, which includes the web platform [11:57:27.0000] at times it is, yes. [11:57:32.0000] I think the consequences of not having it on array is worse [11:57:37.0000] agreed [11:57:37.0000] ^ ditto [11:57:43.0000] i hope to hear about that during the presentation [11:57:44.0000] unfortunately [11:57:48.0000] ^ ditto [11:58:10.0000] I think item name was a poor choice fwiw but that ship has sailed for W3C [11:58:25.0000] ljharb: i don't get the sense you can be receptive to it if your starting point is "web platform is only part of the js ecosystem part of the time" [11:58:45.0000] i'm receptive to places where the spec needs to change to match web reality [11:59:09.0000] i won't be making any new arguments than what's already in tab's explainer [11:59:14.0000] i don't think that's the same scenario as being forced (in the general case) to broadly support design choices, good or bad, just because the web made them elsewhere [11:59:33.0000] like i said, i haven't fully formed an opinion, and def need to give the explainer a reread [12:01:11.0000] ljharb: also the presentation isn't "accept this name or proposal is withdrawn" [12:02:04.0000] ljharb: it's "there're actually some compat risk with naming it item, but everything would be better for the ecosystem if it _could_ be named item, so barring incompat data, strongly prefer 'item'" [12:02:04.0000] shu: The upside of something like `item` over `at` is that it "nicely" extends to other container classes that have a single key [12:02:36.0000] keith_miller: ah i didn't think about that [12:02:41.0000] since `at` strongly implies index whereas I don't see item in the same way [12:02:54.0000] i mean item is such a terrible java-ism name [12:03:06.0000] it is *java*script! [12:03:09.0000] but it is generic like that [12:03:32.0000] one time at jsconf eu some german dude saw a bunch of us coming out of the event venue and asked us what it was about [12:03:34.0000] shu: the explainer says the name is a requirement; i'm sure i saw the wording i used somewhere but def not in the explainer, so ĀÆ\_(惄)_/ĀÆ [12:03:45.0000] someone said javascript [12:03:55.0000] and the german dude was like "yahweh script? is it religious?" [12:06:12.0000] shu: I mean based on the strength of some peoples opinions on JS it's comparable to a religion! :P [12:11:58.0000] prettier's official policy is to add styling options only if means avoiding taking sides in a holy war [12:12:02.0000] so: tabs vs spaces, semicolons [12:13:15.0000] šŸ¤£šŸ¤£šŸ¤£šŸ¤£šŸ¤£ [12:13:21.0000] that is my new favorite thing ever [12:27:49.0000] the problem here is that the proper name for both maps and sets is insert [12:48:10.0000] personally, i would've been fine with that since they both had the same name [12:52:25.0000] oof I'm honestly more bugged by the keys/values/entries situation in Set [12:52:46.0000] orly? [12:52:47.0000] what about? [12:53:09.0000] keys is values and thus entries is just intentionally duplicated [12:53:38.0000] oh [12:53:46.0000] ĀÆ\_(惄)_/ĀÆ [12:54:15.0000] personally i'm ok with that cause it means there's consistency with `Map` [12:54:48.0000] that is the stated motivation but I really wonder whether it's useful [12:56:03.0000] the thing is that `get` is the thing you do with a populated Map but there is no `get`-like operation for a Set, so that implies that Map will have a `set` but says nothing of Set [12:57:20.0000] get on a Set would be `s.has(k) ? k : undefined`, i suppose [12:57:34.0000] yeah [12:57:48.0000] yeah I mean tbf that could exist, it just doesn't [12:58:22.0000] and I could see people disliking `new Set().set`, so it doesn't surprise me that a different word was chosen [13:00:23.0000] hmm I guess Rust and C++ alike use `insert` as devsnek said [13:00:37.0000] for both Map and Set [13:01:32.0000] i think some languages also use "put" [13:07:22.0000] to me "put" weakly implies creation tho [13:12:55.0000] wait what we're doin' Teams this time? [13:12:58.0000] akirose: wait, we're using teams for this plenary? [13:13:06.0000] why? zoom works great [13:13:15.0000] yay not zoom [13:13:28.0000] teams' UX on ios is painful :-/ [13:13:33.0000] like, getting into the call, i mean [13:14:17.0000] ? have you tried lately? bc i just hopped onto a call from my personal computer and it was fill in name, click join [13:14:37.0000] Zoom "works great" but a whole lotta people won't touch it with a 10-foot pole [13:14:45.0000] because they are a garbage company [13:15:04.0000] and their product has both privacy and security issues [13:15:06.0000] i tried to get on a Teams call with daniel a month or two ago [13:15:47.0000] so far all the issues i'm aware of that are unique to zoom can be bypassed by using the web, or the ios app, instead of the native desktop app [13:16:00.0000] ĀÆ\_(惄)_/ĀÆ feel free to hop on to the tech check [13:16:41.0000] seems like a pretty big last minute change :-/ [13:24:22.0000] I for one am excited to add a new entry to my menagerie of video chat clients [13:25:47.0000] how long until we do plenary over discord [13:28:57.0000] does discord have video yet? [13:29:27.0000] eesh, nvm, i'll stop complaining about teams [13:30:18.0000] akirose: it's had video for a while :P [13:30:27.0000] (in my experience the highest quality video too) [13:30:37.0000] lollll look i only use it for union organizing [13:30:41.0000] uhh. [13:30:42.0000] i mean. [13:30:44.0000] NOTHING. [13:31:10.0000] haha [13:31:18.0000] devsnek: in that case idk i wouldn't rule anything out completely. i don't see it happening any time soon but never say never. [13:31:31.0000] yeah i was mostly joking but its always good to have options [13:31:45.0000] each channel can be its own video session which makes breakouts super duper easy [14:06:59.0000] yeah what clients do i have now... webex, zoom (which had to be uninstalled per corp policy), now teams, i guess not too many [14:09:29.0000] fwiw rkirsling just joined from the web client and it seemed to work perfectly fine. he didn't test presenting from the web client though. [14:09:42.0000] :nod: [14:10:29.0000] linux version is a bit odd but it seems to work [14:11:55.0000] one gotcha with the linux client: not 100% sure but it seems like there's no "share window" option, only "share entire desktop" [14:12:17.0000] i think that depends on your window system [14:12:33.0000] i can double check [14:14:02.0000] yeah i'm only getting desktop option weird [15:09:27.0000] mathiasbynens shu: do you know any historical bug for V8 setting extra own properties (non configurable) to function objects? Basically "arguments" and "caller" [15:11:06.0000] ljharb just pointed me to https://tc39.es/ecma262/#sec-addrestrictedfunctionproperties [15:11:23.0000] I don't get where this abstraction happens. I need to go deeper there [15:11:41.0000] looks like there's nothing that makes them be own properties, only prototype throwers [15:12:54.0000] IIRC this is something that happens historically on v8 and jsc, as we can observe still happens today [15:13:30.0000] I'd like to find a specific bug to point it out [15:13:49.0000] let's see what a google search gives me (not easy with these keywords) [15:15:48.0000] got it! the search on v8's bug tracker is great, one would wonder why. [15:15:49.0000] https://bugs.chromium.org/p/v8/issues/detail?id=5047&q=caller%20arguments%20own%20properties&can=2 [15:15:58.0000] also https://bugs.chromium.org/p/v8/issues/detail?id=6049 [15:17:41.0000] and we do have tests: https://github.com/tc39/test262/commit/a266cfa8cb8c17f5724298f2205c03c26c7c83e0 [15:19:47.0000] rkirsling anything related to this in jsc? [15:20:24.0000] https://test262.report/browse/built-ins/Object/internals/DefineOwnProperty/consistent-value-function-arguments.js [15:22:54.0000] I mean I have no background on this but searching found https://bugs.webkit.org/show_bug.cgi?id=158116 [15:39:38.0000] there is more background in https://github.com/tc39/ecma262/issues/562 [15:39:40.0000] and https://github.com/tc39/ecma262/issues/877 [15:39:48.0000] and https://github.com/claudepache/es-legacy-function-reflection/ [15:40:00.0000] specifically https://github.com/claudepache/es-legacy-function-reflection/blob/master/analysis.md [16:14:26.0000] thanks for the links, Bakkot [16:14:58.0000] I'm afraid they focus more in arguments and caller inside the function rather than as properties of the function object [16:15:38.0000] but it's a very weird behavior that makes some mess in a quick switch from strict to sloppy mode [16:18:53.0000] Here is an example where this problem subtly affects other operations: https://gist.github.com/leobalter/0d67d314b66b14d34668d2d8308b9a6c [16:39:51.0000] what is the ask here? 2020-05-30 [18:40:33.0000] shu, I was trying to find the tracked bugs for this issue [18:41:02.0000] I believe already have what I needed, thanks! [18:41:39.0000] I also believe I've heard from someone at V8 something about this won't be fixed soon for a reason I can't remember [14:17:43.0000] devsnek: did you want to update https://github.com/tc39/ecma262/pull/1781? otherwise editors will take care of it [14:19:08.0000] Bakkot: i'm ok with the editors handling it, it is very low on my todo list [14:20:01.0000] āˆš [16:32:52.0000] oh god I didn't realize (/ forgot) the schedule was changing this time [16:33:40.0000] this is going to be a very sleepy week [16:34:53.0000] yeah it's rough [16:36:01.0000] I was preparing myself for three early days but four days of *only* mornings is going to suck a lot 2020-05-31 [18:09:30.0000] How do I get autogenerated files named something other than "index.html" to show up on tc39.es when I push my repo? [18:10:23.0000] I configured the "build" task in package.json to output my spec text to a file named "numberformat_diff.html", but when I push, I don't see that file on tc39.es: https://tc39.es/proposal-intl-numberformat-v3/numberformat_diff.html [18:33:46.0000] sffc: there's no gh-pages branch or anything [18:34:12.0000] did you set up travis or gh actions or something [19:36:01.0000] sffc: your repo needs to be set up for gh-pages. either to publish from the master branch or from the gh-pages branch [19:36:15.0000] sffc: the proposal template instructions suggest using master [21:54:17.0000] I never set anything up but the repo already pushes index.html because when I change it and push to master, it updates a few minutes later on tc39.es. I don't know where the config exists; I assume it's some global setting in the org, because there's nothing in the repo about gh pages [21:57:45.0000] sffc: about 75% of the way down the main Options settings page? [22:21:03.0000] rkirsling: months of 7am meetings with munich has prepared me for next week! [22:21:43.0000] oof [22:23:08.0000] late-night meetings would be sweet [23:03:43.0000] september's in tokyo time, that'll be 6pm - 11pm, Sunday through Wednesday nights [23:07:25.0000] I am a little bit hopeful that travel will be reasonable by then, but not very hopeful [23:07:28.0000] was looking forward to tokyo [23:09:05.0000] yeah hard same, but either way they already announced that 2020 would be all remote no matter what [23:09:16.0000] oh, yeah [23:09:17.0000] bloomberg isn't planning to host anyone physically [23:09:27.0000] maybe I can go to tokyo anyway [23:10:25.0000] i'm told september is likely to be fall-flu-resurgence time, which might make it a poor time to travel :-/ [23:17:34.0000] was supposed to be in the middle of a six-month stint in Tokyo right now :( [23:17:42.0000] but yeah, 6-11 pm is choice [23:18:54.0000] it's generally easy having meetings with our Tokyo HQ but then it's interesting because everything's across the other ocean for TC39 :p [14:36:51.0000] shu: your slide for Type IV is still a type error: https://docs.google.com/presentation/d/1vJeJFueDwrj8ebXFdGsEO1J_Q-DzfU01dLEGVd26A9o/edit#slide=id.g85a8e1c232_0_288 [14:36:56.0000] also ystartsev ^ [16:12:59.0000] i have to get up three hours before tc39 even starts for job onboarding :'( [16:20:03.0000] devsnek: what's the job? [16:20:24.0000] internship at datadog [16:22:58.0000] congrats [16:23:24.0000] that would be quite early though, depending on timezone... [16:24:19.0000] 8:30 ny time [16:27:45.0000] ouch. that is not what I call working hours.