In-person attendees:
Name | Abbreviation | Organization |
---|---|---|
Bradford C. Smith | BSH | |
Robin Ricard | RRD | Bloomberg |
Ashley Claymore | ACE | Bloomberg |
Hemanth HM | HHM | PayPal |
Ross Kirsling | RKG | Sony |
Jason Williams | JWS | Bloomberg |
Jordan Harband | JHD | Invited Expert |
Dan Minor | DLM | Mozilla |
Kris Kowal | KKL | Agoric |
Rob Palmer | RPR | Bloomberg |
Robert Pamely | RPY | Bloomberg |
Andrew Paprocki | API | Bloomberg |
Shane Carr | SFC | |
Shu-yu Guo | SYG | |
Gus Caplan | GCL | OpenJS |
Kevin Gibbons | KG | F5 |
Daniel Ehrenberg | DE | Bloomberg |
Willian Martins | WMS | Netflix |
Peter Hoddie | PHE | Moddable |
Quinn Okabayashi |
Remote attendees:
Name | Abbreviation | Organization |
---|---|---|
Michael Saboff | MLS | Apple |
Chris de Almeida | CDA | IBM |
Waldemar Horwat | WH | |
Frank Yung-Fong Tang | FYT | |
Jack Works | JWK | Sujitech |
Devin Rousso | DRO | Apple |
Sergey Rubanov | SRV | Invited Expert |
Caridy Patiño | CP | Salesforce |
Nicolò Ribaudo | NRO | Igalia |
Yulia Startsev | YSV | Mozilla |
Rick Waldron | RW | Salesforce |
Istvan Sebestyen | IS | Ecma International |
Philip Chimento | PFC | Igalia S.L. |
- Notes from the last meeting approved
- No agenda objections
Presenter: Istvan Sebestyen (IS)
IS: So, this is the usual structure that I give and actually, since the last meeting, not so many things have happened. Many of the points of the presentation are just for reading and so I will go through very, very quickly. So here again, the list of the relevant pieces of tc39 documents. I will just show the slides and that's all. And then we have new members to introduce and welcome to TC 39 and then one slide about the status of the meeting participation, and only the entry to the last meeting which is interesting here. And then again, you see certain standards download and access statistics, very, very quickly, not much happening. And then, which is important, what is the status of the ES2022 approval, and the status of publication. And then finally, which is good news in my opinion, that finally we have also published a nice and good pdf version of the ES2022 standard so that's in my eyes this is a great achievement and I'm very happy about it.
IS: Then I looked at the Ecma General Assembly minutes and then I picked up a couple of things where we have to react, or they are some interesting new things we have to know and last but not least, when are the next TC39 and GA meetings. So these are briefly the main points.
IS: Okay, so here I just show you that we have two types of list: the latest TC39 and the latest GA documents. Just for those who don't know, we have a double filing mode, one for TC39 via GitHub and the other via the Ecma File Server - which is for Ecma the traditional one that all Ecma members know and also for the long-term archiving (which is a typical SDO requirement). And then these are the lists. Only the new documents, since the June meeting are shown.
IS: This is the second part of the GA list and from here, you can see the announcement of the new TC39 members, then you can see they have done their Ecma applications. And actually also signed the TC39 royalty-free TG form. This is because we are a technical committee and additional administration is needed for Ecma as a whole. So, this is the end of the two lists that are usually presented.
IS: The next slide is just a repetition of a slide that I always give you know why we are doing this. And this is just for reading. So I would say nothing new.
IS: Okay, now I would like to welcome the two new TC39 members. I don't think that they are participating in this meeting. But anyway, from the administrative point of view they are entitled to work with us. So there are two US companies. So one company is ServiceNow applied and approved for ECMA associate membership and the other one Shopify is also a new associate member of ECMA. Both companies are very active on the web.
IS: So please go to the next slide. Okay, so this is the usual meeting participation table. Go immediately to the next slide because I am only showing the last entry from the last meeting.
IS: You will see that we had 59 remote participants representing 23 companies. Three invited experts. And you can see that the dropping of the participants is not unusual in a June TC39 meeting because basically ES2022 has been completed from the TC39 point of view. And then we will again see a bump going up after the summer meetings. So, that's the reason why we have had relatively low participation. But still 59 is a very big participation number for an Ecma technical committee.
IS: So this is the list of Ecma TC39 standards download statistics. I will be very, very quick on that because the trend I'm showing to you is still the same as what we had. There were close to 60000 downloaded Ecma standards and half of them or more than half of them were TC39 standards.
IS: Okay, So these are for ECMA-262. So for the main language standards and for the different editions on the left hand side, it is the html-access part, right hand side, it is the download. What we have seen in past meetings is that the first edition-numbers of download are not correct, that's the reason why we have “?” marks there. I can only say with confidence, the latest editions of ECMA-262 are ok for the html-access figures. For the download version we don't have the problem of the numbers of the first editions. So, that's correct.
IS: Well, this is the same for ECMA-402. Obviously the numbers are much lower. Again, the access numbers for the first editions are really questionable. They are not true, but this is what we are getting from Google Analytics. But the download numbers are correct.
IS: Okay, this is an important slide where we are now. So first all, the GA approved ECMA-262 2022, congratulations to the group! And it has also been approved with the new alternative text copyright license (which is a more permissive text copyright license). Immediately after the approval as usual, Patrick - from the Ecma Secretariat - has immediately published both the HTML versions, which, as you know, this is the “master version” and takes preference over the PDF version. It is perfect and we are still using that. Then we have published a very “rough PDF” version, because that was available at the time of the General Assembly. The good news is that since then we have completed the project. AWB did this. So we have now a nice PDF version for both of the standards, 262 and 402. And AWB did an absolutely great job and I am very thankful to him. They are already published. Actually they were published before last weekend. And so, if you go and if you download the latest PDF versions now they are already those “nice PDF” versions.
IS: We have a separate presentation from AWB longer than this presentation. For ES2023 project we need to solve the “nice PDF” publication problem in a more long-term way. We need a much more stable solution for that - built in into some kind of Ecma TC39 tool. But this will be a project for next year and so on, but AWB will be talking about it in much greater detail.
IS: Okay, so this is the table for future TC39 meetings. We know that the Tokyo meeting is going to be remote. There is a question mark for the November meeting, is it in Europe, whether it will be in Norway, Etc, Etc, we have already on GitHub sort of dialogue on it. For the meetings for the next year I don't have a schedule on table yet.
IS: Okay, so I’ve picked up a couple of results from a 2022 June GA meeting where - as TC39 - we have to act here. The GA requested for the “nonviolent communication training” of TC39 some further information. Basically, it conditionally approved 10,000 Swiss francs for such a request, but had three specific questions. And the answers have to be provided to the ExeCom.
IS: Okay, so this is exactly the copy that I have cut out from the GA minutes. So what I‘ve read and a little bit surprised me was the first one. It says: “discussion among all members of tc39”, so we have to discuss “the incidents occurred” and the “implication to reach consensus on a solution”. I have not the slightest idea what the incidents are. and also obviously about the implication and I don't know, you know what kind of communication went back and forth between those who were present at the meeting and the general assembly so somebody who was at the meeting can maybe give us a little more insight about this.
IS : And then the second point, I was also rather surprised to see that was written in the second question about the TC39 Code of Conduct Committee. So far, you know, each time we had the report about the work of the Code of Conduct Committee, when it came to the pointin TC39 meetings we have not learned about “incidents in TC39”.
IS: Okay, the third question is a request for a high level description of the details of the proposed training. I think this is really very important. So this is the task that we have to pick up and have to do, I don't know how we are going to do it and here I am asking here, the TC39 management to react to it at any point in time. I'm just reporting you from the GA meeting.
IS: This slides are very, very short ones. As I said at the last meeting, the Ecma Bylaws and the Rules were going to be changed by the June 22 GA meeting very, very slightly, but very logically. So here, the first message is that it was approved by the GA both on the Bylaws and also on the Rules. So it is done.
IS: I picked up some interesting news. So there was a vacant position of the Ecma Vice President, Actually we had one candidate. It was Dan Ehrenberg. Then he was unanimously approved. Congratulations Daniel to your election as Ecma Vice President.
[applause]
So this was the first point that I picked up, which was Interesting to to mention to TC39. And then the other one that also an Ecma Recognition Award was given to two candidates. As I mentioned the last time they were given to candidates outside of TC39..
IS: Okay, this is a GA venue and date are unchanged from the last time so you can go immediately to the next slide. The meeting dates of the ExeCom were also unchanged.
IS: This is the end of the presentation and if they are no question that I have finished, thank you very much.
DE: Thank On the NBC funding, which is that the inclusion for your plants? bring that as, as it points out that back to committee later on, okay, so the next topic is the ECMA-262 status updates by Kevin giving Gibbons.
Presenter: Kevin Gibbons (KG)
KG: Okay, this will be a very brief update. So the only significant editorial change is a minor refactoring to the regEx logic so that they are now threading through all the state that they need when executing a regEx instead of it just being ambiently available because that tends to be confusing. Normative change that we have made is landing the stage 4 proposal for array findLast and findLastIndex, which we did last week.
KG: And then a meta-change which is mostly relevant if you are maintaining a proposal: the latest version of ecmarkup is now somewhat more aggressive about checking for typos like unbalanced parentheses or referring to abstract operations which don't actually exist. You will need a recent version of ecmarkup and also a recent version of the biblio that is published as ecma262-biblio on npm. If you don't know what I'm talking about and you want to start doing this, please feel free to message me on Matrix.
KG: And this is a reminder from JHD that the IPR form is necessary for anyone submitting pull requests. This is automatically or will soon be automatically enforced by GitHub actions. It wasn't for a little while, but I believe Jordan went through and got in touch with everyone who hadn't. We're all good there. But if you want to make contributions please sign the IPR form if you are not a delegate.
KG: Lastly, pretty much the same list of upcoming work as usual. We’re making progress on making regexes more consistent. Some of the rest of the stuff will land Soon. MF is planning on talking to the researchers from KAIST who presented a while ago about integrating the esmeta type checker so that the spec will be automatically checked for consistency and correctness and internal coherence.
KG: And that's it.
Presenter: Jordan Harband (JHD)
JHD: So I've completed the audit of our GitHub TC39, org, so, theoretically everybody who is a delegate in particular is a team just for their organization. And then that is a child team of a hierarchical structure. So either, please encourage your or whoever is the person at your company that handles this sort of thing to review that list and make sure that all those people still work for you. Just, if you find that someone does not, there is an off-boarding template that you can file on the admin and business repo or you can even just go the lazy route and message me on Matrix and I will be happy to file that for you. That way we can keep these up to date and prevent future maintenance issues. Thank you.
DE: Thank you so much for Excellent work. From an IPR perspective. It is vital that we keep these lists up to date. If you are representative of one of these organizations, you're representing to ECMA that you have a license to the eye. That's being contributed from these people to Ecma. So if, if someone leaves a company, there's no kind of automatic way, that continues so they would need to sign the invited expert form. And so, it's really important that we keep these up to date.
KKL: Where do We find the list?
JHD: I will paste the link in Matrix and yeah, you can look through there. Thank you.
RPR: Yeah, and I'll second what DE just said, which is that this is awesome work. It's a really good use of GitHub and I think this is an example of JHD doing a really good job in his role as administrator.
Presenter: Shane F. Carr (SFC)
SFC: Ok. So hello everyone. My name is Shane. I'm the convener of the ECMA-402, TC39 task group. So, what is ECMA-402? For those who don't know, it's JavaScript's built-in, internationalisation Library. The slide shows some things that you can do with it. and sold out date-time format. Formatting dates in localized forms and localized waste.
SFC: how is it developed? We're developed a separate specification from ECMA-262 to divide. The TC39 task group 2, there are now three task groups. There's task group one, which is the one that we're in right now, task group 2, there is also task group three which is the relatively new security task group. However, all our proposals move through the standard TC39 stage process, we have monthly 2 hour phone calls to discuss the details. There are some links, which I'll show again later in the presentation for how to join and how to get information. These are some of the Personnel, the editors are USA and RGN, we've also continued to get advice from Leo. So thank you for your continued input there. Especially when we're trying to get the ES2022 together. I'm the convener and on this screen shows some of the delegates who have come to recent meetings. So thank you again for all of your contributions.
IS: And thanks to Google for sponsoring Igalia to continue to develop Intl this year. This is a continuation of that contract. I thank you Igalia for your work on doing things like Test262, two and Deanna. Many other things,
SFC: So ES 2022. This is the pdf version of the specification. I can go open the link. Anyway, if people want to go and preview, does any of the editors have any comments or questions that you'd like to ask the delegates about this, the, the version of the 402 standard? And that it's available here. I believe it should be put, I believe it should be posted to the Ecma website soon. So the PDF version every year goes as sometimes it gets generated in different ways and we're quite happy, I believe, with the way the pdf version turned out this year. So thanks to the editors. And to Ecma for helping us, get that together. There's also some pull requests to go through the first pull request is a normative full request that Frank will be giving a presentation on tomorrow, so I'm not going to open up today, but if you want to preview it, it's #701. There's also this meta pull request, which I'll go ahead and open. RGN, if you're on the call, do you want to discuss or just quickly Introduce this pull request? And since it's a meta pull request, I don't know if it needs consensus from this group.
RGN: Yeah I think it would be worth discussing. Is there an agenda item later or is this the opportunity?
SFC: I don't believe there's an agenda item later unless you have one, but this would be the opportunity to introduce this to the group,
RGN: So passing on a longer discussion and just introducing it now: the idea is basically to clarify how ECMA-402 and ECMA-262 relate to each other, with the intent specifically of having ECMA-402 only constrain behavior that is valid for 262 implementations and only in particular ways. So we want to say that of all the possibilities that are left open in 262, every 402 implementation must behave in this narrower way and stay in these tighter lanes.
SFC: Okay, so procedurally is this, I know that JHD has previously reviewed this pull request? Should we seek consensus on like TG1 approval on this pull request now or is this something that we feel that it would be better to discuss that more length later in the agenda
RGN: later is probably better, unless unless we have support already
SFC: JHD since you did review this, do you have any initial thoughts on this? Does this General Direction look good to you?
SFC: while JHD is looking that up I'm going to go back to the slides and depending on how much time we have in our time box here we might be able to get a little further discussion on 690. I want to go back to the slides and just look at the proposal status. so we have this beautiful little wiki page that RCA keeps updated with all the updates on all of our proposals, old ones and new ones together. There are three proposals that are shipping in the 2022 edition and attract, you know, the documentation and all the implementations of those. I would note that our polyfill Champion recently left the company that they were working at. So we don't currently have a polyfill champion. This is an opportunity for you to contribute to ECMA-402. If you're interested in getting involved, write more polyfills for it. We also have these stage three proposals, which you've all seen presentations on. I'll be giving an update on intl number format tomorrow and you can see the status of all the implementations here and all the different browsers it. browsers also in this Wiki page also shows the version of the browser that first ships to the feature, which is good for you to sort of track. When these features are going to available to use these buttons are also, clickable you can click any of these buttons and it brings you usually to the issue on that respective browser to see the status. So that's the status of all of our stage 4 and stage 2 proposals. We don't have any currently staged two proposals. We do have a number of stage one proposals, If you're interested in helping, any more of the stage one proposals are getting more updates. Again, you can join our monthly meetings.
SFC: and yeah, so you get involved here is the links that I showing earlier. so, the way to get involved, you can write documentation, you can do polyfills., test262 tests and again, if you're interested in joining our monthly call, you can click the link to this e-mail.
SFC: And that is the presentation that I have. I saw some I saw a chat message coming but I didn't wasn't able to really read it if the person it could add themselves to the queue, we can then discuss it from there.
SFC: If we can talk a little bit about pull request 690 and also monitoring the queue&A.
JHD: I definitely like the direction. I think that the by virtue of being a separate spec 402, like without these types of kind of tightened specifications, specifications, it could it find accidentally in a place where it, since in practice almost every implementation implements part or all of 402it would be easy to accidentally create specification where code, wouldn't be able to be written universally for a non 402 and a 402 implementation. I think anything in the service of maintaining that ability to write universal code valuable.
SFC:. Thank you. Okay procedurally. I believe what we normally do with these pull requests is just present them during our updates presentation here and then, you know, ask for a consensus. So Jordan, is there anything else as one of the as the main 262 reviewers, or anything else on this? Pull request that you think we should discuss it Fred more length or are we good luck getting like, saying that it Consensus.
JHD: I think it would be wise for more folks to review it, okay, especially a current 262 editor but I would hope… I don’t anticipate controversy, but I don't feel comfortable wire off for everyone else.
SFC: Excellent. So let's go ahead and use that then as a call for people to read this… RGN is requesting more detail. How about if there if there's time on Thursday at the end of the agenda, we could revisit it to check consensus. Or we can ask for consensus at the next meeting. Once people have had time to review this.
DE: Is this only a 402 PR or is there a 262 PR associated.
RGN: It is exclusively 402.
SFC: I'll go ahead and put back up "the how to get involved" slide. We love when people hop on into our monthly calls, and everyone is invited.
Okay, if there is no other comments or questions, I can give back a few minutes by appreciate chamber and thank you.
Presenter: Chip Morningstar (CM)
CM: Ecma 404 remains mercifully unchanged. The keys to standard stability are brevity and obstinance.. We have both.
Presenter: Jordan Harband (JHD)
JHD: There are no updates at the moment. There have been a few heads-ups; we've received that aren't exactly reports but are things that we should pay attention to. But nothing has resulted in a report.
Presenter: Ashley Claymore (ACE)
ACE: I'm a bloomberg delegate, just a small update that I gave a large time box just in case but there's potential for it to grow. So it could be short, could be long. So this is Change-array-by-copy. We got to stage 3. We now have an implementation in JSC, which is in Safari Tech preview and excitingly some of you may or may not have heard there's now a thing called bun. Bun also uses JSC, and it's using a version that has this proposal so that it is actually the first platform to fully ship the proposal. We also have it in spidermonkey behind a compile-time flag and there are two polyfills as well. We have test 262 tests, a PR’s open, So so far stage 3 is going nice and smooth.
ACE: there have been two normative changes, we made recently. They follows the same thing that we recently showed in the last meeting where it's a very small change which you see these two PRs: 89 and 91. We're just hoisting a little bit of work up out of a loop up. Just so that way, there's no re-entrance back into user-land code in the middle of loop. Thanks to SYG for spotting these.
ACE: We also want to get feedback on this issue that was raised. Which was asking whether or not we should remove one of the methods from this proposal, that is TypedArray.prototype.toSpliced. One of the main bits of feedback is TypedArray doesn't have splice so should it have toSpliced? The champions' position on this. is that it should still have toSpliced but SYG has mentioned this and YSV has echoed SYG's sentiments of not being a fan of keeping this. So the Champions group's position is to keep this, but we're happy to kind of consider that if you know people have strong opinions further echoing, SYG and YSV saying about removing it.
ACE: If I just flip over to the slide presented back in stage 2 and one of the things that this proposal we were looking at is given the current state of the world that we had. Where does an immutable interface sit in this? As in, would then be the interface that the Tuple proposal represents up or proposed, proposed, or well, and where does that prototype sit in this Venn diagram and what we're trying to do is carve out space where tuple sits in this so that it will actually sit within this Venn diagram rather than sit like have an extra overlap outside of it.
ACE: So, things like toReverse, and toSorted so that kind of fits quite nicely because they're already here in this middle section here with both array and on TypedArray. Splice is the odd one out here in that it is only on array. So you would right now the proposal you would have typedArray toSpliced but you can't do TA splice, because like this whole – I want to say quadrant but it's a sextant, I think? – these all modify length and you can't modify the length of the typed array. So it kind of if you know the TA is a fixed length, it kind of makes sense that it doesn't have splice and that would also follow that Tuple doesn't have any of these. So I’m curious what opinions people have. One concern we have is if the concern is primarily about something having toSpliced without having splice, that would also be true when we present the record and tuple proposal. So if that's like a more general rule I guess that's more concerning for us because then that makes us go back to the drawing board, a bit with records and tuples. But if it's specifically just about TypedArray, it's kind of less about a larger design space that we're looking at.
JHD: I understand why we can't have splice on typed arrays because it mutates length and we can't mutate the length of a TypedArray. It seems like, there hasn't been a missing Solution on typed arrays around splice or there would have been an attempt to create a function on typed arrays before this that solved it; in other words, whatever toSplice is doing like there hasn't hasn't been clamoring until it before this proposal, I have this use case at camp with typed arrays. It needs something like splice that doesn't mutate to solve it. One person I think has provided a use case but not until this was almost removed from this proposal. so it doesn't seem like we have a compelling problem statement, the toSpliced TypedArray solves. I know what it solves on Tuple because I know what it sells on a raise. And to me tuples in arrays are highly analogous but typed arrays are kind of specialized and also it didn't go through the same design process that most of the rest of the language did. And, you know, I just, I think that it's ok, that they're weird in some ways. So I think that if there's a really compelling reason to have toSpliced on typed arrays, that's we should know before adding it. And I don't see one.
ACE: thanks
SYG: So what initially prompted me to ask the question is that there's two axes of discoverability of these methods here. One is the mutable/immutable pair, and that's what's missing here, and the other is – I guess the other is, is there a set of immutable helpers that we expect of all collections? Maybe that's a goal that seems more that seen sounds more solid footing. But like for that, whether to splice should be included in that said, I think is independent of the debate because… it's weird. I have a pretty weak…. Since this is stage 3, and this is already litigated. This is a very weak request and to kind of reaffirm that this is what we want because it slipped my mind at the time that you didn't have splice on TypedArray. And then I'll close with, I have a pretty weak argument also against complexity for security Yeah, I guess complexity for security because typed arrays are just special anything we add to them. The attack surface because that's like stage one of your chain exploit to get your shellcode into some type the right thing. So, the smaller that surface is for typed arrays, the better and if we don't need to splice, they would be nice to not have it. But that's pretty weak.
ACE: Thank you.
YSV: When we maintain consistency, we are aiding learnability of the language. So I believe in reusing the toothpaste. As you mentioned, reason the to splice naming, in this case, may actually hurt ability for Learners of the language or even Before experience with language to Triple H. What is the relationship between this feature and splice? Additionally, I think splice is a rather confusing word. In isolation is missing. I think that we would in some ways be a benefit and who [audio issues]
YSV: I'll just get to the point. We could implement this separately from change array by copy, and I think there's reason to consider that because it may aid learnability and it may aid as a more coherent [audio cut out]. I think I think you guys get the idea.
DE: We heard we heard a lot of criticism of this but you mentioned that the champions' point of view is that it should be included. Could you repeat that rationale?
ACE: Yeah, so I guess there's a few reasons why I like it. One is kind of counter to SYG's Point while I do see reducing the complexity of TypedArray, that it makes sense from a security point of view is that the fact that this method is a little bit complicated to implement, the spec text is a little bit longer than the other methods to me, I like the fact that it is implemented in the language for me. Splice is one of those operations that when you need it it's a real pain to implement yourself. It's not like some of the other methods where you can quite quickly – like reversing a list you can quite easily write that out yourself. and you're trying to do splice, there's quite a lot of little bits of arithmetic involved in there, so it's quite a to me, it's the kind of like the Swiss army knife of methods, or it's one I really I am pleased it's there for me because I really don't want to write it myself. So there's the utility argument that I guess that's about splicing in general – Having it on typed arrays – I like the fact that, I guess I am more pro keeping typed arrays… While typed arrays are still relatively close to matching the array prototype. You know there's only a few exceptions. It feels correct to me like typed arrays, not having flat, makes complete sense. You can't have a two-dimensional TypedArray. So, I'm more for not sending a like setting a new precedent of not letting typed arrays fall further adrift from array. While this method, I think is still quite in keeping with typed arrays in that. It's from the arguments passed in, you know, immediately up front the size you need to allocate for the actual buffer. This isn't like flatmap, yes, to me flat map doesn't feel very TypedArray because it's very dynamic. You can't just allocate it upfront and populate your TypedArray that you've got to actually kind of do all the work and then transfer that so, it kind of doesn't feel like you're getting much benefit of it being a built-in method. If you don't have toSpliced you can but you did have it on the array, you know, you could transfer do the work on the array and then transfer The Irate back into a TypedArray,
SYG: I said you can just do a .call(). I was corrected and said that the return value is still an array, not a TA. So I need to make a copy.
ACE: I guess some one thing I'm curious about is some of the feedback we've gotten is not specific to TypedArray. It's more general. like this is a controversial name I think I'm never sure when people complain about the word splice. How much of that is just like a meme or how much of that is genuine confusion. Personally, anecdotally I've always been okay With the word, anecdotal stories I used to me, as a film student, I spent years splicing film. So to me the word splice is very natural to get feedback, that is not great, but then that also applies to array.prototype.toSpliced and would apply to Tuple toSpliced. So, if the concern is the naming then it'd be good to know that is more General because then we should kind of look more widely at the proposal wider and then also the records and tuple proposal. I do get it. A more General negative vibe is there. Is there anyone That's positive because, you know, if the main Vibe is – I don't think feeling is strong enough to oppose a majority negative.
YSV: I think that when we have the relationship and the history behind toSpliced and spliced fine but with typedArrays we may want something different to make a distinction. Okay. So I'll try to quickly summarize
YSV: my feeling about splice and toSpliced is because they have the relationship that they are a mutable and immutable variant. The end that there is this long history of splice, then this is a nice relationship between those two and I wouldn't propose that we remove that. I think that's fine as it is. For typed arrays. I think when we have tried historically to push typed arrays and arrays closer together in chat, it was also mentioned that sorting a TypedArray is a bit of a strange thing to do. For example, a TypedArray may be backed by different kinds of buffers. You might be doing different kinds of work like working with graphics and the data from a graphical output Isn't going to make sense, that's you're not going to get something meaningful in that case. So I think that trying to push these two together too much and adhering to this idea that we want to have this as close as possible may actually be hurting how we're designing typed arrays. In the case of toSpliced I agree that this is a meaningful API, but I would say that unless we have a very clear overlap – and in a sense we do with toSpliced but this is a vague case – unless we have a very clear overlap, I don't think we should be pushing those two data structures, those two built-ins to be the same. That's all I have to say.
ACE: Yeah, that's great. It's good to hear that the concern is mostly for typed arrays to more closely align with – as well and I'm trying to get eyeballs in the other limbo delegates in the room whether or not we'd want to retract a position of supporting this method.
RRD:I guess there was a proposition of a temperature. Check. Just asking for everyone else but we hear the implementers' arguments.
DE: Concretely, we could do a temperature check on the proposition of specifically removing TypedArray toSpliced. It seems like we all agree on that array. Sorry, Tuple tospliced and array to spliced make sense to maintain. And so the temperature check is positive sentiment If you want to maintain TypedArray to splice, And negative sentiment If you want to remove typed array to splice. [room questions what expresses negative sentiment in the queue software]
DE Okay, so positive. If you want a typed array toSpliced to exist and unconvinced, if you're not that TA toSpliced place should exist. Indifferent means indifferent means.
RRD: Taking the tally: 1 Positive, 9 Indifferent, 11 Unconvinced/against
DE: Okay, so I want to propose a call for consensus just to make sure we're completely settled on this matter. We are asking for consensus to remove typed array prototype toSpliced while maintaining tuple and array.prototype toSpliced.
RPR: Do we have a consensus on what DE just said? There are no objections. We have consensus.
- TA.p.toSpliced is removed
- no other changes at this time
Presenter: Shu-yu Guo (SYG)
SYG: Was implementing it. Notice the bug. So asking for consensus on the normative fix is a little bit strange so I'll go over it real quick. So quick recap or a golfer. the prototype that transfers is basically reallocated; it transfers the contents of the receiver array buffers into a new array buffer and detaches the original array buffer. So to do this, they must know that they're the original array, and a buffer is attached. Currently the spec draft does one detached check and then does an argument coercion on the new length and it does not do another detach check after it does the coercion. Of course, the coercion could call user code and result in the receiver array buffer being detached. So this fixes that, but it fixes that in a particular way, which is that if the new length argument is present, it does the ToIndex first and that it does detach check. This is arguably inconsistent with always checking detach first and then doing all the argument conversions, then doing another detach check. But there's a single argument here. So if we do detach checks, I figured that just seems kind of useless. So that's the one weirdness about this PR, but we need to fix this regardless. Any thoughts on – are folks okay with that weirdness? Any concerns there.
DE: I'm ok with that. I don't think it's the only time we have weird checks.
RKG: Detachment is weird anyway.
SYG: Yeah, yes, my sentiment is also that it's weird. Anyway, please just don't detach or resize your buffers in argument coercion.
MF: +1
YSV: +1
SYG: Okay, I'll take that as consensus. Thank you very much.
- PR has consensus
Presenter: Philip Chimento (PFC)
PFC: For test262 since the last time there have been a couple of interesting developments that we want to share with the plenary. One is that we have a draft of an RFC process right now. We're going to try this out with a few test cases and then hopefully we can make it official. Since basically every change we make in test262 potentially affects a lot of parties like implementers and proposal authors, this would be a good way for if you have a something that you want to improve in test262, that you can work out your idea, present it to people that it might affect, and get feedback on it. We've modeled it after the RFC process from the Rust programming language which has a reputation for having a good process for that. We hope that it'll work well for test262 as well, but that's why we're going to try it out first.
PFC: Next thing that I wanted to let the plenary know about is that we have an intention to create a staging
directory in test262 where implementations can commit their own tests directly. It will have an allowlist of people who through GitHub access controls will get the ability to commit directly to that folder. The tests won't have to be reviewed. The only requirement is that they'll be executable by other engines. This is to allow engines to benefit from each other's tests earlier in the process of preparing a feature for shipping. These tests in the staging directory will not count towards the requirement to have test262 coverage for advancing to stage 4. The idea is that as a stage 3 proposal progresses towards stage 4, if there are tests for it in In this staging directory, they will get refined and moved into the main folder of test262 at which point they will count towards the requirement for test262 coverage. We're hoping that this spreads the reviewer workload a bit and makes shipping smoother. It's also inspired by a practice that the WPT has. So, thanks SYG for proposing this during our last maintainers meeting and working out all the implications. We're excited about this. This seems like it'll get more coordination between implementations earlier in the process, so that's exciting.
PFC: The last thing I wanted to share is that we have landed tests for the regexp set notation proposal. Thanks to MB who wrote them. That's a stage 3 proposal that we think has representative coverage now. In case you're waiting on that.
SYG: A quick clarification, the staging implementation contributed stuff, the test should be reviewed by someone other than the test author by one of the engine teams like the own engine team. The intention was to codify the existing practice of when we implement stuff, we write our own tests anyway, except they just live in our own separate repos. They're still being reviewed. The dropped requirement is that they're also reviewed by a test262 maintainer until stage 4. That's all.
DE: These changes are really excellent. Where can I read more about them?
PFC: The RFC process is an open pull request right now. The documentation is prepared, but we will land it after we've tested out the process. If you want to see what the draft is, you can go to the open pull requests in the test262 repo. For the staging directory we haven't written any documentation yet because we literally just talked about it last week for the first time. So there will be documentation coming up for that.
DE: For the staging directory do you think it would be possible for proposal champions to put in early but not yet perfectly formatted versions of tests there as well. Even if they're reviewed by other qualified people?
PFC: We didn't talk about that, but that seems like a good use of it for me.
DE: Okay, great. Thanks for your good work on governance and velocity here.
JHD: Just just to add to that. I think the spirit of this folder is a place where we can all collaborate on tests that aren't quite ready to meet all the requirements in main 262. So it does definitely seem in the spirit of it to not just limiting it to test262 implementations.
PFC: That's all. Thank you.
Presenter: Kevin Gibbons (KB)
KB: Yes. Okay so this was an issue that was raised on the discourse, our more asynchronous forum. Someone points out that the BigIntint Constructor, which is used to coerce values to a bigint, does coercion twice. So here I am passing a value has different Behavior the first time you call toPrimitive on it than the second time, and even though you're only passing it to BigInt once it would get coerced twice. This is silly, it doesn't match any of the major implementations, although GraalJS and Engine 262 actually implement spec correctly, so congratulations to them, but I'm proposing to change the specification to match implementations. So that you first do a call to toPrimitive and then if that results in a value which is not already a number, you use the post-to Primitive value as the argument to toBigInt rather than using the original value again, which would call toPrimitive a second time. That's the change. Do we have anything on the Queue or can I ask for a consensus for this change?
RPR: so, okay, so Kevin is asking the consensus on the change, any objections? No objections, congratulations. You have consensus. And JHD has given it explicit +1.
- PR to be merged
Presenter: Robin Ricard (RRD), Ashley Claymore (ACE)
RRD: So, this is just an update for the record and tuple that we plan to present. Probably at the next meeting or any subsequent meeting. Our goal today is to go through this agenda. So we're going to give you a brief tour of records and tuples. Again, the current motivation that we have for this proposal, the different proposal dependencies. So it's other proposals that are related to record and tuple and how they play together. Then we also have other standards that are related to our R&T we're going to talk about. Then the current employment is the state of implementations that we have right now because record and tuple are currently at stage 2 of the spec text. Then a quick discussion. Hopefully, on frozen wrappers, and then we're going to discuss state three reviewers.
RRD: okay so quick reminder again to get started. your, if you use this hash prefix syntax that you're seeing on the screen the first time you're going to be able to either create a record or a tuple they are deeply mutable and are also Primitives. So, that means that if you do typeof, you're going to get a record or tuple. And so you can do updates if you cannot update them in place, but you can update them by copy. And we also backported the top of methods that create new tuples by copy to array and TypedArray. So we talked about it just earlier, which is called “change array by copy”. And so we also have the principle of value equality instead of referential quality. So that means that if you're using triple equal or map or set you are going to compare records and Tuple by the value that the R or T contains instead of references to them. One important thing is that, in order to make this useful for records, we are sorting lexicographically the key ordering in records, and that means we cannot have symbol keys and in records because you have symbols, you would be able to observe the order of creations of the symbols, which is not something that we want, and they cannot contain objects or functions. So we're going to talk about this in the next Slide. The benefit for us is that we can guarantee deep immutability and it's also deep equality and hashing of the records and tuples, and so that means that we can have primitives that are not able to carry communications channels. We're going to get to this because this is related to Shadow Realms and the fact that they can only take primitives as arguments is being passed down. And so finally, this avoids literal Hazard: if I'm just writing record or tuple structure and I forget to put hash inside of that structure, if II, by accident, put an object or an array in there then this is going to throw immediately and tell me that I'm trying to put an object or an array inside of the structure. But we do understand that not everyone – I mean some usages requires still to be able to reference objects or arrays…, we understand that there is a always, a need to do the things sometimes such as referencing objects, that could be DOM elements, that could be functions, could be anything And so the escape hatch for this is to use symbols as weakmap keys. you would use the symbol that you would then put in a WeakMap key that would map symbols to the objects that we would like to reference here.
RRD: We also have various APIs on this, so the record and tuple global constructors. and so they have record or tuple to pull those from to pull that of one thing to note, the record prototype is null. So that means that we don't have any methods that you're going to be able to call on record themselves. But obviously, you have to record that record and record that from entries where you're available. Tuple prototype is a subset of array prototype that is Tuple specific and that is also driven by what we presented in change array by copy.
RRD: Finally, we're introducing, JSON.parseImmutable, which means that if you're passing a string to JSON string to parseImmutable, you're going to, instead of getting objects and arrays as the result of JSON.parse, JSON.parse, immutables to give you records and tuples., the motivation for us is really that it is okay for guaranteed immutability.
RRD: That's something that's been done in the JavaScript Community for a while through libraries. immutable, here in this basic example, we're passing a configuration and we have the assurance that yes, the value is going to check deeply because as we've seen you inside Occurs in Two Poles. Things out there are deeply mutable and so we have guarantees that this will result whatever in this connection, connection, is to look at that value afterwards.
RRD: And then as we talked about earlier, we have value-based equality. I really like value-based equality, for example, in this case where you can use a record to be able to assemble a few values together to do a lookup you also do the same thing with a tuple and what's interesting in that example is that. Yes, we are able to forge a completely different record but effectively, it has the same value as the first one so we can use both as the same keys to look at the same object
RRD: okay? So we talked about proposal dependencies. So the first one that we've talked about change-array-by-copy, which got to stage 3 in March 2022 thanks to Ashley and it already shipped under technology preview 146 and I believe it's going to ship it into the next stable version of (??). Then go symbols as weakmap keys that we went with to stage 3 at the last meeting and And we're considering this work web and Mel and done. So we want to do work on WebIDL to permit records where objects would normally be accepted and same thing with tuples when arrays would be normally accepted.. So the proposal webIDL are still pending, we are going to start working on this Shorty. and similarly to what we have in ECMA-262, we need to designate the Spec, internal records designation that's in web IDL to be obviously differentiated to the reintroduced record from this proposal.
RRD: We do plan in this proposal to keep "record". The disambiguation is only going to be spec internal. So since we are exposing something here, We believe that the spec internal change is possible, and when it comes to HTML and DOM changes NRO made structural integration of record and tuple.
RRD: Okay, we have in terms of implementation a babel transforms a coalition of and there is an ongoing implementation in spidermonkey. There is a meta tracking bug. Here it is currently behind the compiler flag and the V8 implementation is in progress. By TJC, I believe we will take a nap.
MF: So I saw that you had on the slide JSON.parseImmutable. This wasn't a part that I had done any review of. Is the inclusion of JSON.parseImmutable as part of this proposal necessary? If we had it as a separate proposal, would it be motivated enough? And for the design space: I know that JSON.parse has a large design space. Do you think JSON parseImmutable has a fairly narrow, straight-forward design space which would make it not necessary for it to go through the stage process on its own?
ACE: Yeah, it's a question because you can pre-select if it's not clear this slide is the entire API of the proposal. It's not like a snippet, a flavor. So it's hopeful it's evident the proposal is trying to form an even introducing new primitive types. Like it's a big proposal. We are trying to be quite lean on the API and while APIs have been suggested, we said that they could be following the proposal. So things are good questions. to answer your question on the design space of this. It's fairly unambiguous how there's very little subjectivity because everything JSON is representable as a primitive. It's not like going the other way. We're going from primitive to JSON is ambiguous because undefined isn't in JSON. The other way, objects being records and JSON arrays being tuples. It kind of just perfectly maps and there's no kind of edge cases that were just skirting over.
RRD: And to add to this, the motivation I think for me is that a mutable person is going to be kind of a primitive to build up more functionality towards. So it's really the minimum we can do to create interoperability. At some point maybe we do plan to add more compatibility, for example, in web APIs to return records and tuples. But at the beginning, at least, if we can just get JSON strings and convert them, that would be the bare minimum. If really, we want to reconsider it because we think that expands too much. We can discuss it.
MF: Yeah, I didn't want to express a strong opinion one way or the other. I just wanted to see what the confidence level is on whether that should be part of this proposal.
ACE: Yes. The answer is high confidence. Yeah, it should be part of this.
RRD: Yeah. Because again, this is just a minimum thing. You need to reach other things.
SYG: Is there reviver support and that Source text availability in reviver proposal support for parsing mutable?
ACE: There is reviver support. Yes, I guess no to this like seeing how well it interrupts with the sourcemap proposal.
SYG: Okay, I bring that up because it's not clear to me that, given reviver support and the other stuff, that there is no room for subjectivity. Like it might be more designed than just the plain parts.
ACE: [back to slides] So yes, the current state of the spec text. So, there's a fair amount of spec text, we really need reviewers because it's the process and the more of you the more likely spec text is going to be high quality.high known that the beginning, you know, what will officially formally ask for reviewers, and this is the kind of warning that we're going to be doing that. So start to think about whether you're going to yourself forward as a reviewer. That'd be great.
ACE: So as Robin said, We have intentions to also look at the kind of wider ecosystem of specs, but that work hasn't started in terms of writing things yet you know we've talked about it and looked into how we would go about doing it. But really in terms of what spec text is ready to review, we're talking the 262 spec in the proposal's GitHub repository, The fact that this introduces new primitives, it's going to really open up this question of now from our perspective on one side, these new primitives that are very different objects but also we don't want to be entirely different from objects, we want we don't want to kind of fork the world. So our approach to this proposal is that as much as possible that you can use these things as if, if someone currently takes an object, then you can give a record, and if something takes an array, you can give it a tuple. Because as a JavaScript developer, you create and access these things very much like objects and arrays and if you're indexing into them the literal syntax is very similar.
ACE: So there is a current PR that's open, which is all the other places and 262, where we need to make a slight tweak to be effective. you do like a control F and you look for all the places where we say, “if type of argument is object, do this thing” in a lot of places that is, is it object? Then it's checking if it's callable else in that case those records won't ever be callable Get in the other places in its checking. I guess a very trivial place for this is the new error clause, options bag. It's checking if something is an object and then it's just doing a get for calls and And so could we think of being very friendly. Someone could just pass in a record with a calls property with then some primitive cause there are other places like the second argument to JSON.stringify where you can give it array of which Keys should actually be. Clank preserved in the actual JSON produced and the Order of those keys again that's that's place currently you know, it's doing a check “Is this an array?” We think it should also then accept a tuple.
ACE: And the main thing, which is more of a chore, is that fact that "Record" is already a thing inside the spec. And this is the case, the same for web IDL of aspects. It turns out the word "record" is a very popular word to describe this type of structure. Our plan is to, you know, work in each of these places to make sure it's completely unambiguous when you're talking about the actual Ecma primitive language value record vs the spec internal record.
ACE: so, some things that kind of are still open issues, even though the Champions group has a stance on this, so one is the wrapper objects of these whether or not they should be frozen in the current spec they are Frozen. So to be clear what you're talking about is you know, if you even while you can't see new hold on Newt up or it's like symbol that will throw it's still possible to get the actual object wrappers if you do as this example is here, if you have a sloppy function and you then call it so that the receiver is now primitive. That's an implicit kind of like passing that to the object Constructor or if you explicitly pass these things to the object Constructor as a call. So in that in those kind of cases, we think that, unlike all the other Primitives that are extensible, in this case we think it's important that because they're – because the entire raison d'etre of these Primitives is that they are immutable, especially for record where it's entire purpose is it's a bag of string/keys, it shouldn't be extensive or even when you've got the gun, object or a perversion I think is, especially true, because of the fact that if you the record, do is record API. If you pass that object wrapper to it, it is saying “true”. And we think it would be kind of surprising quirk of the language. If something could say, yes, this is record, but then, in the very next line you could extend it. You feel like that's just kind of a wet moment that we would introduce so, yes, at this kind of the saying what I just said approaching cancer, slide do it. Yeah. We'd like to kind of break with tradition and have Frozen exotic wrappers because we make this matches the mental model.
RRD: The main thing if we want to discuss, use cases for mutable wrappers because this is something that's not clear to us.
ACE: So one thing that internally we feel like we've had consensus on for a while – within the Champions group consensus, not wider consensus, but the actual GitHub issues were open without an update. I'm kind of listing them here to kind of met it. It's unclear that we've actually had a strong stance on this for a while.
ACE: So it was an open issue about whether or not we could do something more interesting when you try to turn records into Strings, rather than just getting the object record, kind of square brackets. And for a long time, we thought that while that is interesting, these new primitives have that capability because they're less dynamic than objects. It's kind of safer, there's fewer things. after when you try to turn into a string, there's no Getters that you could trigger anything. We don't think that it actually pays off in the long run because generally we think that it would be the kind of the one time where you could pass this object like thing and get this nice detailed string back of all its contents even though you can't do that with objects normally. So we think it's not a pattern that we can encourage
ACE: Record if you pass undefined
to Record() whether it should throw, and of we think that it should, we can go to the issues and up here, if you want to read more about reasoning.
ACE: And so equality, you think that it should be same value zero equality when you doing === equality, but if you do object or is you can then kind of actually see that. The zeros are different.
ACE: and then, lastly, that kind of whenever people talking about all these will be great as those optimizations, like, yes, potentially, there could be optimizations but we think out of the box that whenever you're either constructing and or comparing records and all tuples that, you know, it's going to be a linear operation.
ACE: So things where actually we have changed the spec recently is changed that because we've kind of said that the string you get back when you try and implicit Eternal recording to a string, won't be a very useful one that should be like symbols and it should, it should throw rather than just let you do that implicit conversion similar to be trying to like record to number. We did a kind of a little bug fix where The ToPrimitive AO kind of relies on actual methods on the primitive exotic wrappers like value of symbol.toPrimitive to actually turn things into primitives. Because record prototype is null It meant the ToPrimitive AO can’t actually handle records out of the box. So we have two special case it And we also another kind of like spec bug fix or making sure we actually reject the literal underscore Proto underscore underscore as you can't set the Prototype of Records.
RRD: Okay, with that? Yes, we would like to get stage three reviewers before we go through tcq, hit anyone's interested in reviewing this proposal. JHD? RKG? That's two. I think we need someone else. It's a large proposal. I think, at least three people would be advised. We can also find reviewers offline. Thank you, Ross and Jordan, really appreciate it.
[going to queue]
MF: I wanted to start by saying I am generally in favor of the idea of having tuples usable where arrays are expected, and records where objects are expected. There's just a couple of cases which are like, really on the edge where that I wanted to talk about. One of those is Tuple.prototype.concat using IsConcatSpreadable. IsConcatSpreadable, for those that are not aware, is a protocol that when implemented means the value will be spread (will have its elements iterated and added to the array) rather than be added to the array directly. This was added mostly for historical purposes for integration with HTML NodeLists. NodeLists try to be very much like arrays, they contain node objects from the HTML spec. So for two reasons, I don't really think that's appropriate. One, I don't think you should proliferate IsConcatSpreadable without very good cause. Two, if NodeLists are really like the only expected user of this protocol, NodeLists always contain objects, and why would somebody try to have those objects spread into a tuple? So, I both think it's philosophically inappropriate and practically not useful. Can that change? Can we not use IsConcatSpreadable there?
ACE: As a clarifying question, is it, if Tuple concat still checks something was an array so that it kind of explicitly said yet arrays are okay, but it didn't do the symbol lookup, is it about arrays or Is it about the kind of symbol protocol?
MF: For concat it's just about avoiding using that protocol. I think that IsConcatSpreadable should be used as little as we can get away with.
ACE: Then I guess we got both. We would like Tuple concat to accept arrays because arrays are objects. You can't put arrays Holds that makes more sense, you know, they would spread to Guess that it's the about does array concat Tuple, do list concatenation.
RRD: The symmetry of it would be nice if we're going to have tuple.concat of an array i work out a certain way. We expect the opposite property to be true as well.
MF: Yeah, and I would expect that as well. I think that in this world where we're treating them as kind of interchangeable that Array.prototype.concat will also spread tuples.
RRD: but yeah, but without IsConcatSpreadable, essentially congrats, probably would be just available for array prototype concat.
ACE: Yeah. I think that makes perfect sense. Yeah.
JHD: So I have a counter opinion to that, I think that it even if we had note lists. Array concat would have still always spread arrays. I believe that's not controversial. I similarly would always expect it to spread tuples and I would expect tuple concat to spread arrays, and that's unrelated to the protocol, and it sounds like everyone's on board with that as a plan, regardless of how its implemented. I agree that there's no use case for spreading a node list of objects into a tuple, but there's also no use case for passing a node list into concat because that is itself, an object and we'll throw. So it's sort of Irrelevant in the discussion. It’s workable to hard code into both of those methods the behavior. But it seems weird like I think that Is concat spreadable is the mechanism that the language chose to indicate whether concat spreads it and it just seems unfortunate to me to build in a hard-coded special case solely because we think that a specific symbol protocol is icky.
ACE: Like, I said, we could expand on icky. Potentially, I'm trying to run because I remember those a blog post recently made in the last year where Something hit, massive performance, Cliff purely because it touched symbol is can cat spreadable, which then, in I think V8 was one of these kind of if you touch that invalidates a lot of assumptions. So it’s more so than just feeling icky and that it really does have ecosystem concerns
DE: Fundamentally I agree with Jordan's reading of history. But I think it's okay for us is a committee to decide that ES6 had some over design and made some mistakes where we've been kind of coming to some to some sort of shared understanding about this for Symbol.species, this came up recently for, I mean, just now, for a typed arrays following getting to spliced and I think we can decide that going forward, we actually do want this more, more, you know, predictable, simple behavior isConcatSpreadable. Given a lack of of use cases, cases, and the simplification that it could
JHD: To respond to that. Yeah. I would think our lists of mistakes that ES6 made probably largely overlap. Should probably write it down somewhere.
DE: There's definitely a lot of them
JHD: and I'm like, I'm typically very on board with trying to avoid propagating those mistakes, and specific performance considerations. I am for implementation property and not something we should design around it. unless it is completely unavoidable based on the, you know, testimony of implementers who have that experience. And if and if they have that, feel free to chime in with that. But short of that, he like there were lots of ways that this could have been the node lists. Could have been handled in concat without a symbol, internal slots or some sort of cache from HTML and so on. And so I don't actually know the history of why this specific route was chosen. but like, I guess if I suspect that there are use cases for it Beyond, just spreading the word lists at this point, it's been on the web a long time. Okay. And I would expect that any such use cases would also want to be spread into a tuple.
DE: Well, you could say the same about species about toPrimitive and I think the fact that it's there means that it's useful.
RRD: I guess this goes a bit further than the decisions that we would like to take today. What about we propose a PR that would hard code instead of using isConcatSpreadable and from there, we could see how it looks like. I personally, would like to see the difference in Spec text because yeah,
DE: yeah. Sounds like a good way forward.
[ Other queue items for isConcatSpreadable
NRO: If we diverge from the Array.prototype.concat behavior, it's one more thing to learn
SYG: That seems like an empirical question: is isConcatSpreadable a useful protocol? ]
RBN: I'll just really quickly follow up on what SYG was asking and like commenting on JSON.parseImmutable. There was previously a small discussion about how wide is the design space for JSON.parseImmutable. My assertion here is that I'm of the opinion that it's relatively narrow compared to most things specifically, because the design intent behind JSON.parse immutable, is it is for all intents and purposes exactly the same, quote unquote, exactly the same as JSON.parse except for the fact that the return values where it would have returned objects returns records and this likewise for arrays and tuples. And then also except for cases where like a reviver, I don't know exactly how the spectators Works in this. It's been a while since I've looked at it but I imagine that when you return an object and reviver it will eventually throw because it speckles construct a record with an object that. So that being said, all of, I know that the JSON space is turning a lot lately because we've got this Source, Tech stuff and we've got the reviver stuff. I would imagine any work that gets done in those future proposals. You know, ordering notwithstanding will have to be compatible with this. And similarly I also don't think that'll be a problem because specific differences are not that large. It's ultimately just like the container for these values and it doesn't change like the structure or the source text or anything. All a lot of words to say, I don't think it'll be a problem, in that the actual design of this is very tiny. That's all I want to say.
RRD: Agreed.
JHD: As we've discussed on the discussion calls, I would prefer the wrapper's not to be frozen. It's fine if they're exotic for example, string wrapper objects, you cannot alter the numeric index properties, it would be totally reasonable to me if a record wrapper, in particular, was exotic for string properties. I would hope that we don't always decide. We would hope that we do not want to commit to forever using hard-coded spec language when we want to support records in protocol. The way to avoid the future is hard. Coding things is to add a symbol to it and without a prototype that can still be done by adding it as a known symbol, there's some discussion to be had around that but that is a path. Even if it was hard coded, that path would be following the precedent of other things boxed like Primitives that have hard-coded treatment in protocols. Still have a simple method usually on the That be conforms to the protocol and the wrapper objects, thus conform similarly. I would expect the same especially from tuples which have a prototype and also from records. How can I polyfill, or forget about polyfills? How can I make my own record or tuple wrapper and make it perform? It behaves differently for a protocol for my own use cases, if it is frozen. I need something that has the internal slot that can be unwrapped. I can't wrap. Put it in a proxy. I don't like to inherit from it with object.create. I'd have to be able to mutate the wrapper and I mean in both I think the Tuple the tuple wrapper is should be analogous to the string wrapper and behave similarly which is that I can add whatever I want on to it. Except the things that are Tuple properties, like the numerics, and then the wrapper, I would expect the same since a record can only have strings in it. That's fine. If I can't put custom strings in it, it matches the record as far as string properties. But I just don't see any reason not to allow me to put symbols on it when I want to do so.
RRD: So just to clarify, and then we go to Dan. Yeah, you're suggesting that you would be only interested in being able to add symbols strings. We don't.
JHD: I cannot conceive of a use case where an empty record Like we're a wrapper around that D Record should have different string properties than the record itself. So I think it's good for them.
DE: Could you elaborate on the use case? All the other cases where I could think of where we might want to make a protocol are ones where we want to give records reliable Behavior. So I can't think of a case where we don't want this to be overridable. Maybe you could give an example?
JHD: So this is something that was asked of me on the call and I have not yet come up with something concrete written down, and I Stood Still incumbent on me to do that. I think that when you say reliable Behavior, anything that has a protocol is already user hookable behavior and So, things are not supposed to be more reliable than the protocol ensures that is the point of making it a protocol. And if we want to talk about a protocol like species that we want to get rid of, that's fine. We're trying to rid of the whole protocol, but I wouldn't consider it reliable to have special cases that follow the protocol without using the protocols interface.
DE: It's still pretty hard for me to picture because we have things like ToNumber which do have builtin behavior for Primitives and I kind of like that as an idea going forward for records. So, you know, when you're able to think of concrete example, then that'll be really helpful
JHD: To be clear. I also think this won't come up for any New Primitives. We add that they aren't containers. I think that record and tuple are primitive containers and that is why they are special. And why would this question come up.
DE: That's an interesting thought. It's really hard for me to evaluate in the abstract
JHD: I will continue to try and write something down and supply that I wanted to bring up the topic as well.
RRD: Yeah, that's awesome specifically because you will be reviewing bottom up
WH: Record.isRecord
and Tuple.isTuple
returning true for wrappers bothers me because it allows you to generate an unlimited number of identical records which are all not === to each other, violating the value semantics that records and tuples provide. If I read the spec correctly, === comparing a wrapper with the record it’s wrapping returns false, and likewise for two wrappers of the same record.
ACE: Yes.
WH: This is not how existing primitives work. For example, Number.isInteger
returns true on 4 but false on a Number wrapper of 4.
ACE: so, I guess what? motivation for record record is record, is, is that without not having a prototype, there were no other ways to produce a brand, check for the the, the object wrapper, which was like from Jordan. Expressed that, that was a desirable quality. But whereas, in other places you can use prototype value as a way to kind of trigger the brand check knocking the Prototype. So that's what initially motivated that API and why explicitly and works on the, the Rapids, you're right that it then leads to that consequence of if you do create a lot of these wrappers, which hopefully people won't doing, you can produce an infinite number of them that aren't equal. Well,
WH: This breaks the contract for records and tuples. I would expect something on which Record.isRecord
returns true to obey the record value semantics rather than sometimes having value semantics and sometimes reference semantics. This is too confusing and diverges from primitives like Number, so I’d want Record.isRecord
and Tuple.isTuple
to return true only on primitive records and tuples.
DE: I don't think we really need an extra predicate to check the Primitive because we already have a type for that. I'd like to call on Jordan to explain why he requested this feature for brand checking wrappers of records and tuples.
JHD: yeah, so it is currently and whether intentional or not, an axiom of the language that all Primitives that aren't in nullish can have a wrapper object when pass through the object Constructor or used as a sloppy receiver type of reports object, on those wrapper objects as expect all of those objects. There is a, for all of those objects. There is a mechanism that checks internal slots to detect whether this wrapper object is in fact, wrapping A Primitive of the expected type, there is also a mechanism to unwrap or extract the primitive from the object. It isn't a consistent thing, unfortunately. And it isn't like you have to know what it is for each thing, but it exists. We discussed this actually in es6 for not just Primitives, but for objects as well that all objects should have this. That was why we did not keep the string tag. Why do we do? We did not withdraw it from es6 and that's and that's something I want to retain. I think that as long as record tuple rappers can exist, which I think it would be a big precedent deviation to say they can't. Then there must be a way for me to identify them. They have an internal slot or not? And then separately there must be a way for me to unwrap them when I've decided that we'd have detected they have one. So for tuple this is actually much more trivial because you could stick a value of on to build a prototype for example, symbol dot toPrimitive, right? And those are all fine, but the record has a prototype. And so, there has to be a static method to do it.
RRD: So, can we can, we try to kind of result this and so Can I propose something? And you can tell me if that's completely stupid record, does is record with only work on record Primitives. Tuple.isTuple with on work on Primitives well. Would that be outlandish to add is record wrapper and is to provide her. So you could specifically fo for this
JHD: Yeah, I mean that that's fine. That just means that my generic predicate would be type of vehicles record or is regular ever. Yeah, I mean the I think that's less ergonomic but fine like I'm I am standing firm on needing the capability. I can not stand it. Like, I have not heard about how ergonomic it must be.
ACE: What one think the thing about this is it, it could resolve itself in time But could you take the like emit idea? when we're looking at the object someone raised, the fact you can't, there's no built-in way to remove something from a record without writing a utility yourself. then sub. What we saw is that all, there's an object at MIT proposal, if we got an object on that, maybe would get a record at the bottom of it and then that record would alarm it. If it was checked, it would then give you. So let it resolve itself in time. time.
JHD: There's potentially another way we could look at this. well, I mean but in that case the Record .o Man would be providing the same unwrapping facility that record already does.
ACE: So it's the detection facility that it would not be provided by an event function, if you try catch it was like,
JHD: oh yeah. So and that is true. But try catching as a slot detection mechanism is by and large a legacy from es6 that we have not continued, we haven't added anything since es6 as Well, but it's slow and not ergonomic. And I think it's a It would be pretty unfortunate if that was our way forward.
RRD: I think we're going to go ahead of time before I already over time. Yeah, yeah.
DE: I guess just quickly for my queue item Jordan if you could follow up with something written about your use case,
JHD: like in terms of console.og node and every test framework that describes what it's doing. It needs to know whether something is a wrapped object sitting for better debugging. I think I've done it but it's there.
RRD: I think I think we're we're happy to explore addition to the record wrapper and to go wherever the spine.
DE: Yeah, would people have any concerns with the direction of adding Record.isRecordWrapper
and Tupe.isTupleWrapper
?
WH: Just making sure that Record.isRecord
and Tuple.isTuple
would only return true for primitive records and tuples? My concerns would be addressed if that’s the case.
JHD: Yeah, that would be the case.
DE: does anybody have any more concerns for stage 3 if the intention that the presenters stated was to go state 3 based on this and possible changes, based on what we heard today, are there any other issues that people might have?
RRD: Otherwise available and we have a monthly call.
- JHD and RKG to review
Presenter: Luca Casonato (LCA), Guy Bedford (GB)
LCA: So yeah, I'm Luca and I'm going to present together with Guy Bedford on import Reflections. And we would like it if we actually go to stage two today, or that's what we're aiming for, okay? Yeah, quick recap on what input reflection is. We presented this a couple times by essentially input reflection. A user can import modules with alternative Reflections or alternative representations, which are not the default reflection of that world that we already have. A use case that we have brought up previously is to allow importing, rarefied representations of a compiled module, which is unlinked to a nun. Instantiated when the host, As such representation, And for example, your webassembly module. As you see in this example, you might want import the wrong module which is unlinked and uncompiled, or sorry unlinked and uninstantiated but is compiled, rather than directly importing the module into the yes graph and it's actually get yeah, so this is the suspect were proposing. Aesthetics impacts there's this keyword after the import statement which specifies which reflection would like if this is emitted, you go the default import which we already have right now for reflected Imports only the this form where you import the default is allowed is no named exports or decorations for reflective imports.
LCA: There is also a dynamic import form of input reflection, which we think should be supported through the option options bag on the import syntax. This options bag would have a single key, which is allowed, maybe we called reflect and this can be a string representation of the reflection that you would like to have for. It can alternatively be undefined and the options that can be omitted if you want the regular behavior that we have already.
LCA: To quickly go over the proposal scope because it has changed since last time, we very. We've narrowed down to proposals go further than it was previously. There's no narrow down to just being module reflection, which means we want to point out only support a reflection where one can import a loaded compiled on linking and expand executed module object, we do not want to pursue asset. reference reflection in this proposal because I think it is too complex for now, but we will continue to consider the implications for future as a reference of the proposal during the design process. So this is something we may want to pursue in the future but it is out of scope for this proposal.
GB: Just to recap some of the changes since last time. Previously we had the syntax with "as module" at the end of the import statement where it was an arbitrary string. Based on further feedback that we had on that we have now moved to using a direct reflection keyword in the syntax and that was through discussions in the module calls that we've been having. And this means that the module keyword can be explicitly defined as opposed to defining more generic reflection mechanics with this arbitrary string functionality, but we still look at that. Keyword, as being the reflection keyword, so that other keywords in future can follow the same pattern that we're creating and we can also consider these other types of reflection. So what we're doing, In is we're very much thinking about doing it in a way that can extend to other use cases of the future, but at the same time, narrowing our Focus to this particular syntax. So when Luca mentioned the asset references proposal everything we've done is fully compatible with that. you could replace the module import reflection keyword with an asset keyword the same Syntax would work that you can import assets and on Dynamic employed, you could have reflect asset as well. So we feel that we've kind of thought about it generally and we have a convention that can work for lots of different things and expand things but then we don't actually need to Define it as a generic mechanic; we can just very explicitly specify the exact syntax for our purposes here.
GB: Just to reiterate the exact webassembly use case, because I think it quite often comes up what exactly are the economics. And the kind of interactions that play, this is this would basically be the recommended way of loading webassembly today. And it there's a lot of stuff going on here and it's a long for You're not familiar with all the equal, the details to reply. So, webassembly.compileStreaming takes a fetch response and gives you back a compiled object. Then you have this new URL pattern to do a portable import. And finally, you're getting our to your module. So I mean, there is a lot of different things going here. I just want to break down some of the pieces. So the first point to note is that even with the webassembly ES module integration. There will always be a need to directly get access to these webassembly dot module objects because of the fact that in most cases you need to perform additional instrumentation around the module. That wouldn't necessarily be possible directly in the ES/wasm module integration. and if you make one small mistake that syntax, You are going to have some issues. So for example, if you don't use the new URL, specifier comma import metadata URL pattern. Then you creating something that works, but it's not going to be portable as a library, and it's not going to relocate. Well, and you're going to need to have some out-of-band configuration mechanism for users to point to the webassembly location. And as soon as you do that, you do static analysis that you no longer know what you're importing and so so that's that's a really strong motivation and problem that webassembly, you're losing the information of what you're actually. executing which is what the EAS module system gives us in the first place. has its a lot of information about what's executed. If you run on platform that doesn't provide a fetch function, then it's just not going to work. And then you have to have these branching statements to then lower the platform-specific file loading APIs. And then not use webassembly compile streaming, but then just use webassembly compile or something, I always forget which one, there's a whole bunch of APIs. And then you have to fall down into these Alternatives and before long, that function, that was already very complicated, starts getting split up into 20 or 30 lines of code that is all very custom, very manual and doing a lot of things. Iif you split out the URL, as its own variable and you have a branch on the Fetch and then you're assigning to a fetch function and then your maybe using compile streaming or maybe not depending on which branch you hit, you end up with a lot of variations of This coffee's code paths. So there's this kind of huge explosion of possibilities of how you could write this and we've completely destroyed static analysis. So there is our way that your tooling Even This is complicated to analyze in a build tool to be able to know what webassembly is being executed so that you can actually analyze the execution but once you explode out into all these conditional variations things. It's almost impossible for any tool to know what, what's being executed.
LCA: And I want to mention real quick, that this is not a hypothetical concern. There's like this is the actual output of a build tool, I don't know if you can see this. These really this 40 lines of code, which essentially does this. There's a bunch of different branches here doing different types and fetching different webassembly instantiations. A different build tool here generates again similar output with a bunch of different branches. This is not the entirety of the code. There's more in this file. Like this is a very non-trivial amount of code.
GB: Okay. Yeah, so that the benefits of bringing this under the umbrella in the spirit of the webassembly is module Integration is firstly users, get the ergonomics but there's there's a standard way to just get hold of that webassembly module in JSP roast and old we cut out all of that complexity so that's what the end user sees the benefit of that unified ergonomic is that all the other benefits, then follow from its analysis can. know exactly what webassembly modules are being executed in can easily trace. It just like they can for ES modules and, and using the same techniques analysis tools used for years module announcements. And then finally, on top of that, you can build tooling that can now deal with optimization. And general build tooling problems that fall out of that and that that are based on that analysis and then security is the other the other benefits that because we Kno know exactly what it's executing. Your analysis is able to have stronger security, analysis possibilities and on the actual platform side as well. It also offers a neat way for the platform to control the security. And said that there are some of those benefits which followed as well.
GB: So symmetrically for the jsu's case, what we found as we've explored the reflection where JS is that there are some interesting possibilities here for how a similarly common primitive for JS. Reflection can help and Aid. The use cases around Dynamic model instantiation that we want for JavaScript to enable JS modules, to be more reflective more. To provide more low-level capabilities and the benefits that extend in that when we do this with JS as well, is that you get those same benefits of static analysis, tooling benefits and security analysis for these compartments workflows that compartments have been exploring. So we can do better than module-eval when you're doing these compartments workflows, we don't need to restrict ourselves to arbitrary Source texts and And effectively treating. Those arbitrary module-eval, we can maintain these strong static guarantees even though you're doing very Dynamic stuff and that's quite interesting from the perspective for example, enabling mocking eval in an application that has CSP enabled, or virtualization application that wants to have strong CSP policies and not just enable arbitrary evaluation. So there are some some very real benefits that we can bring back to. (?) Primitives in the compartment style.
LCA: Yeah, so more the technical side of things. So these are the use cases we have mind, we to go up to provide this. We need to add a new host hook we think, because webassembly is defined in separate specification, right? So there's like, layering layering issues here, our layering your requirements actually, where the host needs to specify, what reflection should be returned for specific specifiers and our we have asked inspector act upon the repository, which you can look at. And for now, we're also using this. The toast to occur for the jschmuldt reflection because we are not yet in a state where we have figured out exactly what DJ's reflection the object returned from today's reflection should look like, because this is highly related to compartments and macro blocks. So for now we are not defining this and we are make hunting this entire problem into the host hook. And during stage two we will figure out exactly how to deal with underwear collection and how we can natively integrate that into ECMA-262 spec without conventional belong to host. The final figure if
GB: I can just add to that. We mentioned before that, there were a bunch of APIs that we could explore here or possibly even specify. What we agreed to do for now is we will hope that other specifications can provide these definitions for us. So we don't expect that we will need to define what a JS reflection is. We're hopeful that through better collaboration, we can we can work to and make spec progress so that we can reference another specification and that's what we're shooting for here.
LCA: Additionally, another technical problem here is the module specifier semantics. So as most of you are probably familiar you import a given specifier, If you put that same specifier multiple times, you'll get same, the same object returned every time.. We intend that this is the same for reflection, in the sense that any reflection with a given specifier. So we're given specifier plus, refer must return, an identical reflection. And also, we want to additionally, add the requirement that the reflected import must represent same underlying asset as the on reflected imPort for the same specifier. So this means if you were to load the same asset both as instantiated and an uninstantiated module, we would want that to only be changed once at be loaded points. And not be able to change what I've said. It actually is executing or a representing between those two Imports.
LCA: There's still a bunch of open questions we need to answer. Most of them come down to interaction between multiple compartments, as GB was talking about earlier during the host rock slide. We need to figure out the exact idempotence requirements and adjustments that we need to make because as I just described in the previous slide, we need to make sure we need to figure out how exactly this needs to be represented in Spec text right now. These requirements are just requirements on the host open, which we have found for assertions. Particularly many people don't understand, and we would like to figure out better ways to Define this in the spec, in such a way that it is easier to understand. We also, also need to figure out how these dish. How Jeff Reflections have the object returned from Gates Reflections? Are can actually be dynamically instantiated. This is what next section is partly, actually going to be about compartments, as you can look forward to that. And then we also need to figure out if how we want to align with module blocks because module blocks, the courts in its current in their current form importing, module blocks The then import syntax can actually get them. Do we want to support the same behavior? And if so, we also do, we only want to do this gorgeous Reflections? Or does it make sense to also be able to import assembly modules this way? yeah, so those are some of the open questions we shall have. Are there any questions from the queue?
JHD: So, the first one is definitely something that can be resolved with in stage 2 but the Syntax for static and dynamic reflection doesn't seem mirrored to me the word reflect appears in the dynamic form and not in the static form. I brought this up, I think on github. so it that is unrelated to the stage two advancement question, but I think it would be important that they be mirrored and that means the same words are in both places. In the same way we chose for import assertions heading for clarity and learnability, that's important.
GB: I guess the mental model could perhaps be seen that the syntax is a little like, calling a function that these are anonymous parameters. Whereas in Dynamic import, you're giving named parameters. So I think that's a little bit more one way to see it – that the position of the syntax, that's that second keyword position is the reflect option, basically is how we would see it. And then that's that's why it's called reflect in the dynamic input syntax. But can certainly appreciate that, I think that, was that's one of the benefits of perhaps approaching it more generally is that we do think of that as the reflection keyword and we think of the idea of like the asset references proposal as a reflection. reflection. So that these things could fit into our model that hopefully we're creating that isn't just going to constrain us too much, but we can certainly thinking about for them
JHD: And then my next queue item, iit makes me really uncomfortable that syntax would produce some arbitrary random, kind of host depend determined object, all the use cases you presented seem valuable. But like and I get the convenience It's of having the syntax immediately produce a webassembly do something. But is that necessary or could it instead produce some of something that you passed into a webassembly function? For example, to construct what you need like as an example. Is there a way we could minimize host Defined things, and kind of make it slightly? Less magical.
LCA: So let me take this one. I think that we already have things like this, right? Like, you can the web import a CSS module, for example, and then the CSS module will have if you do a default import on that, it will return a CSS Source text. Now, I did some host defined object. And essentially, this is similar, right? Like, what we are essentially giving what the host is ventured. Essentially, defining, here it is. The default. Export of the of the reflected import.
JHD: So I think profoundly different though. I mean like, a default import you expect to be able to get whatever the module author gives you. Reflecting around the module is giving you a like insight into, you know, it's giving you like something from the inner inner workings of the module system and like it feels it also feels strange to me like sort of related to this that the type of object I get depends on the format. The module is module is offered in and the more that like I think it's a the experience is worse. The more I have to know about the way the module I'm importing is authored Like knowing its API and semantics, of course that's unavoidable. But like the way it's typed, like what language, it's written in and so like the more I can avoid having to know that in order to use it, think the better and it seems really weird to me that I could get a custom object because presumably this interface or API or whatever is incredible entirely unspecified,
GB: we are quite narrow, specifying it. So as mentioned, we expect to fully specify The JS reflection so that that would not be something that would be possible to change. So, all JS modules would have a clear singular JS reflection. That's not something that we would commit hosts to all sit at the end of the day because of this nature between webassembly and JS and the layering of the specs. The only way to do it is a host hook. But I mean for we don't expect that it would apply at the moment. We don't see any examples of other Types of module Reflections that would apply apart from webassembly. We could explicitly even put that in the spec and say this is only for webassembly, there's ways to more strongly restricted but there is this Duality between JSON web assembly where when importing webassembly, there is different things you want on the reflection that are very webassembly specific uses need access to table information, typing information, things like that. That will be very specific to the compiled module. and that we have this defined and if anything this brings the languages closer together as opposed to treating it as an external problem, that is isn’t ours to solve.
SYG: Yeah. So I find Luca’’s analogy mostly correct. like, I think JHD, if you think of so, you said you already expect the default export of a module to be some arbitrary thing and therefore you don't have this mess. Mismatched expectation that ought to be the same thing even though it's still syntax, right?
JHD: Like it's still import something, right? It's like a function return value that. It's still the function could me anything.
SYG: Right. So module reflection doesn't exist yet. So what is being proposed here? Is that what you could get from a true reflection? It's not completely arbitrary. It's it's like narrow down to be completely arbitrary but it's not so narrow down as to be always exactly the same thing but that's part of the proposal, I'm not sure why would have the intuition that it ought to be like. It doesn't seem like an argument to If it says if the argument is what I heard was its syntax, therefore should always returning. Same thing. Default export is also syntax, but you have already internalized it does not return the same thing because that's how it works. I don't see why that's an argument this should not be done. There are other arguments you could make for why it should not be a narrow (?), but the fact that it is syntax isn't an argument for that.
JHD: Yeah, so I agree with you. The way I phrased. It was, didn't make sense for the reasons you said, it's not simply that it's produced by syntax. its that, if I, if my mental model is meant to be, this is generic reflection around. the module which will tell me information about the module which may or may not contain wasm specific things. But like some problem, presumably, presumably there's some Universal things that module reflection will have. And then there's some extra stuff that an individual module might have and so on that in general, seems fine to me, is the like inheritance hierarchy of, this is an instance of a special constructor, that's not in the language spec, like all that stuff. Seems really strange to me. We could have had import.meta be something like that, or the module namespace object be something like that. that. But like instead it's a very tightly specified normal thing or consistently exotic thing and so it's all the capabilities is trying unlock. I had that seems great to me and bringing WASM and JS closer together is great to me and acknowledging them wasm is not any random other language. It is a special sibling of JavaScript or something, or cousin, or whatever that also seems great to be I'm but I don't get a good vibe from getting a like this magic instance. I'm sure there's other designs that would be worth exploring, maybe they'll end up not being worth it. And this current design is better. But I think it's worth Exploring that further, whether that's prior to or within stage two, I don't know what will be most appropriate, but like it just feels very strange to me. And also the general existential thing. I can say I'm concerned about with any proposal is that, if it leaves the gate too far open, might never be able to tighten it again, or do I like close it again? And so I am always interested in maximally restricting, what can be done. and then as soon as we find there's a re the, you know, with the paths to loosen it. So that as we're told that there, Use case, we can provide for it.
USA: So, JHD, sorry, yeah, the next item in the queue might address that.
SYG: Thank you for the context there. I think the tension here with WASM and in particular, is that wasm, is here today, the JS, wasm API is here today and some white use and what was simply that module is in wide use today. And you know that's that's a unique constraint that doesn't exist on other modules, in that there's already like an agreed-upon thing that it'd be nice if the hierarchy could work out. I think that's what we ought to be going for with pragmatism there. And the other thing, if I can read the subtext but I might be misinterpreting I know in the past, JHD, you have expressed concerns that poor performance that, you know, you don't want the tools to abuse import insertion to evaluate attributes. You want the tools to kind of pitch meeting to be to have willful violations.
JHD: Yes.
SYG: And you think a good way to limit that is to build certain language into the into the spec to discourage that. I I see that problem is mainly a communications problem with the tooling folks. And I'm not necessarily like I'm not convinced currently that maximally restricting it in the spec will achieve that goal. That is one tactic would be used to try to achieve that goal. I'm not personally convinced of that and it just want to get that out there, but I don't think that's that is relevant to. That particular sub, Texas is not really relevant to this proposal as they're presented right now, which is so-so. Narrowed down to to wasm, but yes, you can you can easily take it to them.
JHD: What I would say is that communication to tools requires or can be aided by a normative restriction. It can also be aided by editorial notes, and there's also lots of other ways to do it. But there are many tools that don't talk to people, they just read the spec and then ship things like that.
LCA: I think this I think it's a valid pretty bringing up and I think it's something we need to consider and I think it is something we can definitely explore maybe during the loader weekly meeting that we have, I don't know, maybe you could join those but maybe that's a good thing too because thinking Because I think this is also like a cross-cutting cross-cutting concerns about do you, example, allow with us.
DE: Okay, Niccolo. You have a concrete thing on the Queue that actually resolves this. We've been talking very abstractly for a while.
NRO: Yes, so that's part of working on other module proposals. I was trying to understand how much we can move from host-defined Behavior to things exactly defined in the spec. I think for this particular case, we can at least guarantee that whatever this was a host-defined operation (?) the same thing that gets evaluated when you import a wasm module, so it's still host-defined Behavior, but we can narrow down its way more than what we proposed or compartments does.
KKL: Hi, this is Kris. I wanted to jump the queue a little bit into it because it's a good response for this question. I support stage 2. I feel that it's well-motivated in the Sin taxes palatable. I agree with Jordan that the type should be more specific than webassembly module, but can be webassembly module. if it if it were too Go up to the height that we find. The, I think that we're already on track in conversations with the modules group to come up with a good solution, I think, for what the reification is for, for a module. And, and for the underlying module source, which would be reusable and that overall, we're pretty happy with the trajectory for this proposal. As Jordan said, I do expect that this the type would be more specific. It would be able to that web assembly module would have to be able to provide a more specific API that is consistent with what we would see from a JavaScript module for the purposes of the static analysis of its dependency graph. But apart from that it could be object identical to a web assembly module if webassembly module were extended in that way, provided that we arrive at a an API for that in the modules discussions. I think that's everything from me.
DE: I completely agree with everything that KKL said. So further, there's ongoing discussion about the types of what a construct like this might have and module blocks and whether or how these relate to each other. This is very closely linked to the open questions that were mentioned at the end of this presentation such as whether this reflective module can be imported. And I think stage 2 is a great place to work this out. I think as we come to more concrete answers on these the nature of the host took will change and I do think that it will end up being more specific than than what we have now without, you know, excessively restricting, how HTML or their hosts can can make this work. The important thing is that we make something that is Specified concretely enough to be made to work. So historically with es6 initially, the way that modules were specified was found to be not concretely implementable in browsers. So there was a later change to defer a lot of the behavior to hosts in way that allowed everything to be very concretely specified, which was very important in getting them shipped in browsers. But that doesn't mean that, it's the only way to do it. I think further refactorings are possible which enable the functionality in real life that we collectively decide to ship, but also provide these sorts of understandability guarantees that we want.
YSV: I actually want to touch on what DE sort of left off with here on what you have in the open questions. There's this open question about the space between module blocks and this proposal the reason I want to bring it up is because we're sharing the syntax space there and my understanding of how it works in In the module blocks proposal is we have module as a keyword load by curly braces and then all this stuff and then that works as a specifier which can then be used instead of import. But here, we're going to have an import and then the same code form. So, import module will. And then have the binding followed by the specifier. So I was thinking since we're also coming to this question of will reflect the modules be supported during dynamic import instantiation. That's an interesting question because then we will be importing twice. We will have a import of the module of the reflective module and then we will be importing it a second time. So that gets me thinking. Do we maybe want to drop the import keyword from the beginning of this static module reflection statement Have have we thought a little bit? I think there is more to of think through here. If this is how we want to approach it, especially if we're going also apply the same logic to assets. And I'm kind of wondering if we do want to do that. So I wanted to raise that, I don't have any objections here. I have a couple of concerns. I haven't been present in the most recent module calls so I don't want to throw a wrench into any of that.
KKL:I feel that it's – without too much prediction of the future I think that it is very likely that the module Hhrmony calls will eventually resolve at a place where module blocks and module reflection are reified into the same type. I think that it is also true that that type will probably carry an exact webassembly module provided that it's (?) enough that we can statically analyze it. And that, that these two will probably as you say occupy the same space.
YSV: Yeah, we we may want to play around with this context a little bit more, but as I said, I don't, I don't have any concrete objections. It's it was the rethinking of how the syntax of this proposal will work, was new to me. So, that's where the question came from.
USA: It was also a clarifying question by Luca.
LCA: Yeah, I think you have to do it already. You don't have a concrete syntax proposal. I'm already asking about that.
USA: That's the queue.
LCA: Fantastic. Then I would like to ask for stage 2. We have an initial spec text on the repository, which implements the entire specification based on the host-defined behavior. We don't think this is final, but I think it's a good starting point for stage 2.
DE: I want to note one more cross-cutting that I should have noted earlier in the module calls. That I think we should resolve during stage two, which that module fragments may allow you to do import an identifier, I think can be unambiguous, but as long as we're, we're discussing cross-cutting concerns with module blocks. I just wanted to note this is one. I support stage 2.
KG: Ask for reviewers!
DE: I imagine things will change a lot between now and stage three.
LCA: If anyone wants volunteer that would be great but I think there's still going to be a bunch of discussion ongoing during the loader calls.
KKL: I will eventually volunteer to review this.
DE: I'll also volunteer to review this.
LCA: Thanks DE.
- Stage 2
- KKL and DE volunteer to review once things are eventually ready
Presenter: Kris Kowal (KKL)
KKL: Okay, yes, it's clearly on I'm Kris. It's been a very long time since last presented at a plenary, the first time I presented was in 2009. Where I proposed. Hey, here's this thing that eventually became common JS and then in 2010, I presented again. Like, hey, here's how we solve this commonJS menace that we've created. And it has been ever since that. I that I felt said, hey, I have not presented since but what I learned from that experience was two things, one of which was never under any circumstances attempt to be funny at plenary. the other thing I learned was never under any circumstances propose a module constructor. And we'll see, we'll see.
KKL: So this is an update for the compartments proposal, which is now been in stage 1 for 2 years and we've gone off in bed at a little bit and then met up with this modules Harmony group. And so the question is, what do we do with modules in JavaScript? It turns out that we have a wide variety of verbs for modules in JavaScript. We run them, loading, transport bundle analyze split defer, watch isolate, there are all sorts of things that we do as modules and in this proposal, you will see. Absolutely no new motivating. Use cases. You will see all of the same motivation coating use cases that you've always seen before with modules with one clever catch. And that is to say that we are trying to close the gap between the experience that you receive with program in development and testing and what you see in production and possibly even make some of the existing use cases practical in production where they are not today because they would require including a JavaScript parser into a production application for reasons. And it happens that we have all of that in production already. Why should we do it in JavaScript?
KKL: Since we last spoke about compartments were brought into stage one as an exploration of the problem of emulating host behaviors: the idea, was to allow any host to emulate any other host and that scope turns out to be unnecessarily large possibly harmfully large. That is the bulk of the problems that we need to solve with that. There were motive, that motivated the champions of the proposed. Are adequately solved by virtualizing module loading and the isolation of evaluators and the compartments object itself. as we have been vetting for the last couple of years, we feel through our conversations, module harmony could be reconstructed from more atomic, things that align better with existing module proposals. And so, this is an update we're not asking for advancement. What we are looking for is opinions, from within this group of whether each of these individual, slices of the compartment layering, are well-motivated and why, or why not? And, there are a whole bunch details about this proposals that are very much in flux and are subject to agreement with the rest of the modules proposals, which we hope will advance together, or at least advance together on a common Foundation. So the compartment proposal breaks down into layers. We would first make a surgical change to the language, which introduces first-class modules in the ability to virtualize importing other modules. This would not require us to entrain. thing about module Maps or canonicalization, from web specifications, it's just reifying module records and splitting module records between their constituent Parts, which are the highly reusable, immutable, module source, and the representation of the life cycle of a module instance. And then the second part would be an ability to reflect the static analysis of a module that's been parsed by the language that is to say, what did it import so I can go off and load it and build up my own module graph in user space and then a second part of the third layer off one, the would be adding first-class module sources which would unlock. This is an optional layer that would allow us to unlock things like other languages than JavaScript in user code and even among the champions, there's some disagreement about how to go about this, but the desire to be able to, for example, in user code, come up with one of the many valid ways Of loading commonjs into an ESM Module graph would be supported by this and then give you options for doing things like assets. New Explorations. That users might be able to do without explicit consent of TC39 or the web. And then the last one, the last necessary layer in order to build compartments from more Atomic elements would be the ability to construct a new set of evaluators Within neighs within the same realm this again, is another surgical change that would interpose a layer between execution contexts and the realm where the eval function and module Constructors would be bound to particular Global context. so that all of the evaluators could be isolated within a smaller thing than a realm. You might call it a “compartment” and then compartments, then become something that we can decide later whether to incorporate into the language as a higher level API out of these Atomic operations or simply defer to user code, because they would be implementable. I posit without proof in terms of the lower layers.
KKL: The dependencies among these are not straight up linear, it's not strictly a layer cake. Some of these things depend on others and others do not which means that we have some flexibility about which layer is get attacked in which ones do not end when. So I'm not asking for an Omnibus, an Omnibus inclusion in the language, all of these things we can look at some of them separately, separately, but we feel, in particular, that first class modules and the virtualization of import is a common building block or at least the initial refactoring of the spec to enable that is a necessary common building block for module blocks deferred execution and and module reflection, which we look forward to discussing with the modules Champions and up to the point where we achieve module Harmony. And what we unlock at each of these layers is different, which means that the coalition's of people who are interested in them and the and the motivations are stronger or weaker or interesting to different people depending on which layer you're looking at. First Class modules are unlocked that Foundation that allows to have a coherent set of module features added to the language. And also I answer the question of how we would multiply instantiate a module the same with, in a particular realm and And while this does not unlock much on its own, it does not deliver much value to user code. It is a foundation for having a coherent language going forward at the next layer. This is the one, I think opens up the most avenues for user code, to explore extension of the language. And that is module reflection, which is say analyzing the import graph of something that JavaScript has parsed on your behalf. Say, I take this thing, I parse it, I figure out what it's it's statically analyzable findings are. And now, I and user code can go and resolve those Imports specifiers and find the corresponding sources and build out module graph without ever actually executing any code and notably without and introducing Babel. and that unlocks the ability to write bundlers that allows us to explore import map in user space and it gives us everything we need to implement hot module replacement in user code without having a ‘source to source’ transform and a number of other motivating cases. And then at later this, this third layer first class, module sources would allow us. of create new types of modules. Like, for example, a JPEG module if you wanted where you could just take some arbitrary text and then convert it into a module instance, from that text and notably, this would allow us to invest to create a bridge forward from the past for common J's and hopefully, someday never think about it again. And then the last, the last, necessary layer as a building block, for building compartments is evaluated your evaluators, which we feel have two major camps of potential motivating. Use cases one of which is hey, there are these DSLs out here. Like in particular, particular, the Jasmine including jest, that create, that put their API in global scope, they as properties of the global object. And then just rigorously ensure that none of these two modules, execute, concurrently or interleave with one another that they can figure out which describe call corresponds to, which original source: that is solvable, we could create an alternate Global in the same realm that even is prototypically inherits from the normal Global that would allow you to have a per module Global for these DSL cases and therefore, be able to have multiple instances of modules with these piece of DSL and you wouldn't have to resort to Dynamic scope to figure out who was calling, which module was calling. And then also the other camp. feel would be our own camp. The camp that wanted compartments in the first place. That is to say those of us at Agoric and Moddable and others who are isolating, third party dependencies in the same realm, which allows us to limit the blast radius of the supply chain attack. The trick here is that suppose you have some modules that come from some particular package: We can construct a policy that ensures that it only has access to the APIs that absolutely needs in order to do its job. So that is to say your “left-pad” package does not need access to the document. So why does it have access to the document? This is, this is the motivating, use case for compartments as whole. And then, of course, at the last layer, we can build that use case out of these four. Lives in user code or added to the language. Another good reason to have compartment in the language apart from the embedded case is also that compartment is useful high level API for writing running times for things like import Maps, which would necessarily have to be included in the inline script of the root of the page. So there are some benefits, we think, to having compartments in the language on top of these low-level Primitives. But that is, of course, the topic of today, we're looking for Back on whether each of these layers is sufficiently motivated.
KKL: So phase, zero. Taking a look at each of these phases a little bit more closely. First-class modules would look like this up. Pull out your plenary bingo cards. Thus this and check off “Kris proposes module Constructor again.” So again, pardon I'm proposing that we add two new globals the language, one of, which is a module Source compiler, which takes Text of a module and gives you a representation of the compiled source and the compiled Source would be a reusable artifact, the underlying module Source record behind. This this would be shareable across agent clusters because it is effectively immutable, highly shareable because you only need to compile once and then you could and these things can last for a very long time, which is the principal motivation for their separation, they are also utterly powerless which means that you could share this. between different compartments or or evaluation context, however, you wish to look at it such that it is safe to share these things. They just represent executed code, part of the compiled code that can be later executed in another context and that brings us to the module Constructor which it says, “Hey here is this Source”, I would like to link this in a particular context and create an instance of it eventually and here are the virtualized behaviors want for its Behavior. And how, and what I wanted to see as the properties of its import.meta and the proposed tentative proposal is to make this look very much like the module block proposal which is to say this is yet another overload of or Possibly, just the one overload were actually asking for across all of the modules proposals for dynamic import, instead of just a string. Here's a module instance, please Advance it to its terminal State: success or failure and give me its module namespace object. If you succeed, that is to say that if you were to import a module, once it has a 1 to 1, 1 to 1, 1 to 1, Etc, relationship with its module environment. Record the module instance, the module exports namespace the yet, Seen module Imports, namespace. All of these are 1 to 1 such that if you awaited the same module instance twice, you would get an identical namespace object. And if you wanted to have a different one, you construct, a new module from the same Source, potentially even with the same hooks, the hooks May default to the underlying the underlying hooks associated with the current evaluator, which notably might be ones provided by your host, which allows to use the existing post behavior for hooking for importing and thereby recovered. Just if all you care about is multiple instantiation, it is easy.
KKL: And while we're over here, as I consider it a challenge, for any of you to construct the proposal that allows us to fill in the largest contiguous block of plenary bingo. And it would be something I presume something like time, zone, sensitive regular expression, matching for Emojis, with combining characters, 402 clock, so that you can get hour and minute hands minute hands in the same time zone. Or, we could bury that idea here, where it belongs.
KKL: So other things about module instances, that yes, again, if you wanted to have separate instances, you create new module instance from the same Source, you thereby amortize, the cost of having compiled the thing in the first place and can get a separate instance and the import hook looks like this: It is tentatively, The Champions do not yet agree about this, but tentatively it looks like we're going in this direction that there's an import specifier and some way to get out the referrer, which currently as it is sufficient to use the import meta to find either a resolve function or a URL or path depending on what is a depending on what is meaningful to the host for the purposes of resolution. And then we write a function in user code that resolves, that locates it. fetches it from whatever storage mechanism and then constructs the source and returns a module instance, notably the module instances are not yet initialized. The idea is to build a graph of modules up front, and then, and then when, and then, and then use the import hook to advance a particular module on its transitive dependencies to their final State. And this is sufficient for implementing modules and user code.
KKL: the next layer up from that would be module reflection, which is to say, hey, existing module Source Constructor, Constructor, it would be lovely if we had ability to analyze its dependencies. it's bindings and such. So the bindings array, is it corresponds to every there's an array of findings which are objects that describe each of the Import and Export statements that you see inside of that module Source such that I can write user code that goes off and fetches those And builds out a graph. And this is just reifying information that already exists when compiling a JavaScript module, and again, this unlocks, the ability to implement an import mapper in user code, for example, a node and it unlocks the ability to write a bundler since we can collect a module graph without executing any of the individual modules, and then write those into a single string that we put into it a script tag on a web page. It's sufficient for us to do hot module replacement because we can write a little note. That's reacting to the changes to a particular file and then invalidates, it's transitive dependencies using the dependency code graph that you construct from this and then and then kicks off a fresh initialization of the new route module object and all of the handoff of state that's implied by HMR. It's also possible to write a test Watcher, that does basically the same thing. It's like, hey, if anything changes Reload it, run rerun the test and then another layer up,
KKL: sources were concretely proposing at the Is likely to change that the module Constructor currently would, every layer above this module, can module Constructor only accepts instances of module Source, or potentially a web assembly module, provided that it had the right internal slots to be recognized as a module Source. How about we also be able to implement module sources in user code for arbitrary languages. This is a very, very dumb language where the text of any file. It's a module that exports, the default value 42, but you can extrapolate from here how interesting modules can be implemented in terms of this, it's just an object that tells you what its findings are and gives you an initializer, execute function and the namespace to populate. So that is to say the source does not contain any state when you initially, when you take this source and with the module instance, it would use this and past the state into its initialize function for it to populate and then, of course, use the existing in the same machinery. For import, an important matter is to apply the namespace that you get would be pre linked with all of your dependencies as described in your bindings.
KKL: and then, the final layer is evaluators. Evaluators is simply a Constructor that says: Hey, I want an eval function in module, whose content who's in terms of execution context, internal slot refers instead of to a realm, but to a new Bank of evaluators and the evaluators in turn refer to a realm. So this is a refactor changes, Nothing about existing behaviors to the language, including the notorious behavior of direct eval, which is By this where I am a single realm want to have a eval function, in module, the only difference being that the global environment records for the module environment records, in which, these programs are executed, are only able to see the properties of this given globalThis. And this is what allows us to say, hey, you “left pad”, don't get anything, you get the intrinsics that you need and nothing else. And we can make that safe by implementing our lockdown or compartment, either in a user or native code given layers 0, 1 & 3.
KKL: so, looking since this is probably the freshest for everybody, let's take a look closer at it and evaluator for a module is to say, I want to new evaluators, I want dynamic import Behavior within this group of evaluators in script context to have this particular import folk and import.meta. And this particular globalThis and then I then that gives me a module Constructor, which is bound to that set of evaluators. And with that, I can create a module that will only see that GlobalThis similarly function Constructors would only be able create instances of function that can see the given GlobaThisl disassociated with the evaluators and so on.
KKL: and the way this would look as a like, concretely, if you were to implement a DSL, like, Jasmine or Jest, one way you could do this is say, hey, I want a new bank of evaluators just for this one module. I'm going to give it a globalThis that just uses my own globalThis and provides these specialized described before and after functions and these two and unlike the current implementations of such things described “before” and “after” are able to close over the originating module and do not need to rely on Dynamic scope to discover that and can be safely executed concurrently
KKL:Which is to say at level 4, this is a depiction that contains deliberately blocked out code. I've heard that it is faux-pas to Bright Slides that have lots and lots of code because people in rooms like this cannot help themselves but read and not listen the point of this slide is enough to show you what the code is, but to show you how much it is and the end, this could be good or bad depending on what you're motivating, use cases. And that's the feedback that we care about. Do we have sufficient motivated motivation to put this into the language as a native? Well that depends on whether this is too much code to put in every index.html that emulate that has an alternative version of import Maps was a you know, whatever new feature import Maps need for your particular use case, like Integrity checks, whatever that you're willing whatever and if we had you're experimenting with ahead of a compartment compartment natively, you wouldn't have to write this. If you do, maybe it's not the worst thing in the world. We want to hear from you. For, I understand in the embedded case that it is likely that we would still want the native implementation of this because code weight matters, a great deal and having a higher level API may, we don't know, allow us to do the same operations you can with the atomic API without many reified JavaScript objects and that is stuff. We intend to explore going forward. And that with that, those are all of the layers that I'm proposing. And I have deliberately blocked out way more time than I think, is absolutely necessary for this topic. Knowing that modules are the third rail, the top, the feedback that we are specifically looking for is, is about motivation. And we intend after Two great. Have it after having many further conversations with the champions of other module, proposals to come with a much more concrete version of this with spec test text and for two at a future date, which is to say much of these details will change. We expect and yeah, I give to the floor for
CP: What do people think about splitting this up into different layers, different proposals, because clearly we can advance each of them individually. Although, we do have the Modules Harmony, where we would want to have a more cohesive idea, to plan to advance them in a similar timeframe, obviously we made the decision to explore these new layering and I would like to know what the position of the plenary is in terms of keeping it as a single proposal, or just slice it and dice it into a different proposal.
DE: So, to answer the question since I'm next in the queue, I didn’t understand this is as making it a single proposal. I understood this as a framework for multiple proposals, because, you know, other one that we heard about today kind of fits within this. And I think this is a very coherent framework and it matches my mental model of how these things could go about. We still have open questions to dig into more about whether, you know, the committee as a whole finds all of these to be motivating and I think we might eventually answer this as parts are motivated and parts aren't but still having the unified bigger picture mind, helps us to design all the pieces in a coherent way. So you know, know, great presentation.
USA: Recently something came up was, was the idea to have some process around what was called, “epics” a way to deal with a number of, proposals that are linked together, but, you know, in a productive I guess maybe this would be a good Contender for such a change in process.
DE: What do you think? you can respond to these questions
KKL: Yes, so obviously I care much more about what do you folks think on this topic than what I think. think, but the, I can that as being coherent. I'm highly supportive of the idea of epics as a process, if this were an epic, I think that this would be a part of a modules epic, not the entirety of it. And I think that it would serve as a modules Epic. very useful for and as an umbrella for this and the three other module proposals, Under the Umbrella of “modules Harmony”. And I could see this being broken up, but I also can see this as for a number of participants in our conversations, the finishing line is the only interesting line, so whether to break it up or not, Again, I defer I defer to you
USA: Yeah, just to quickly respond to that. I completely agree with you. I mean, yeah, I do respective of if we break this or not. I think it's nonetheless useful to have a epic for module harmony to link all of these initiatives together Because they have a lot common working space.
KKL: I am open to helping with this new emerging process for epics. We now have two example cases.
WH: I want to second DE’s point. I want to see how all of this fits together; it would be very difficult for me to evaluate separate proposals incrementally without knowing the entire plan of where we're going.
KKL: Thank you, strong, strong, strong agreement.
PHE: Thank you. Just kind of responding to a few of the points have been made. There's a lot of interesting work going on with modules right now. Across many proposals. I won't read today what they are looking that from an implementation perspective, if those had to be if an implementation had to implement those without guidance, from the spec, Independently. it would be a nightmare. And so I think we need something unifying. I think that what KKL has proposed is remarkably clear, given how complicated the problem space is. So I think this is a great path to explore. What WH said, is absolutely true. Like, how the pieces all fit together and how not only how these pieces fit together, but how they fit with the other module proposals, it is critical. I don't think we can pick it apart very intelligently otherwise and just reflecting on on a comment, You made briefly KKL from from Moddable perspective anyway, as one of the Originators of the compartments work, our interest is strongly and how these pieces get us to the functionality, the compartments originally proposed. I think you've, you've laid that out pretty well, but there is some work to do in some of those boxes on that slide.
KKL: Now, thank you, PHE.
CP: I want to thank Kris for putting this together in a very short amount of time. We have been blazing into this for weeks now, and this is looking pretty good.
DE: So since we have all this remaining discussion time, in past TC39 meetings where the idea of compartments have been discussed, some people expressed doubts about the motivation but KKL mentioned some things about motivation here. Are there any more thoughts from the committee?
SYG: I mean, I have doubts about virtualization at large and I've expressed this to Agoric folks. It's hard for me to make them very Concrete in response to the current proposal. I think number three on the screen gives me the most doubt, of introducing more evaluators, and consequently also number four, but that's kind of yeah, everything above 3 gives you the most doubt currently but it's very vague, right? It's I don't have to be when it's proposed. Concretely, the trade-off and the like implementations V8 will be looking at this with the trade-off that we have said, before of virtualization is often intention with complexity and security and maintainability of the underlying engine, the more bits that were not exposed to user code are now that are now exposed to user code. That is often in tension with the reliability and the Only of the software and that's a tension that will be looking and if it satisfies those tensions ostensibly, there doesn't seem to be any issue. But often those goals are in tension at something I'm going to keep in mind, going forward. Yeah so that concern still exists. But layer two down there. Seems pretty good so far.
KKL: Well I will take that too. That sounds to me like the closest I can get to a roaring endorsement from SYG so I certainly expect nothing more than that. There are a number of things about this framework. that I intend to expressly persuade such problems. One of those is carefully, teasing apart things that appear to be the same that are not like one of one of the things that's intrinsic to module the modules problem in general, is that what constitutes an origin and what constitutes an import meta url and what constitutes a referrer for the purposes of resolving a module. Specifier are often the same value, but conceptually refer to different things and have different constraints. And like just like I don't want get deep into this, but like one of the things that expecting, the web platform to come and ask for from this proposal is a for I would definitely does this. is it compatible with content security policy. is. This Does this does this platform this set of Concepts? Not all not only not break it, but do it. But very expressly supported in the cases where the host needs them. And just to give a highlight of what that looks like in Phase zero, I very clearly laid out here. There's a separation between the distinction between a module instance, in a module Source. Module sources are an immutable object and can have host data that is the origin. I posit that there's an origin of corresponds to a source and if and if in the machinery, dynamic import, it encounters a source from a, from a, from An Origin. That is not accepted. That would be, that would be a one. It rejecting such a source would be one way to remain compatible with content security policy and it's that goes on farther than that, suppose that we had some point we wanted to make this oops, it stands to reason that if a new module Source, reconstructed from a trusted type, which has behind the scenes and Associate origin that might pass to the module source and thereby allow that to be executed the same. And if we were to use a webassembly.module object, as a representation of code that had been previously imported through the static import mechanism through a host to find hook, that would be yet another way that An Origin might become associated with the module Source, such that we satisfy the requirements of import reflection, which is to say that there are webassembly sources that are vetted, but we did not pass through text and user code before they were executed, which is a completely orthogonal, kind of string even in the, even though in the base case, it is identical the import meta url on the web specifically and even though, the import meta url is identical to the referrer on the web and and which is to say, there's, there's a danger that, if we conflate these ideas that the referrer might be given responsibilities that are normally conferred upon the modules of the module sources origin, which it cannot fulfill If it's virtualized, able was used to say. If it's spoofable. And that's that's that's one of the important layers the distinction. Is that a module instance can have a referrer and that refer may be coincident with the origin but it might not, it can it can be changed, and that's important, right? Because a module, logically has no location. No physical location and that's important because it might be in local storage. The text might be in local storage. The text might be compiled by code in a moddable embedded device. It might be, it might be in a bundle. In which case having an import meta url to the extent that import meta url is useful. It is useful for a finding adjacent assets relative to the source location wherever it physically exists. And that is useless for bundled code. Since we're physically exists is a large string and and doesn't correspond at all to where it originally was located in, in the physical medium from which it was built. So decoupling these Concepts. I think creates a framework for understanding Security in way that we that, I hope web platform and other hosts are, are satisfiable with. And in the fullness of writing spec text.
CP: To add to that SYG. It's important to highlight, (and I think KKL has a slide for that), that the layer zero is the absolute minimum building block that we can use to build on top of in order to create something useful there. So I would say that we need layers zero and three. Absolutely. While I don't care much about layer one. As for layer two, we can defer it to the Host just like we did were discussing in the prior conversation about WASM, you can get the Host to create those Module Sources for you as an avenue to continue adding new type of modules, but we believe that given the developers the power to create a namespace object, (basically, that's what this layer gives you), that will cover a lot of our use cases and we have this is a vibrant over correctly. We have been talking about this for ten years now, when we were working on the loader API, when Dave Herman was pushing to have these particular features to be able to set the binding’s value in a namespace object that you create yourself and so on. It does open up a lot of new ideas and new opportunities for people to control part of the module graph. But without zero, none of these will really matter.
KKL: There's two answers to that CP and I carried a line I intend to have long conversations about this particular slide order to get it into and do what we believe is a copacetic State. I think that there is there are multiple ways of understanding how to do this That are analogous to the difference between promise to defer versus The Promise Constructor that might make this easier to easier to accept one way or the other. There's an equivalent version of this where you say, Where there's like a Constructor function that receives an array of bindings and returns an entangled set module instance, module Imports, namespace module, export namespace, such those different properties could be used for different roles. Like the Imports. Namespace would be used by whomever is implementing the internals of the execution, the exports namespaces, the object that we're already familiar with and the and then the module instance, object is one that we're proposing. Phase zero or is representing the life cycle of a module, which would be functionally equivalent to this except that it would not introduce, it wouldn't put us in a position where the module Constructor is responsible for reifying the ??? at in my feeling its equivalent and I'm open to that kind of API Evolution.
SYG: I have a question for CP the he said, 0 & 3 were absolutely necessary absolutely necessary. So forth, three the evaluators It's you find that motivation to be ins absolutely necessary for the same. for limiting, the supply chain attacks.
CP: Number 3 (layer) is necessary for compartments. If you don't have that you don't have compartments.
SYG: Why compartments are necessary for you?
CP: It is not! The original proposal from Agoric was to provide a compartment API and I think modable was probably pushing for that too. In order to have good evaluators, you need to have layer 0, which allows you to create module instances and link them together.
KKL: Is it fair to say that what your that a rephrasing of what you're saying? CP is that assuming that compartments are well-motivated. Compartment is necessary to have zero Players is zero and three to construct them.
SYG: Yes. Okay. I understood that part that's that's that seems to be The technical bit of like that seems to be just true. I'm saying three gives me three and four give me the most pause and I guess I misunderstood I thought CP he was saying for his use cases. Compartments are also necessary.
CP: Oh okay, I thought you were saying that you were okay with three or four but you were hesitating on the other ones, so I was confused. Yes, about compartments, we have talked about this already, I don't think we necessarily have to have it in the language, I’m talking about layer number four, because you can construct it in user land and yeah, it's complex, like 100 lines of code.
DE: So fundamentally, I think the term evaluator might sound scarier than what we're talking about. To me the the content of an import hook. Which it sounded like you were Okay with SYG is is a lot more complicated than the concept of being able to substitute the global object. I mean substituting the global object in a free-form way as in slide 3 may be excessively expressive and it may be sufficient to have an object whose properties are copied over for a lot of these use cases, but it makes sense that if you want to isolate a piece of JavaScript code, you want to just give it different global object. To be able to do all the evaluating it. Otherwise you have to use weird with
based tricks to hide the old global object. That's that's a fundamental concern.
SYG: <<No microphone used>>
DE: And I don't see, I can see why import hook might be difficult. But it's hard for me to see why a new global object if the object is allowed have so, yes for use. If I think the reason that you want to have a different global object is kind of straightforward that if you have the same global object, is the enclosing one or an entirely new ShadowRealm, that's kind of both of those might be using the outer global object implies too much sharing and using a shadow realm might imply to little sharing for certain use cases.
SYG: So there was a reason we pushed for shadow Realms having that built-in very strong built-in cut off. And if we were to relax that by evaluators, that gives me great pause because the arguments there have not changed.
KKL: Oh, so the to address that particular point, there is an important distinction with evaluators, the intrinsics are not different. Intrinsics would be shared on this proposal
SYG: so I guess we didn't do that because people wanted to, like use cases, cases, we heard, but people were very Excited to use Shadow Realms to run on trusted. Third party code and we try to explain. Well, it's very difficult. by “we” I mean Chrome here V8 and some of these excited users were internal to Google and external to Google. I'm going to try to explain well, like experience has shown that it is difficult to correctly. Cordon off and an inner thing, but we recognize that you want to do Of in this therefore to better. like very hard boundary that you literally cannot entangle the object graphs and if you were to do this now with evaluators I'm not sure what of the arguments have changed to make that.
CP: Okay well my understanding is that this is about multiple Global objects that are ordinary objects under a single realm.
SYG: So when you mean the supply chain attacks before a warning, like, people are using this with some expectation of isolation. This is going to be very difficult to get, right? If it begins on them, configuring it correctly.
KKL: Yes. So yeah, you are correct. It is not easy. It is possible and this compartment is necessary, but not sufficient in order to achieve that ends, but those ends can given the When the existence of an evaluator is primitive in the language. It is possible to create such isolations, get entirely using user code,
SYG: is a not possible to do that today with anyway, sorry
KKL: this is it is with shims as with all of these
SYG: I don’t want to get too much into the weeds can be done with for that particular hook,
SYG: but I think I've said my piece on my concerns about the motivation for layers, three, and four. And that DE is correct that I that I also have concerns about the import hook but without reading something concrete, like I there, I agree more with the motivation. I see how you might need an import hook and yeah would need to work together to kind of strike the right balance for the expressivity and see what the cost is, but I have less concerned, they're worth like fundamental experts. That's the fundamental motivation of that. But yeah. Needs to, you know, there's like this is making programmatic a bunch of capability that kind of exists in a declarative way in the web platform with import Maps, maybe doesn't quite what you want to do. Be nice to have a programmatic. I understand if everything plays nice and then it works out, it seems okay.
KKL: Again, that that is as close as I could ever hope to receive in terms of roaring positive feedback.
MM: I think there's everything that KKL said is correct but without but there's a particular concept that I think needs to be mentioned, needs to be explained in order to address the objections, that SYG is raising, which is that we know how to, in user code, freeze all the primordial Zone we have been very careful in TC39 to keep any hidden State out of the primordials and to keep any hidden powers out of the primordial. Those so when when KKL and CP and others as Well, as moddable and MetaMask all, say the compartments Can can compartments or evaluators that enable us to build compartments can be used for isolation, If you don't freeze the globals then everything SYG says is exactly correct. It is completely incoherent to use compartments or evaluators as a isolation mechanism with any interesting guarantees if they're they're all sharing same primordial. And those primordials All as mutable as they start out, so it just want to clarify. That what we found is that in building shims walking all the primordials down ourselves, is not that painful, and therefore, that's part of what we have in mind when we talk about actually using this as an isolation mechanism in user code. And using it for in particular least Authority linkage for dealing with supply chain attacks. And Realms are realistic for least Authority linkage of packages with each other in order do to give them separate initial authorities. because having packages assumed object contact, operating through realm boundaries is going to be more pain than we will typically want to bet.
KKL: So with what this concretely looks like, terms of an implementation is that given the existence of an evaluators primitive if you wanted to isolate a particular module such that, it did not have the ability to reach any powerful mutable objects as you would construct, a global object for the contains only Frozen ,deeply, Frozen intrinsics, and any powers that you expressly wish to granted.
MM: So SYG. Does that clarify the how your concern meets the the what you've been? Hearing
SYG: it clarifies it. I'm not sure it necessarily moves my thinking very much like I it gives me a better picture of how you are thinking about using zero and three, and four to correctly Guarantee Supply Chain at to, to mitigate to, to mitigate. And to limit the blast radius, as you said that technique, like to be clear, I have confidence you MM and in you KKL and SES folks to write the right thing, to have them to do all the things. What I do not have confidence in is like and the argument for back and Shadow Realms, what was that? It becomes if we make something, if we have an API that entices folks to do something like isolation and we mean very particular kind of isolation that we understand how to reason about we entered into how to write but we depend on them having the right kind of understanding. And we do not believe that. It is easy to get, right? We have concerns about that.
KKL: That makes sense.
SYG: And, and for the like, if you believe that freezing is the way to go here and this I'm remembering, you know, Frozen Realms all the way back, you know, maybe this is a resurrection of that like if we can massage it in such a way that like the foot gun concern is addressed that might work but you know, that's me being obviously optimistic
KKL: so let's suppose that that what that would look like and run that by you, that would look like not exposing evaluators and instead which would throw away the just use case etcetera but that's immaterial it would look like instead of providing compartments but only after providing a lockdown which is to say Notifying a lot more in 262 in order to chief, that happens.
MM: so yeah, I'm first curious to whether that helps address SYG’s concern here. So if we added to the set of mechanisms being proposed here part of the Epic, If part of the Epic was what hardened JavaScript calls ‘lockdown’ that does freeze all the primordial? After doing some very, very specific surgery on them that we have found to be widely compatible with existence code. This is, by the way, lockdown and compartments are part of what XS is shipping and as built by Moddable.. The model validation moddable shipping lockdown and compartments as built into the engine. Agoric has a full implementation of both in the Shim, the certainly, in our anticipated, use, we would anticipate on whatever platform using all this valuation. Compartment mechanism with lockdown. If lockdown is sort of the missing element, for which I, which I that it is actually missing element for how to use evaluators and compartments safely to achieve isolation. If lockdown were included in the bag of proposals were calling module Harmony. And if they were expected to be part of the Epic with that address, The concern?
SYG: It’s hard for me to give the affirmative now. I’m thinking is like, I'm thinking of that part to be orthogonal. Two layers 0, 1 & 2, Which address problems there. Say that. Don't that there are different from like, so I'm not sure why they would be part of the same epic. I'm interested. Like, I will be fine with pursuing that other thing. lockdown, but that seems to be a pretty different use case than what that market.
MM: Ok, I can see that and it's there. I wouldn't say there are fogging all but, but what I would say is compatible with you just said, which is there's dependency layers 0, 1, and 2 have no dependency on layers, 3 & 4. And the Synergy between this and the other module proposals such that we were thinking of grouping module Harmony together into an epic. That synergy is with layers 0, 1 and 2.
SYG: Fair enough. I think DEDE has a response but then I'll just I'll quickly say, then to come back to DE’s Original question of do other stakeholders here, have motivation concerns well, look the use cases in the motivation for three and four seams sufficiently different to that Like the trade-off space. There are not quite the same as the trade-off space that what we're thinking about the module for, like the module blocks, the import source to, sorry, did the module Source stuff you presented, the wasm use case that deferred import use case like the same sufficiently different me that I have less motivation concerns there that I have with the other stuff that we all have. We spent the last 20 minutes talking about the trade-offs in the evaluators and the compartments use cases. I'm not, I don't have a clear enough thinking on it yet to really say to MM, like if we do this, are you okay with it? There are top of my concerns that came up with Shadow Realms that will come up again. That was the, that was the particular one that I talked about, but there could be other ones. So that's very hesitant to say that. Like, yes, we will help pursue this. At the end of the day we'll be looking at it from an invitation complexity perspective, will be looking at it from like the experience, the user experience. The web DX of How likely people to get it, right? Like those are some of the criteria will be looking at and those aren't yet clear to me for three and four as they are as how clear they are to me for 0 1 and 2.
MM: Okay. number three also did have another motivation which KKL mentioned in his slide show. I'm just wondering what your reaction is to that motivation. which is because it's not an isolation motivation. It's the the I saw motivations the factors. There's all these separate Frameworks that each like to populate the global with things to be used when you're using the framework. But that the the framework is for operating on code, that should not see those on the global, the code being operated on should not see those same things its own Global, and the evaluators does accommodate that without any isolate without any Claims due to strong isolation.
DE: yeah, I find the mocking or virtualizing the global environment use case very important. It's been difficult to migrate test Frameworks to ESM and I think we can. I think we can take SYG’s constraint and think about this with Shadow Realms. We ended up in a place that none of us were really thinking about initially and I think we can. Be creative. I think a lockdown-only version wouldn't wouldn't meet this of virtualizing the broader environment. So we just need to step back and think hard about the space.
KKL: I like what you said and about the function of an epic, I think that the function of an epic is to allow us to co-evolve multiple proposals such that such that any individual proposal does not preclude a later proposal in that layering and to that end having these features at the end of it is although they might Advance separately having them in the same epic in order make sure that a change of the lower layer does not preclude. thing that occurs in another layer is, I think a useful function for epics How's the cube?
RPR: So I'm glad you're talking about epics on modules. I think there's more value to come from modules. And we've talked a bit about virtualization and the benefits there for isolation. And the benefits for flexibility. And DE & MM referenced developer productivity - cases of using test Frameworks and so on. I would say if we're about to do a big push on modules, to make them great in the spec, the elephant in the room, or the elephant in the spec, with modules, is that at the moment in the industry, if you look at the main place where JavaScript libraries exist, which is npm, if you look at the main runtime that people use on the server side, which is node, there adoption of ES Modules is very small. It has been very slow to make progress and even just maybe in the last month, there was a thread on the Node project of "shall we recommend that developers use ES modules in future?" and they weren't able to come to the answer of "yes". So I feel like if we're going to put some work into making modules great, it would be very useful if we can connect with the node community and see if any of the things we're proposing might lead to a greater industry uptake of modules.
KKL: Yes, absolutely. One of the one of the things that we've been up to, for the last two years is answering the question for ourselves is: do compartments provide a bridge from commonjs to esm because that is what is missing is well there are a number of bridges, not all of them are the same. Not all of them work in the same way, but for but the idea of making a sufficiently large subset of existing cjs usable as a transitive dependency of an ESM project in a meaningful way. For the cases where it makes most sense which notably are not just running on the back end but also running on the front end and what, what we've done at Agoric and with help from fromfolks at MetaMask consensus is build an object at the number of number of the layer 3. Even number two here, that allows us to make an opinionated and opinionated binding to CommonJS. that allows most common J's and we've been working to maximize what we mean most, for to participate in this particular loader and the neat thing about this loader is that it's an ESM loader, which means that it's asynchronous, which means it depends on. It depends on the static and of the, the aesthetic, analyzability of the module and common was Is intended to be statically analyzable to the extent that that was useful. And it doesn't matter what we intended or what we wrote in the commonjs spec, which does say that the argument of require must be a string. No one has to follow that rule but they do have to follow that rule. If they have a prayer of using browserify, or webpack in their library. And so there's been this sort of like, you know, like the moon's that make rings though, the shepherd's rings as a there. Our the the bundling ecosystem is a Shepherd for the commonJS's. Ecosystem that puts it in a position where the vast bulk of common J's can be loaded in an asynchronous loader and then bundled in the captured and Etc and statically analyzed. So we took Guy Bedford's lexical static analysis, tool for that he built for node extended it, so that it can do the thing that no doesn't just to say, analyzing the Imports as well as the exports, to recap. Guy wrote a tool that does a static lexical lexical. Analysis of the commonJS module in order to figure it out, its named exports. So that name that exports can work better node more like what you can get with Babel and node because it's using a synchronous common JS, loader that. Cannot break off from choosing not to solve the import side, but we decided to take that and extend it so that it can do the import side and have commonJS is a narrower subset commonJS, Admittedly, that's able to participate in this framework. And yet again that depends on the ability to virtualize. third-party module types. And the nice thing about doing it in a way that is defined in user code instead saying, hey, We need to bring commonJS into 262, which I would never say. It is a taint that we do not need to bring into these halls. We do need a way to make. We do need a way for specific applications to make decision opinionated decisions about what subset of the common JS Ecosystem, they want to lift into the ESM ecosystem and this framework allows us to us to do that.
RPR: Yes, I think my two points here are that, we should reach out and see if that proposal can address that gap. And if we find it does, then I think that these proposals may then have significantly more value to the community and more people will find them compelling.
KKL: Absolutely, so it doesn't if forth for the record we would very much like to produce a to involve folks from who are involved. And in in the evolution of the node.js node.js module loader, GB himself, who has joined us among the co-champions four compartments and it's also a champion of other module Harmony proposals and we need, we need their voices.
JHD: Yeah, definitely reaching out. Always good. There's a lot of opinions out there many of which contradict and it's good to get a sense of them all to try and paint a better picture of what things, what the real problems are. There's some things about this proposal that may, if they can be implemented in a performing enough way, may make the state of native esm in node. in particular better and that alone will remove some blockers to adoption. there are a lot of reasons why esm adoption is very slow in node that are in perspective opinion unlikely to change in the coming decade. So you know, the in particular I think one of the biggest one is the inability to require esm into commonJs because CGS is synchronous, and esm is asynchronous and all the attempts in TC39 to try and work around that, were rejected and or did not succeed. Or however, you want to phrase that so I would love to see that address my personal very strong ideology is about backwards, compatibility and interoperability and not that I have any particular love for commonJS over ESM, but the current state of things is not Encourage ESF adoption, which is why I knowed like collaborators raise that question, I think I'm not
RPR: I’m not sure we fully done everything we could to help help Node in that respect.
JHD: So so, yeah, I guess it's just the it's the optimism of let's let's try and see what we could do. Yeah. As I totally agree with doctors and if it turns out that we discovered, that these this collection of layered proposals, I'm avoiding the word epic because that gives me ??? and Nightmares that this collection of proposals actually helps that problem. That's awesome. If instead we find out that different proposals would solve that problem. I'd love to explore that as well. The reaching out the important part in trying to figure,
KKL: we could call an Epoch have it right next to temporal. The yeah. Agreed. I think that they're, like, if going into a very deep conversation, very briefly, I think that there is a possible way that This, this framework could be used to ameliorate the issues in the node ecosystem. in particular, that you can only go down from asynchronous to synchronous and is a huge problem and I think that is and while in the node ecosystem, I think that this would be distasteful but it is a let me propose that. You need not have a single that there need not be a single solution to CommonJS and the environment. You could have a layer that preserves backwards compatibility for the foundation of know, that are built on commonJS at the and then, on top of that, be able to bring one of those into an ESM loader layer. And then have that the esm loader layer, a parallel of common JS modules. And if I know anything about the node ecosystem, its appetite for having multiple instances of the same module is not zero at least.
JHD: Yeah, we've discussed that a couple years ago in plenary and like we were looking at like zebra, striping techniques and other things and because the ordering of the graph The ability to satisfy existing use cases in such a mixed graph, with was a presented, a very large challenge different data. Yeah. And I remember AWB response to those like, ??? at the esm, what belongs to ESM. I don't think it's realistic have a flag day for JavaScript.
RRP: My final point on this, which is that we solved this for Node, not only is that compelling but I am fairly sure help other runtimes too.
GB: Yeah, I think it's a great point and definitely there's a huge amount of room to establish that back-and-forth communication with TC39 and node more than we have and ensure that we're solving some of the problems. a lot of the discussions on node parallel, a lot of the modules discussions that we're having here and that's quite interesting that you know, this kind of hole all these things were working on it with this module CPR. if that's what we're calling it, it's a lot of these features do brush up against some of the current pain points in node, which is what I just wanted to bring up. One thing that comes up quite often is that Jest isn't very easy to compatible because they use nodes vm.module which basically replicates the V8 module API which in turn pretty much follows the spec current spec and that's very difficult to use. so users don't always get it right. And if they were better, virtualization techniques like we're working on, then nodejs could benefit hugely from a lot of the questions are about virtualization and these kinds of things and instrumentation. So furthering, those discussions could be very useful to build alignment and then also I'm sure there was another one, I've completed the government so I'll leave it at that for now. Yeah, but yeah.
RPR: The point on jest yes,
KKL: You mentioned instrumentation. suspect that the layer number 2 that is the third layer. I really should not have used zero. is would be useful to the end of instrumenting esm. But what to say that you could construct a module instance, knowing the bindings of another source and created an adapter.
CP: So the way I see these is when it comes to solving the interoperability issues. You probably can go very far when coming from CJS point of view, with layer one reflection mechanism. This is up for discussion. Obviously, we need to include the ability to access the hoist functions that are declared as export values. You can get very far but we haven't got to that part of that discussion. It's okay, okay. That's interesting. You will still need to figure out what to do with the TDZ though. You can use layer one from CJS and get very far. In the case of pulling from ESM, importing from commonjs, you definitely need layers 0 and 2. You have to be able to create virtual modules that represent whatever the exports saying that you have. You are only going to come halfway there because obviously if you have values that are set onto exports later on, they are not going to be qualifying. You still get very far with these three layers, I believe. And that's why we have been pushing on getting these things nailed down on these three layers that are the most important because they create a foundation for a bunch of other things.
SFC: Yeah, my comment regarding the question about ESM adoption. One problem that's that I've been experiencing a lot, and you can also talk to my intern Quinn about this, is WebAssembly ESM. LCA's proposal that was presented earlier is, I think, a really big step in the right direction. But there is not currently a module loader that does a very good job with WebAssembly. If ESM would be the standard for how you should do WebAssembly modules, I think that would really drive adoption, because that's currently a pain point. And if we can solve that pain point, I think that would be a nice thing to focus on as a priority.
CP: There's the side note on that, we're really not shooting anymore for a loader. The way we think about that, (at least the way I'm thinking about it), It's like we have been struggling for 10 years try to create a what I call it a parameterize artifact or parameterize API that allows you to do everything and we're trying to escape that trap by conforming to a low Level APIs that allow you to construct whatever artifact you want that can act as a loader in a cohesive way for a module graph or a segment of it. Just as a side note, there is no such thing as a loader anymore.
KKL: Suffice it to say. I agree that that participation from people in the webassembly community in this process would be extremely helpful for helping that Motivating Use cases. and I think it's possible that it would come to a very fortuitous outcome
USA: Yeah. With all this talk of this sort of replacing CJS with ESM, I want to be a third what I believe RPR saying which is that potential solution here should probably try. It's best to play velvety JS. Otherwise, it would come at a huge cost of ecosystem disruption. which would make the lives, at least in the moment of node.js developers very difficult. So, yeah, we have to accept that CJS is going to stay in some way or another and that we should play well with it rather than ignoring that it exists.
KKL: As a perpetrator of that particular sin, I agree. I think that, I think that when folks think about migration it's compelling to say that we jump directly into the pure perfect world, the reality is that in order to get rid of something, you first must create the bridge that allows you to tolerate its existence forever. So, my hope is to create that bridge then allow the community to gradually migrate away. There are a whole bunch of wonderful things happening in the system. To that end, like creating packages that can that can be sourced in ESM and then linked as commonjs or esm. And, and sometimes those even provide the same interface that it's relatively straightforward to, to shift your dependencies from leaning on the ESM or commonjs, systems for selecting, which is, which are beginning to exist as well? I'm optimistic that we'll get there even as horribly complicated as it is to create a package that satisfies both esm commonjs today.
RPR: And you will finally pay your debt.
KKL: oh God, that would be impossible
JHD: And I just want add for package authors primarily in the node, ecosystem, the thing you have to beat isn't cjs for sorry. Sorry, this is because CJS can consumed by ESM. ESM can't just be as good in order to be worth the migration it has to be better enough to overcome the inability to be used by CJs tools. or it has to be able to be. So like that's the bar it's being caused. Because like you're actively excluding the largest group of users. If you ship esm only and the numbers prove that out,
KKL: this feels like a strong case for the layer. Number two, as motivator,
DE: Yes, let's keep making incremental improvements.
KKL: Absolutely.
CP: The more practical question, this mostly for KKL, I guess who have the ones we start progressing on. These will have different specs for each of these layers in the same repo or different repos?
KKL: Let's discuss that at a different venue. I think that we'll need to come to a decision about whether to break this up or not.
KKL: Thank you, everyone for participating in this conversation and I hope that gave some time back.