00:12 | <yusukesuzuki> | btw if anybody else didn't get added to the Tokyo 2024 channel, please do speak up! |
00:44 | <Rob Palmer> | Has anyone dialled in yet? |
00:45 | <rkirsling> | Oh! Could you add me too? Thanks! |
00:46 | <yusukesuzuki> | Oops! Thank you!! |
00:50 | <Rob Palmer> | We are prepping to start. If you wish to help, please sign up to a session for Note Editing! https://github.com/tc39/Reflector/issues/537#issuecomment-2394180693 |
00:54 | <Rob Palmer> | The Teams call is up! Please rember to NOT sign into Teams itself. Join the call as a guest. |
01:27 | <littledan> | We have 4 slots for non-ordinary members in ExeCom |
01:27 | <littledan> | there are more slots than current members. I encourage everyone to join! |
01:32 | <shu> | Chris de Almeida: the wintercg vote |
01:34 | <Chris de Almeida> | shu: maybe DE can elaborate, but my understanding is that they are going to fully move to Ecma, rather than have the split of the CG vs WG |
01:34 | <Chris de Almeida> | the IPR concerns were due to doing some things in w3c and then some things in ecma and that was problematic |
01:34 | <shu> | last time that move was voted on and the vote failed due to IPR concerns. i am asking a clarification on what has changed since then |
01:35 | <shu> | because what i hear internally is "it's pending legal review", and aki's presentation makes it sound like it's a done thing |
01:35 | <canadahonk> | I can talk on this if people want |
01:35 | <canadahonk> | shu: maybe DE can elaborate, but my understanding is that they are going to fully move to Ecma, rather than have the split of the CG vs WG |
01:36 | <littledan> | If you're interested in the founding documents, please let me know and I'll send them to you. I've already sent to Chris Wilson and Tantek Celik, in addition to the Ecma ExeCom. |
01:36 | <shu> | specifically i'm wondering are you doing the thing where you're sending all the contributors IP transfer documents or whatever |
01:36 | <littledan> | specifically i'm wondering are you doing the thing where you're sending all the contributors IP transfer documents or whatever |
01:37 | <shu> | is that thign pending legal review from the original folks who raised the IP concerns |
01:38 | <littledan> | is that thign pending legal review from the original folks who raised the IP concerns |
01:40 | <shu> | i'm assuming at least mozilla and google legal |
01:43 | <bakkot> | fwiw the audio sounds fine on the call |
01:45 | <Aki> | Someone wanna drop that screenshot of TCQ questions for me so I can answer them here? |
01:46 | <Chris de Almeida> | we shouldn't paste here |
01:46 | <shu> | (mine was answered in the chat just now) |
01:47 | <canadahonk> | Someone wanna drop that screenshot of TCQ questions for me so I can answer them here? |
01:47 | <Aki> | Chris de Almeida sent me the screenshot (thanks!) |
01:48 | <Ashley Claymore> | Ben: when you get a chance could you add a slides link to the agenda |
01:48 | <Ben> | Doing now |
01:48 | <littledan> | suggestion for Mozilla's concerns about being able to review the agenda: We require all agenda items to be added before the deadline, unless there is a particular "emergency"/reason for why the addition was delayed. We strongly encourage slides, repos or other supporting materials to be added to the agenda before the deadline or soon after it, with their contents done as early as possible. |
01:56 | <yulia> | the suggestions dan made above (slides & content must be available) makes a lot of sense. I would also suggest (to avoid issues in the future) that we move the deadline to 14 days (in line with ecma), and we have an indication of the amount of work (in hours) so far added to the meeting. We can't approve what we don't review, and we want to make sure that the output of tc39 is as high as possible. I think that is a shared goal. If we can plan our meeting a bit better I think it would help. |
01:57 | <yulia> | I am not sure if many delegates are reviewing all proposal before the meeting, but it is a requirement for us as implementers, because if something lands and we didn't really think about it -- we are left holding the bag |
01:57 | <Chris de Almeida> | Ecma rules say 21 days |
01:57 | <ljharb> | fwiw those suggestions are already the case. supporting materials that aren't in by the deadline allows for procedural blocking |
01:57 | <yulia> | ah my mistake |
01:58 | <littledan> | we've confirmed with Ecma in the past that TC39 may adopt its own deadline (otherwise I would've worked on getting the rules changed). But 14 days seems reasonable to me. |
01:58 | <shu> | at least for proposals 2.7+ i think an earlier deadline makes sense |
01:58 | <Aki> | yeah i was having a conversation the other day about this and surprised to discover TC39's deadline was different from Ecma's, i totally forgot |
01:58 | <yulia> | the current 5 working days that we have to fully review all of the proposals was not enough |
01:58 | <ljharb> | i'm not sure how we could calculate how much review work is needed, because it won't correlate with timebox time |
01:59 | <ljharb> | i'd assume the largest review is needed for 1 → 2 or 2 → 2.7, and the smallest for a stage 0 → 1 or 2.7 → 3 or 3 → 4 |
02:00 | <shu> | i'd assume the largest review is needed for 1 → 2 or 2 → 2.7, and the smallest for a stage 0 → 1 or 2.7 → 3 or 3 → 4 |
02:00 | <shu> | so at least in terms of irreversible consequences |
02:00 | <yulia> | yeah 2->2.7 is the biggest, that means that things that are not that, end up getting the short end of the stick |
02:00 | <ljharb> | so given that, requiring an earlier deadline for attempting to enter 2 or 2.7 might make sense (no need to require it for the others) |
02:00 | <bakkot> | fwiw I also did not notice that the agenda item contained "TG4: Source Map Specification, 2024 edition approval (30m, Jonathan Kuperman)" |
02:00 | <bakkot> | mostly because I do not look at the task group updates section |
02:00 | <Chris de Almeida> | I don't have strong feelings on this but I do not want a complex rules engine for which deadlines apply to which stages |
02:01 | <yulia> | same, i would say just an earlier deadline allowing more than 5 days of review time |
02:01 | <shu> | then we probably do want to move the deadline up earlier for all proposals |
02:01 | <littledan> | I don't have strong feelings on this but I do not want a complex rules engine for which deadlines apply to which stages |
02:01 | <Chris de Almeida> | +1 |
02:01 | <ljharb> | we have never had a deadline for non-advancements and i don't think we should start now |
02:01 | <yulia> | i believe we are only discussing advancement deadlines |
02:02 | <Chris de Almeida> | I think it would remain a 'best effort' thing, not a 'you missed the boat, sorry' thing |
02:02 | <ljharb> | the word "deadline" refers to the latter ime ("dead" being a somewhat final state) |
02:02 | <Chris de Almeida> | but it's very helpful if everything is in before the given date |
02:02 | <littledan> | well, I raised non-advancement-requests, but I can accept if we don't adopt the policy that I suggested |
02:02 | <Chris de Almeida> | and the later things get added, the more problems it creates |
02:02 | <yulia> | yeah, with the risk of something beling blocked -- i mean it would be the same situation as now, but with 2 weeks (10 days of working time, if there are no holidays) would go a long way here |
02:03 | <littledan> | adding something to the TC39 agenda is asking everyone to take time to focus together on a topic, so I think it's not too much for it to apply to everything. It will help us to be more effective if we have all supporting materials for all items ahead of a deadline. |
02:03 | <ljharb> | part of the reason we wanted to keep the deadline short in the past is that there's only 2 months between plenaries |
02:03 | <ljharb> | those extra 4 days have been very helpful in the past to get ducks in a row for an upcoming plenary |
02:07 | <yulia> | That said, since we meet so frequently, spilling over to the next meeting isn't a huge delay. |
02:07 | <rkirsling> | fwiw I also did not notice that the agenda item contained "TG4: Source Map Specification, 2024 edition approval (30m, Jonathan Kuperman)" |
02:07 | <ljharb> | 2 months is a significant delay, but 4 days doesn't seem like one to me |
02:07 | <rkirsling> | like, 30m topic in the 5m topics section |
02:07 | <Ashley Claymore> | Current doc for advancement to Stage 1 says:
|
02:07 | <yulia> | the time taken in those 4 days, vs incomplete review and missing something, the cost of the latter is much higher |
02:08 | <Ashley Claymore> | maybe we should make that should a must |
02:08 | <littledan> | those extra 4 days have been very helpful in the past to get ducks in a row for an upcoming plenary |
02:08 | <nicolo-ribaudo> | I'm not following the chat, but if it's for source map: it would be a 6 months delay and not 2 months, due to the GA meeting twice per year |
02:08 | <rkirsling> | maybe we should make that should a must |
02:08 | <Michael Ficarra> | maybe we should make that should a must |
02:09 | <Aki> | I'm not following the chat, but if it's for source map: it would be a 6 months delay and not 2 months, due to the GA meeting twice per year |
02:10 | <littledan> | overall, the wording in the agenda doc has encouraged people to not bother to especially try to get things into the agenda ahead of time, even when they maybe could've. It's been confusing for me to explain to people that they really should put everything there earlier, and I've had to clarify that lots of times. |
02:10 | <nicolo-ribaudo> | littledan Btw, the reason we were thinking about the license for the spec itself, is that both ECMA-262 and ECMA-402 are published under Ecma's BSD version |
02:15 | <littledan> | littledan Btw, the reason we were thinking about the license for the spec itself, is that both ECMA-262 and ECMA-402 are published under Ecma's BSD version |
02:16 | <Chengzhong Wu> | do we have a slides link to TG5 Report? |
02:17 | <yulia> | https://docs.google.com/presentation/d/156wJbnrIEt-hbkhh0paVAIjrG9L7oe_R9z211yS0bIA/edit#slide=id.g308ab6c6cfb_0_25 |
02:17 | <bakkot> | yulia: would you put a brief summary of the TG5 presention in the notes? there's a spot for it |
02:18 | <bakkot> | I could generate one but it's best if the speakers do it |
02:18 | <littledan> | I could generate one but it's best if the speakers do it |
02:18 | <bakkot> | yes |
02:23 | <bakkot> | I strongly agree with Michael's point that we should never switch on iterability for any reason other than to throw for non-iterables |
02:23 | <rbuckton> | auto-wrapping is a footgun that required a special symbol to workaround for Array.prototype.concat. We shouldn't repeat that mistake |
02:24 | <ljharb> | that isn't why isConcatSpreadable exists, it exists so DOM NodeLists can explain their special array concat behavior |
02:25 | <keith_miller> | I thought isConcatSpreadable existed to make me suffer as a new hire :P |
02:25 | <ljharb> | iow that symbol is not relevant to this proposal, whether it autowraps or not |
02:25 | <rbuckton> | It also likely wouldn't have been necessary if Array.prototype.concat did not have the auto-wrapping behavior |
02:25 | <ljharb> | that too! |
02:25 | <ljharb> | someone made sure that "make keith suffer" was redacted from the notes |
02:25 | <ljharb> | it would still have been necessary. |
02:26 | <ljharb> | because NodeLists aren't arrays and did have special concat behavior |
02:26 | <ljharb> | without the autowrapping, NodeLists would have thrown instead of been added without spreading |
02:26 | <rbuckton> | Either way, auto-wrapping is a footgun. it also doesn't align with our recent decision to cut back on coercing things |
02:26 | <ljharb> | but NodeLists spread, thus the symbol. nothing to do with autowrapping whatsoever. |
02:27 | <hax (HE Shi-Jun)> | What's the special behavior of NodeList? |
02:29 | <hax (HE Shi-Jun)> | Either way, auto-wrapping is a footgun. it also doesn't align with our recent decision to cut back on coercing things |
02:32 | <nicolo-ribaudo> | As a committee, we should adopt the principle of "making it hard to accidentally do the wrong thing". When user intention is ambiguous, let's ask users to be explicit |
02:33 | <littledan> | In TC39, the bare minimum is "web compatibility", which is a much weaker property than "breaking change". As Jordan explained, basically anything that we do can be considered breaking. |
02:36 | <Bradford Smith> | Iterable helpers that flatten their arguments are implicitly branching on iterability and likely to be used a lot in future. |
02:38 | <bakkot> | which iterable helpers flatten their arguments? |
02:39 | <Bradford Smith> | Maybe my memory is faulty. I thought there was at least one API that did this. |
02:39 | <rbuckton> | IIRC, Iterator.prototype.flatMap does not coerce non-iterator/non-iterable |
02:39 | <bakkot> | it rejects non-iterators |
02:40 | <rbuckton> | If you consider Iterator.concat to essentially be (...args) => args.values().flatMap(x => x) , then we should also throw for non-iterators |
02:41 | <ljharb> | in general as well, something being iterable is a massively impactful "trait" of it - something changing between being "a thing" to being "a container of things" isn't and shouldn't be a common thing. if we're talking about good API design, good API design wouldn't make this change, i'd think |
02:42 | <bakkot> | If you consider |
02:42 | <bakkot> | accepting iterators turns out to get really awkward |
02:42 | <bakkot> | because you have to take responsibility for closing them |
02:44 | <rbuckton> | I'm not saying it must be implemented as such, but a naive implementation using flatMap would throw, not coerce. |
02:45 | <ljharb> | that naive implementation would eagerly exhaust the iterators, which this doesn't do |
02:45 | <rbuckton> | Again, I'm talking about consistency. Iterator generally doesn't coerce |
02:46 | <ljharb> | true, that's what Iterator.from is for |
02:46 | <rbuckton> | I'm not concerned, there are plenty of bad API designs on Array we shouldn't carry forward, even if we carry forward the concept to other APIs |
02:46 | <Justin Ridgewell> | @ljharb very weakly yes, but I got over it quickly in Rust |
02:47 | <Justin Ridgewell> | Used a whole bunch of once(foo) , but it’s much easier in JS because you can wrap in an array without screwing with types. |
02:47 | <rbuckton> | For instance, iterator helper methods don't take a thisArg despite the array prototype methods of the same name doing so. |
02:49 | <ljharb> | sure, but array concat's behavior isn't bad. (ignoring isConcatSpreadable ofc) the thisArg is useless since arrows and bind exist |
02:50 | <nicolo-ribaudo> | Rob Palmer If Ron finishes early, you can move forward my import attributes discussion (the constraint on the agenda is mine) |
02:50 | <Rob Palmer> | Thank you, Nicolo |
03:01 | <rbuckton> | Rob Palmer with the deadpan "wheee" 😂 |
03:02 | <jkup> | hahahahahahahaha |
03:03 | <bakkot> | lots of stage 4! |
04:00 | <Rob Palmer> | The schedule has been updated significantly! Today's afternoon session now looks very different |
04:02 | <rkirsling> | oh whoa apparently the rap battle is happening today |
04:03 | <Aki> | GIRD YOUR LOINS EVERYONE |
04:16 | <yulia> | clarifying question for someone here who probably knows the answer (otherwise when guybedford has time): This proposal is mostly to make worker imports of modules more statically analyzable right? why are new methods necessary on the Module Source object for this? https://tc39.es/proposal-esm-phase-imports/#sec-module-source-objects |
04:18 | <nicolo-ribaudo> | Yes that was the primary use case, but people then tried to think about how to use this for static analysis (basically exposing the metadata that the engine already has to collect) |
04:18 | <nicolo-ribaudo> | I think this would mostly be useful in Node.js as it is |
04:19 | <nicolo-ribaudo> | The browser utility is more marginal, unless we get something like the module constructor |
04:19 | <shu> | yeah i'm not clear on imports() and exports() utility either |
04:19 | <yulia> | yeah its a little hard to see a justification for this in browsers right now |
04:20 | <yulia> | but thats not related to the update, this is a general concern about the proposal |
04:20 | <nicolo-ribaudo> | Can one of you go on the queue? |
04:20 | <nicolo-ribaudo> | thanks :) |
04:32 | <rbuckton> | erights: As stated on a previous slide, there is no return override capability. |
04:33 | <Mathieu Hofman> | rbuckton: I think Mark's question (who isn't on Matrix) is whether a class can use a struct as the returned object in a return override to stamp fields on the struct |
04:33 | <rbuckton> | Ah. No, it cannot |
04:33 | <ljharb> | why not? |
04:33 | <ljharb> | if it's an object it should work |
04:34 | <ljharb> | just as if i can weakly hold it |
04:34 | <Mathieu Hofman> | I mean I'd love that, but yes, why, what's the mechanism ? |
04:34 | <ljharb> | it's an object. all objects (except window ) can have fields stamped on them via return override. |
04:34 | <rbuckton> | No, the fields must be statically known at construction time for one-shot initialization |
04:34 | <Mathieu Hofman> | if it's an object it should work |
04:34 | <ljharb> | "adding a private field" is the same as "putting an object in a weakmap" |
04:35 | <ljharb> | that's explicitly how private fields were designed |
04:35 | <ljharb> | return override isn't syntactic |
04:35 | <ljharb> | it is currently an invariant that if it is an object (modulo window) you can stamp private fields onto it via return override, and hold it weakly. we shouldn't break that invariant. |
04:35 | <Mathieu Hofman> | return override + private field stamping is a syntactic capability that is not deniable or virtualizable, unlike WeakMap |
04:36 | <ljharb> | that's already the case for all objects, it's a consequence of being an object. |
04:36 | <rbuckton> | private fields, if/when supported, will also have a fixed layout. |
04:36 | <Mathieu Hofman> | and it was a huge mistake |
04:36 | <Mathieu Hofman> | and I strongly believe we should not hold this as an invariant |
04:36 | <ljharb> | doesn't mean we should create inconsistency by deviating from it |
04:36 | <rbuckton> | it is necessary to achieve the performance characteristics we want for structs/shared structs |
04:36 | <ljharb> | to me this is an obstacle to stage 2, to be clear. |
04:37 | <bakkot> | can you class extends Struct {} ? if so you can surely put a private filed in that class? |
04:37 | <nicolo-ribaudo> | private fields, if/when supported, will also have a fixed layout. |
04:39 | <rbuckton> | Yes and no. The fixed layout is partially so that implementations can properly optimize field accesses in ways that they cannot with normal fields today. For shared structs, we want private fields to be shared memory as well |
04:39 | <Mathieu Hofman> | That is technically not necessary for for stamping private fields |
04:40 | <bakkot> | right but... can you do that thing? |
04:45 | <rbuckton> | can you |
04:46 | <ljharb> | that sounds like the only option to resolve it tbh |
04:46 | <bakkot> | I am OK with it being impossible to class extends Struct {} , to be clear |
04:46 | <bakkot> | just asking if that would work |
04:47 | <ljharb> | i'm not ok with being unable to stamp fields onto it. |
04:47 | <rbuckton> | I'd be fine class extends struct not working |
04:47 | <hax (HE Shi-Jun)> | As the current proposal, struct seems like a weakened version of class. Perceptually, the difference between struct and class is much smaller than the difference between struct and shared struct. I mean, it seems easy to rewrite a class to struct, but very hard to modify a struct to become a shared struct. This make me feel weird that "struct" and "shared struct" use similar name and syntax... |
04:48 | <bakkot> | if (and only if) it is impossible to class extends Struct {} then I am also ok with the return-override trick not allowing you to return a struct |
04:48 | <bakkot> | in which case, as a consequence, you could not stamp additional private fields on an existing struct |
04:49 | <littledan> | Correlation is also important even if you just have one object, and want the methods to work after sharing it to the other side |
04:51 | <rbuckton> | struct is a restricted form of class , partly because class polymorphism is expensive and slow and cannot be fully optimized via ICs. the fixed layout of structs is partly intended to improve performance due to the well known layout. Basically: class is more flexible but slower, struct is more restrictive but faster. |
04:54 | <rkirsling> | did I blink and miss an explanation of function coloring |
04:55 | <rbuckton> | did I blink and miss an explanation of function coloring unsafe block. |
04:55 | <rkirsling> | I think I understand what it means (like "an async function is fundamentally different from a sync function") but I don't see what shu is saying |
04:55 | <ljharb> | https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ |
04:55 | <rkirsling> | Function coloring is a function being aware of whether it is invoked inside of an |
04:55 | <rkirsling> | https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ |
04:55 | <bakkot> | we should add that to the glossary |
04:55 | <hax (HE Shi-Jun)> | rbuckton: Yeah, I mean it seems we should use syntax like sealed class { } to make it clear (though sealed is not a correct keyword) that it's a better but restricted class. And let shared struct just use struct {} ... |
04:56 | <ljharb> | the queue has 13 items btw |
04:56 | <danielrosenwasser> | Basically if you have a function foo that contains an unsafe {} block, callers of foo don't need to wrap it in an unsafe {} block. |
04:56 | <ljharb> | so i'd be able to write an "am i in an unsafe block" predicate? |
04:56 | <rbuckton> | rbuckton: Yeah, I mean it seems we should use syntax like struct , including the unique construction semantics. struct and shared struct construction differs significantly from class . |
04:57 | <danielrosenwasser> | so i'd be able to write an "am i in an unsafe block" predicate? |
04:57 | <rbuckton> | so i'd be able to write an "am i in an unsafe block" predicate? |
04:57 | <ljharb> | gotcha thanks |
04:57 | <danielrosenwasser> | oh no |
04:57 | <Mathieu Hofman> | so i'd be able to write an "am i in an unsafe block" predicate? |
04:57 | <Mathieu Hofman> | but as a predicate that has the shape of a function, no |
04:57 | <ljharb> | if you can't write such a predicate i'm not sure how you could virtualize shared structs |
04:58 | <hax (HE Shi-Jun)> | Shu and the v8 team have other reasons to want |
04:58 | <Mathieu Hofman> | you can with proxy |
04:58 | <ljharb> | ok, then you can, and functions can be colored manually? |
04:58 | <Mathieu Hofman> | it'd just be a boolean flag passed to the trap |
04:59 | <hax (HE Shi-Jun)> | I understand from the engine viewpoint (or spec viewpoint) it's true, but I guess from developer concept model, it's too different. |
04:59 | <nicolo-ribaudo> | so i'd be able to write an "am i in an unsafe block" predicate? You can try/catch around reading from a shared struct that you have, right?
|
05:00 | <rbuckton> | I understand from the engine viewpoint (or spec viewpoint) it's true, but I guess from developer concept model, it's too different. struct differ enough from class that making it differ purely based on a modifier would trip up developers. |
05:00 | <ljharb> |
|
05:00 | <danielrosenwasser> | ah I've misunderstood - so is the following disallowed?
|
05:00 | <nicolo-ribaudo> | ok, but can i run that try/catch inside a function that someone else invokes in, or not in, an unsafe block? |
05:00 | <nicolo-ribaudo> | It's like checking if your caller is strict or loose |
05:00 | <nicolo-ribaudo> | You can't |
05:00 | <rbuckton> |
|
05:01 | <bakkot> | I would like to see a lot more examples what code is/is not legal for unsafe , somewhere |
05:01 | <bakkot> | it is probably good I just don't understand it yet |
05:01 | <rbuckton> | bar does not magically get colored as unsafe when called. it must be lexically scoped within the block. |
05:01 | <rbuckton> | using or unsafe ? |
05:01 | <bakkot> | unsafe , sorry |
05:02 | <rbuckton> | unsafe only controls the ability to get/set a field on a shared struct instance, and only applies to code lexically scoped within the unsafe {} block. |
05:02 | <bakkot> | ok, that sounds straightforward; I think I got confused by all the discussion of coloring |
05:02 | <Mathieu Hofman> | unsafe only changes the behavior of get/set lexically contained in the block. |
05:02 | <bakkot> | but I am confused about the discussion of the APIs, then |
05:02 | <bakkot> | like Reflect.get etc |
05:03 | <Mathieu Hofman> | Should Reflect.get have some way to access the value (regardless of where the call happens) |
05:03 | <rbuckton> | The problem with Reflect.get is that it either must always succeed or always throw when reading a shared struct field. |
05:03 | <bakkot> | or we thread a parameter about unsafe-ness through, per the slides |
05:04 | <rbuckton> | Which means a Proxy must also either always succeed or always fail, or passing a get through a proxy trap becomes inconsistent when it passes through Reflect.get. |
05:04 | <rbuckton> | Yes, that's the third option. |
05:04 | <Mathieu Hofman> | get/set behavior is pretty straightforward. Where it gets funky is with own prop MOPs |
05:05 | <rbuckton> | My point is more that Reflect.get cannot magically know its in an unsafe block |
05:05 | <bakkot> | ack |
05:06 | <rbuckton> | It either must always succeed, always fail, or be explicitly informed via a parameter. |
05:11 | <danielrosenwasser> | Maybe I'm misunderstanding - but if you view it as an object which has been sealed, the behavior seems consistent with other objects, right? |
05:12 | <bakkot> | given a choice between "make it practical to write shared-memory parallelism in JS" and "preserve the property about things being in WeakMaps", I cannot imagine thinking the second thing is as important |
05:12 | <bakkot> | it is like, several orders of magnitude less important |
05:16 | <bakkot> | this is not to say that I don't see the real cost to having more complex rules for developers. it's just that making it practical for pages to have shared-memory parallelism is of incredible, massive value to every user of the web, measured in nontrivial fractions of our lives spent waiting for slow pages that didn't have to be slow. and against that, "JS developers have more complexity to learn" just does not rate |
05:16 | <bakkot> | ideally, of course, we would find something that allows us to get both |
05:16 | <littledan> | Yeah this seems like a clear case of what Yulia mentioned as a philosophical concern |
05:17 | <bakkot> | but if it comes down to a choice between those two, we cannot choose the "we don't get practical parallelism" one. |
05:17 | <rbuckton> | I'd much rather have shared memory multithreading than consistency with WeakMap keys. We already have this violation with symbols. |
05:17 | <ljharb> | symbols aren't objects. |
05:19 | <rbuckton> | There are other synchronization primitives and concurrency mechanisms we'd like to add, but none meet the bar for an MVP proposal, we hope to propose them as follow-ons later. |
05:19 | <Mathieu Hofman> | sorry I spoke too quickly, there is currently no spec behavior that allows a host to prevent object keys to be added to WeakMap, but there is to allow them to refuse any private field stamping |
05:19 | <ljharb> | sorry I spoke too quickly, there is currently no spec behavior that allows a host to prevent object keys to be added to WeakMap, but there is to allow them to refuse any private field stamping |
05:20 | <rbuckton> | There is also the possibility that structs and shared structs are more primitive-like than object-like, especially given that shared struct per-realm prototype lookup is likely to be very much like primitive prototype lookup. |
05:21 | <ljharb> | yes, i remain surprised they're not primitives personally |
05:21 | <Mathieu Hofman> | primitives shouldn't be mutable |
05:21 | <ljharb> | oh true |
05:21 | <ljharb> | Mathieu Hofman: re the host hook, it's only allowed in a web browser https://tc39.es/ecma262/#sec-privatefieldadd and that was very very intentional, since the expectation was that only window would ever use it |
05:22 | <rkirsling> | I am also worried about this topic but unlike Waldemar, I feel a lack of expertise on the subject lol |
05:22 | <rbuckton> | In a way, they are essentially "structured primitives" in that they have own fields. I'm not opposed to them having primitive-like behavior for typeof and Object() , but we'd need to discuss more among the champions. |
05:22 | <Mathieu Hofman> | that would be a much bigger problem for existing programs, a new type that has object like bahviors |
05:22 | <ljharb> | "use unsafe"; |
05:22 | <rbuckton> | that would be a much bigger problem for existing programs, a new type that has object like bahviors |
05:23 | <rkirsling> | "extra sloppy"; |
05:23 | <Mathieu Hofman> | right and we only considered it because R/T are immutable |
05:23 | <bakkot> | the value of unsafe blocks is definitely much lessened if unsafe -ness is not part of the type system. we could make it so, though? in the sense of, functions could be tagged with unsafe -ness, which is on by default if you use unsafe {} blocks, and then have some explicit mechanism for saying "this function uses an unsafe block but is actually safe" |
05:24 | <bakkot> | and if you call an unsafe function and do not have unsafe {} in your call stack then it throws |
05:24 | <bakkot> | disclaimer, I have not thought about this idea for more than 30 seconds |
05:25 | <rkirsling> | one concern that immediately rises in my mind (thinking about the cross-language use of an unsafe keyword) is:is this the only thing we'd ever want unsafe to mean in JS? |
05:25 | <rbuckton> | and if you call an |
05:25 | <shu> | yeah other names have been proposed, like volatile , i think? |
05:25 | <bakkot> | yes, but with a way to opt-out, which matters a lot |
05:25 | <shu> | re: "unsafe" |
05:25 | <bakkot> | the reason async is annoying is because you can't go from async to sync |
05:25 | <bakkot> | and here you could |
05:25 | <Mathieu Hofman> | and if you call an |
05:26 | <rbuckton> | unsafe {} isn't necessary at all for shared memory semantics, it is purely a guardrail to discourage unintended misuse |
05:27 | <bakkot> | function coloring is annoying only because you can't use async from sync. here you could as long as you explicitly opt in to enforcing the invariants yourself. |
05:27 | <rkirsling> | I do like volatile , maybe. either way I'm glad to hear that naming is being thought of |
05:27 | <rbuckton> | yeah other names have been proposed, like volatile {} was a suggestion from the TypeScript team as an alternative, and we're welcome to discussing others if there is a better option. |
05:27 | <Bradford Smith> | Personal take: The benefit of private fields is guaranteed encapsulation. I see the reverse WeakMap used to implement it to be an unfortunate implementation detail, not something to take advantage of. I would expect and hope that 99% of developers will not even be aware of it. Given that, it would be really weird if you could add private fields to structs after construction - which are supposed to be of a fixed shape. |
05:27 | <Mathieu Hofman> | You also basically end up with a 1 bit dynamic scoping for unsafeness of the call |
05:30 | <rbuckton> | ljharb: (a) is mostly figured out amongst the stakeholders, and we believe (b), (c), and (d) will not significantly impact whether this proposal will advance beyond stage 2. (b) could obviously have some limitations in the long term. |
05:31 | <nicolo-ribaudo> | What does "contamination" mean in this case? Isn't it solved by "no function coloring"? |
05:31 | <rbuckton> | I don't understand what "contamination" means here |
05:31 | <rbuckton> | unsafe is very local, it doesn't spread virally like async /await . |
05:31 | <Justin Ridgewell> | Does it need to be unsafe blocks? |
05:32 | <Justin Ridgewell> | Could it be Reflect.getUnsafe() and have it be explicit accesses without carrying a bit throughout the spec and ecosystem |
05:32 | <danielrosenwasser> | Is accessor allowed in a shared struct ? Can I just avoid unsafe with that? |
05:33 | <rbuckton> | That level of indirection would be a major performance bottleneck for a performance-critical feature. |
05:34 | <rbuckton> | That level of indirection would be a major performance bottleneck for a performance-critical feature. Reflect.getUnsafe() |
05:34 | <rkirsling> | I don't feel like it's that rare for a Stage 2 proposal to die...? |
05:34 | <rkirsling> | am I crazy |
05:34 | <Mathieu Hofman> | R/T comes to mind |
05:35 | <rkirsling> | I don't want R/T to be dead though 😭 |
05:35 | <bakkot> | i gotta say, given that we can already do sharedArrayBuffer[0] = 42 wherever we want, I really do not understand the hard constraint of unsafe blocks from mark |
05:36 | <bakkot> | like, yes, it would be nice to have some help from the language to call out when there's spooky stuff happening |
05:36 | <bakkot> | but we already do not have that |
05:36 | <ljharb> | then convince the browsers to make new primitives (ie, convince that the adoption and value will be sufficient to be worth the work) |
05:36 | <Justin Ridgewell> | This was in response to foo.bar |
05:36 | <yulia> | congrats on stage 2 shu |
05:37 | <shu> | thank you but why am i so unhappy |
05:37 | <Mathieu Hofman> | i gotta say, given that we can already do |
05:37 | <rkirsling> | thank you but why am i so unhappy |
05:37 | <yulia> | thank you but why am i so unhappy |
05:37 | <yulia> | and shared memory will happen, having support for it in JS is important and this is the right shape |
05:37 | <rbuckton> | How is it a level of indirection, this can be optimized the same as Reflect.getUnsafe(Reflect.getUnsafe(x, "y"), "z") on a regular basis, that's terrible DX. |
05:37 | <bakkot> | I am OK with making these deniable in the environment, if that's the concern? have like a SharedStruct which every shared struct needs to extend and which can be deleted |
05:38 | <shu> | oh i didn't think about that as a way to deny syntax, that's interesting |
05:38 | <bakkot> | does that solve the problem for you? |
05:38 | <rbuckton> | I am OK with making these deniable in the environment, if that's the concern? have like a |
05:38 | <Justin Ridgewell> | Even if it can, I don't really want to write unsafe {} everywhere either |
05:39 | <bakkot> | or just like when a shared struct is evaluated it checks globalThis.canMakeSharedStructs and then if you want to turn that off you make that nonwritable-nonconfigurable false |
05:39 | <rbuckton> | I don’t really wanna write Reflect.getUnsafe() . |
05:39 | <bakkot> | or... several other options |
05:39 | <ljharb> | laughs in python's GIL |
05:39 | <bakkot> | denying postMessage and similar sharing-across-agent capabilities works just as well, yes |
05:39 | <yulia> | can we do unsafe functionName () {} and just make it like async/await? (not a serious suggestion) |
05:40 | <Justin Ridgewell> | Neither do I, but its far more convenient than getUnsafe() |
05:40 | <bakkot> | (anyway I really really gotta go to sleep, will read messages in the morning and leave transcription bot running for now, later all) |
05:40 | <rbuckton> | can we do unsafe functionName () {} and just make it like async/await? (not a serious suggestion) function foo() unsafe {} |
05:40 | <rbuckton> | Keep in mind that unlike async/await, unsafe does not spread virally to your callers |
05:41 | <ljharb> | i mean, async/await doesn't directly do that either |
05:41 | <ljharb> | only indirectly by returning a promise |
05:41 | <yulia> | async/await results in very viscous refactoring situations |
05:41 | <littledan> | I think it’s good that our process allows significant questions to be open during Stage 2. It would be bad if champions were incentivized to hide debates until later. But more importantly, the signal to invest significantly in a proposal is important to be able to dedicate the work to solve the problem. |
05:41 | <rbuckton> | i mean, async/await doesn't directly do that either |
05:41 | <yulia> | you have to update all callers, or end up with a fire and forget situation |
05:41 | <Justin Ridgewell> | I did propose this, but not like async/await, more as a way to avoid doubly nested blocks. Alternatively, unsafe exists as a concept, or that it’s implemented as a block? |
05:41 | <yulia> | so yeah unsafe would not be that viscuous |
05:41 | <Justin Ridgewell> | If the second, then unsafe functions don’t really solve it. |
05:42 | <waldemar> | I don't understand what "contamination" means here unsafe will contaminate generic abstractions and algorithms, which will be pressured to wrap themselves inside unsafe blocks just so that folks can pass shared structs into them. Most don't really care about consistency and we already have the same problem with accessors, callbacs, and proxies. Wrapping one of these in unsafe will just become boilerplate practice. |
05:42 | <yulia> | the function solution would be implemented the same way as the block, and would have the same complexity concern i had earlier, which is why i wasn't so serious with it |
05:43 | <yulia> | so its not really a solution, we would need something else, that doesn't require marking the get/set with a flag |
05:43 | <shu> | waldemar: yulia: Mathieu Hofman (i can't find mark in this channel) ljharb PTAL at the conclusions in the notes to see if it's explicit enough for your liking |
05:43 | <rbuckton> |
unsafe {} at the top level as a workaround. That's just bad practice. |
05:44 | <rbuckton> | And it should be discouraged. |
05:44 | <Mathieu Hofman> |
|
05:45 | <rbuckton> | I would encourage anyone who has interest or concerns in the shared structs proposal to join our regularly scheduled stakeholders calls, we've been making a lot of positive progress in all areas. |
05:46 | <waldemar> | We have no viable story for how to handle abstractions that apply to shared structs. |
05:47 | <waldemar> | How do you tell an abstraction that can apply to both shared and unshared structs that this usage is safe and that usage is unsafe? |
05:48 | <Mathieu Hofman> | To be honest the only thing I can think of (besides unsafe blocks) to enable correct shared fields access is to only allow private shared fields, which would require methods / accessors |
05:49 | <ljharb> | that would give you immutable structs right out of the gate, no? |
05:49 | <shu> | I would encourage anyone who has interest or concerns in the shared structs proposal to join our regularly scheduled stakeholders calls, we've been making a lot of positive progress in all areas. |
05:49 | <Mathieu Hofman> | How do you tell an abstraction that can apply to both shared and unshared structs that this usage is safe and that usage is unsafe? |
05:49 | <waldemar> | But generic abstractions and algorithms shouldn't be unsafely dealing with shared structs, that's the point. They are likely not able to operate generically on the object. |
05:49 | <rbuckton> | that would give you immutable structs right out of the gate, no? |
05:49 | <shu> | reading the back log, i agree with Mathieu Hofman that return override w/ private field stamping really really should not rise to the level of a design invariant that consciously aim to keep |
05:50 | <ljharb> | "immutable" if you squint hard. |
05:50 | <rbuckton> | Yes, I picked up on that. |
05:50 | <waldemar> | In practice there is very little delta between the mischief shared objects can get into and what ordinary callbacks, accessors, proxies, etc. can do. |
05:51 | <waldemar> | The differences are primarily of interest to experts, not casual users. |
05:51 | <shu> | In practice there is very little delta between the mischief shared objects can get into and what ordinary callbacks, accessors, proxies, etc. can do. |
05:52 | <Mathieu Hofman> | yet somehow shared memory programs have a lot more race type bugs than async or callback code |
05:52 | <waldemar> | i agree, but i also don't know how to address mark's requirement that the app-wide opt-in/out switch like COOP/COEP is insufficient |
05:52 | <waldemar> | yet somehow shared memory programs have a lot more race type bugs than async or callback code |
05:52 | <rbuckton> | I'd rather not have unsafe {} , to be honest. But I'd rather have unsafe {} if that means we can get usable shared memory multithreading. I'm open to other suggestions so long as they don't negatively impact performance in a meaningful way. |
05:53 | <shu> | though i don't think we've fully engaged with bakkot's idea that there be a programmatic way to deny shared structs, even if they're syntax? |
05:56 | <rbuckton> | Given that JS has proxies and getters, any property access could conceivably change underneath you. |
05:56 | <shu> | waldemar: is it a fair characterization to say your skepticism of unsafe {} boils down to SABs already must be grandfathered in, so it's a false guardrail? |
05:56 | <shu> |
|
05:56 | <shu> | wtf is wrong with matrix |
05:56 | <rbuckton> | Also, its possible to write abstractions that work with shared and unshared objects equally, so long as they do so through callbacks since those callbacks can be lexically scoped within an unsafe {} block. |
05:56 | <shu> | if i start a message with a + it turns it into a - and then a bullet point?? |
05:57 | <ryzokuken> | wtf is wrong with matrix |
05:57 | <yulia> | though i don't think we've fully engaged with bakkot's idea that there be a programmatic way to deny shared structs, even if they're syntax? |
05:58 | <shu> | i'm not sure if it actually addresses agoric's concerns though, should ask |
06:03 | <waldemar> | waldemar: is it a fair characterization to say your skepticism of unsafe {} boils down to SABs already must be grandfathered in, so it's a false guardrail? That's part of it. A bigger part is that:
|
06:03 | <Mathieu Hofman> | Mark is there with you, time to chat with him ;) |
06:05 | <nicolo-ribaudo> | How does unsafe work in Rust? I know that it's a different type of unsafe, but I assume some of the same concerns about "virality" and "false guardrail" still apply? |
06:06 | <rbuckton> | Rust has a borrow checker and full type system, so it can enforce the guardrail via the API |
06:07 | <rbuckton> | In JS, we have "name your function fooUnsafe() " |
06:07 | <nicolo-ribaudo> | Re the "everybody would use unsafe just to be sure", maybe instead of unsafe we can use a different property access operator. e.g. obj.foo only works for non-shared objects, and obj⚠️.foo would only work for shared structs |
06:08 | <nicolo-ribaudo> | So you cannot use it "just in case", and if you want to write code that works with both you have to introduce your own abstractions |
06:10 | <nicolo-ribaudo> | In JS, we have "name your function |
06:11 | <danielrosenwasser> | From here:
So my understanding is that basically the operations allowed in an unsafe expression context are:
The other two are basically markers at the declaration site, and they push the work onto the caller to either contain the code in an |
06:13 | <nicolo-ribaudo> | It sounds much more similar to the one proposed for shared structs than I expected! "Access fields of a union" is kinda like our use case, even if it's unsafe for different reasons |
06:13 | <nicolo-ribaudo> | But the difference is that whether you need unsafe or not is not determined by your caller, because as Ron said there is a type checker |
06:17 | <rkirsling> | now entering the spice zone |
06:17 | <rkirsling> | super appreciative of that disclaimer actually |
06:17 | <Chris de Almeida> | the first rule of spice club... |
06:18 | <Ben> | everyone, please, it is crucial to walk without rhythm while in the spice zone |
06:29 | <nicolo-ribaudo> | I'm curious about that logical assignment CVE |
06:30 | <nicolo-ribaudo> | Isn't it something that can be implemented just in the bytecode emitter, relying on existing ops? |
06:30 | <rkirsling> | I looked that one up too because it blew my mind |
06:30 | <Michael Ficarra> | I want to know what portion of these CVEs would have been impossible had they been implemented in a memory safe language |
06:30 | <rkirsling> | it was specific to SM's initial implementation |
06:30 | <ljharb> | I want to know what portion of these CVEs would have been impossible had they been implemented in a memory safe language |
06:31 | <Michael Ficarra> | Obviously "more C++ code" means "more memory bugs". That does not mean we should do less language development. It means that we should write less C++ code. |
06:31 | <yulia> | I want to know what portion of these CVEs would have been impossible had they been implemented in a memory safe language |
06:32 | <yulia> | rust isn't as heavily optimized yet, and also certain areas of the engine such as garbage collection don't really work in rust |
06:32 | <nicolo-ribaudo> | Maybe we could just write engines in JS and compile them to native with Porffor |
06:32 | <Michael Ficarra> | oh I didn't realise performance was more important than security |
06:32 | <yulia> | if it wasn't a balance, we would not have jits. |
06:33 | <ryzokuken> | Maybe we could just write engines in JS and compile them to native with Porffor |
06:35 | <yulia> | we are trying to approach this in an open way, so that we can come to a solution together. The vast majority of monetary investment, in making JS work, is on implementers shoulders. As is the risk, and responsibility when things go wrong. Being told to stop complaining and that our concerns are invalid is not a way forward. We, as equal delegates, can just say no to all features going forward. We aren't doing that, instead we are inviting dialogue. |
06:35 | <yulia> | also, JSSugar is one solution, coming from v8 -- not all of the vendors are aligned on it |
06:36 | <yulia> | I personally see another way forward, tackling a different surface, that will enable language evolution |
06:36 | <Michael Ficarra> | Oh totally agreed, and I'm actually really supportive of the JSSugar approach. I just don't buy the security motivation basically at all. |
06:37 | <Andreu Botella (at TC39, 🕐 JST)> | browser vendors aren't the only implementers |
06:37 | <yulia> | I didn't speak of browsers, but implementers. Moddable is a cosigner |
06:38 | <Michael Ficarra> | And I'm also really bitter that browsers (and OS vendors) continue to write more code in a memory-unsafe language that I have to run on my computer. |
06:39 | <yulia> | well, if we make some really radical moves maybe we can make it more feasible to do 1) more of the language in memory safe languages regardless of the browser engine, and 2) allow more competitors |
06:39 | <yulia> | let's talk about it after because its a big idea that won't be discussed now (im still talking to stakeholders about it) |
06:40 | <Andreu Botella (at TC39, 🕐 JST)> | I didn't speak of browsers, but implementers. Moddable is a cosigner |
06:40 | <yulia> | some parts, at least at present (GC in particular) aren't feasible (right now) in a safe language, just because of what you are doing |
06:41 | <rkirsling> | Okay, I meant vendors, not specifically browser vendors. Igalia is an implementer who works on engines built by other vendors. Although we're probably in a unique position |
06:41 | <Marja Hölttä> | Michael Ficarra: the most chrome / v8 bugs are not because our C++ is doing memory management wrong, they are because we have a logic bug in generating machine code or because our invariants are extremely complex and one part might make a change which violates an invariant somewhere else. happy to talk more about this. interestingly, a huge proportion of the CVEs listed on shu's slide were in my code, and none of my bugs were because of C++, and would've happened even if V8 was written in a memory safe language. |
06:42 | <yulia> | also part of the context here is the unshippability of the things that we spec, see my upcoming presentation on species |
06:42 | <yulia> | species being one of the worst offenders from a sec perspective |
06:42 | <yulia> | and performance perspective |
06:42 | <Marja Hölttä> | the basic problem being: "logic bug in a normal application -> typically a bug, not a security issue" whereas "logic bug in a compiler -> a security bug" |
06:43 | <keith_miller> | 100% agreed almost none of them are out of bounds memory accesses. Some of them are UAFs but most memory safe languages wouldn't solve those ones as they're GC related. |
06:43 | <Michael Ficarra> | also part of the context here is the unshippability of the things that we spec, see my upcoming presentation on species |
06:44 | <keith_miller> | For the most part they're because generated machine code is just wrong |
06:44 | <yulia> | Do you think that's something we still risk today with our current stage process? |
06:44 | <Michael Ficarra> | okay then maybe JITs are the real evil |
06:44 | <keith_miller> | So you'd have to have a proof-carrying compiler, which is, AFAIK, still mostly in academia only |
06:45 | <yulia> | no disagreement that the performance requirements of the web also drive complexity |
06:45 | <rkirsling> | okay then maybe JITs are the real evil |
06:45 | <yulia> | however, moddable which has a much simpler implementation has also had similar issues. it is not browser/jit only |
06:45 | <canadahonk> | So you'd have to have a proof-carrying compiler, which is, AFAIK, still mostly in academia only |
06:45 | <rkirsling> | (we have JIT totally disabled on PS for security reasons) |
06:46 | <keith_miller> | something something wasm kind of somewhat does this? |
06:46 | <rkirsling> | (it was a HUGE attack surface on PS4) |
06:46 | <Michael Ficarra> | @keith_miller yeah but it's a much smaller language at that point |
06:47 | <Michael Ficarra> | (it was a HUGE attack surface on PS4) |
06:47 | <ryzokuken> | crackers maybe? |
06:47 | <rkirsling> | I am not a security expert |
06:47 | <rkirsling> | I just know that there were whole twitter accounts dedicated to it |
06:48 | <Rob Palmer> | I assume this slide on "The bar" is a logical OR rather than AND |
06:49 | <canadahonk> | (we have JIT totally disabled on PS for security reasons) |
06:49 | <nicolo-ribaudo> | Rob it's the implication symbol |
07:01 | <hax (HE Shi-Jun)> | I lost connection and after reconnect I can't see the shared screen, does anyone have similar issue? |
07:01 | <jkup> | This happened to me earlier but after a minute I could see it again |
07:02 | <hax (HE Shi-Jun)> | This happened to me earlier but after a minute I could see it again |
07:02 | <hax (HE Shi-Jun)> | yeah, it comes back |
07:07 | <hax (HE Shi-Jun)> | I guess runtimes can bake it, eg. deno/nodejs? |
07:09 | <nicolo-ribaudo> | Yeah, I would hope we wouldn't make it illegal to implement JSSugar in engines, just optional |
07:11 | <yulia> | waldemar: sorry i couldn't respond fast enough: the problem statement is very broad, and we so far haven't addressed the point that you made, so if you have any ideas on this they are very very welcome |
07:11 | <yulia> | maybe we can talk async about it |
07:13 | <waldemar> | I'm unhappy about the framing of this as a tension between users, developers, and implementors. In most cases we can reduce complexity for all three; existing complexity is a result of past decisions that benefited none of these three. |
07:15 | <Chris de Almeida> | I'm trying to keep an open mind, but at the end of the day this forks the language and I would just not use the sugar features. yes people use tooling but not exclusively all the time, and a lot of workflows rely on the language being available directly in the browser |
07:16 | <yulia> | I'm unhappy about the framing of this as a tension between users, developers, and implementors. In most cases we can reduce complexity for all three; existing complexity is a result of past decisions that benefited none of these three. |
07:16 | <canadahonk> | I'm unhappy about the framing of this as a tension between users, developers, and implementors. In most cases we can reduce complexity for all three; existing complexity is a result of past decisions that benefited none of these three. |
07:16 | <yulia> | On the other hand, something like nullish coallescing resulted in more efficient code in the end, but (for firefox) we had users who suffered from stability (in particular we had bugs coming in from users who could no longer load sites, but also couldn't update their browser) |
07:17 | <yulia> | this is because syntax in particular is not forward compatible. you can't shim it, you have to transpile it. |
07:18 | <waldemar> | thats certainly the case for something like species, but bigint is an independent proposal that had a similar effect |
07:18 | <rbuckton> | pipeline desugaring is a bad example because it's so dead simple |
07:19 | <Michael Ficarra> | A lot of folks are making points about low BigInt usage, but we'd be hurting if something like that weren't in the language — it comes up rarely in APIs, but, when it does come up, hacking around the lack of BigInt would have made a bigger mess. |
07:19 | <rbuckton> |
is just
|
07:19 | <Mathieu Hofman> | we use BigInt a LOT |
07:19 | <yulia> | A lot of folks are making points about low BigInt usage, but we'd be hurting if something like that weren't in the language — it comes up rarely in APIs, but, when it does come up, hacking around the lack of BigInt would have made a bigger mess. |
07:19 | <yulia> | and i think there is a future where we could have that |
07:19 | <Mathieu Hofman> | I don't think any financial application could work without BigInt |
07:20 | <nicolo-ribaudo> | this is because syntax in particular is not forward compatible. you can't shim it, you have to transpile it. |
07:20 | <rbuckton> | BigInt is also quite important to Azure |
07:20 | <Michael Ficarra> | I don't think any financial application could work without BigInt |
07:21 | <Mathieu Hofman> | maybe it's not seen in the instrumentation of browsers, but there are a lot of backend use cases for BigInt |
07:21 | <yulia> | How is this relevant? Those websites would have broken even if there was a missing runtime API. The developer would have still chosen to ship the polyfill for that browser version, similarly to how they could have shipped with the transpiled code |
07:22 | <nicolo-ribaudo> | shims are lightweight to ship, you can't ship a shim for syntax. it requires tooling, shims don't |
07:22 | <yulia> | the second half is, yes |
07:22 | <nicolo-ribaudo> | Oh, I'll be curious to hear the Mozilla proposed solution when it's ready |
07:23 | <yulia> | but that is v8's position, mozilla didn't co-sign that |
07:23 | <yulia> | not that JSSugar isn't a potential solution, we are just unsure about it |
07:23 | <ljharb> | thats certainly the case for something like species, but bigint is an independent proposal that had a similar effect |
07:23 | <yulia> | I'm working on getting the approval for it & roping in all of the stake holders, should come soon |
07:23 | <Chris de Almeida> | I don't have data to support this, but I really think the presentation overestimates the use of build/compilation tooling, and disregards the abundance of... not using those things, or in the same way |
07:23 | <rbuckton> | Tooling can't address eval , new Function , other evaluators, or new RegExp() which would need the tooling to be run in browser to support these transformations. |
07:24 | <rbuckton> | It's already a problem when transpiling today. |
07:25 | <rkirsling> | I don't have data to support this, but I really think the presentation overestimates the use of build/compilation tooling, and disregards the abundance of... not using those things, or in the same way |
07:25 | <rkirsling> | ...as a co-signer of the first half |
07:26 | <Michael Ficarra> | Tooling can't address |
07:27 | <rbuckton> | please don't do these things /.../ but not new RegExp("...") ? |
07:28 | <Michael Ficarra> | I don't really care either way about regexp. Don't use eval or Function. |
07:28 | <rbuckton> | And the eval case was an important discussion point re: decorators raised by Mark Miller, so it's come up before in plenary. |
07:28 | <canadahonk> | ... and eval(...) differing completely in support feels 🥴 |
07:29 | <Rob Palmer> | I don't have data to support this, but I really think the presentation overestimates the use of build/compilation tooling, and disregards the abundance of... not using those things, or in the same way |
07:31 | <rbuckton> |
You can sort of make it work, but it requires knowing the intricacies of the language. e.g., transpiling
and expecting
and |
07:33 | <nicolo-ribaudo> | Node.js shipping a TS compiler is the proof that people hate using tooling |
07:33 | <Chengzhong Wu> | "Many people using tools" doesn't mean that "many people like using tools" |
07:35 | <rbuckton> | Node.js shipping a TS compiler is the proof that people hate using tooling enum , parameter properties, etc.) |
07:37 | <littledan> | Yulia: Wasm is in scope for source maps. Considering other serializations is as well, though the group has decided so far that this type of efficiency isn’t the most pressing concern. |
07:38 | <yulia> | Source maps is just too heavy. it doesn't scale. WASM was using dwarf but there were issues with that as well (i believe for supporting all languages) |
07:38 | <Rob Palmer> | Node.js shipping a TS compiler is the proof that people hate using tooling I would use a weaker word than "hate". It's more about the hierarchy of abstractions - ideas > design patterns > tools > runtimes > language. The more fundamental/essential the functionality, the more folk benefit from pushing it down the hierarchy to codify it and make it more accessible. Folk like types being even more accessible. |
07:38 | <yulia> | I think that the current source maps group doesn't have any overlap with the WASM debugging wg, but the issue of debugging information in JS was part of that as well |
07:39 | <littledan> | We are definitely focusing on the mapping to Wasm from source maps. Are there any participants from the previous effort that we should recruit to join? |
07:39 | <yulia> | have you had fitzgen come by at all? |
07:40 | <yulia> | I don't know if he will have time but he was on both |
07:41 | <rbuckton> | Many if not most syntax proposals will require runtime functionality to work. using requires Symbol.dispose , pattern matching requires Symbol.customMatcher as methods on a number of built-ins, so a single feature requires changes to both JS0 and JSSugar. |
07:44 | <jkup> | Nope, not to any of our recent meetings at least! Would love it if he had time. For Wasm the effort has mostly been lead by Kotlin, Chrome DevTools and Tauri so far. |
07:45 | <keith_miller> | Why couldn't using be desuggared? Symbol.dispose ??= Symbol() would be the init sequence for the shared symbol |
07:45 | <yulia> | So if you didn't have the history: we tried to standardize source maps before. That is what became the wasm debugging group |
07:46 | <rbuckton> | That's not the same as a built-in symbol, plus the using proposal has other API changes as well. |
07:46 | <jkup> | So if you didn't have the history: we tried to standardize source maps before. That is what became the wasm debugging group |
07:46 | <yulia> | i'll see if i can get fitzgen to come, ill try to come by as well |
07:46 | <yulia> | yes thats it |
07:46 | <rbuckton> | TS will downlevel using , but expects the developer to supply the shim for runtime functionality. |
07:46 | <yulia> | it fell apart (maybe it started up again?), it was mostly chrome that had time for it. yury on the sm team also has some of the history |
07:47 | <rbuckton> | using may be a trivial example, but pattern matching is not. |
07:47 | <ljharb> | that's a really good point. if eslint doesn't support syntax by default then users won't adopt it; if it's going to change, eslint won't support it |
07:47 | <hax (HE Shi-Jun)> | nicolo-ribaudo: I think we can cover Babel cost by forcing champion implement it in Babel 😉 |
07:48 | <rkirsling> | the problem there is that Babel would become a singular blessed tool |
07:48 | <Michael Ficarra> | set up GoFundMes for TC39 proposals |
07:50 | <Michael Ficarra> | or just get the community to pay Igalia I guess |
07:51 | <shu> | the cost isn't in implementation |
07:51 | <shu> | the cost is maintenance in perpetuity |
07:52 | <ljharb> | given the current state of voluntary payments to "free" software projects that are important to society/security/humans, i'm not optimistic about browser crowdfunding either |
07:53 | <nicolo-ribaudo> | shu I understand that you don't want to "demote" any proposal, but it would be a good exercise to pretend that this presentation happened 5-10 years ago, and show how the current proposals would have evolved under this framing |
07:53 | <shu> | are you asking me to actively invite psychic damage to myself |
07:54 | <nicolo-ribaudo> | It's part of the cost of proposing such a big change :P |
07:55 | <hax (HE Shi-Jun)> | the problem there is that Babel would become a singular blessed tool |
07:56 | <Justin Ridgewell> | Does Mozilla not have someone attending TG2 meetings? |
07:57 | <ryzokuken> | Does Mozilla not have someone attending TG2 meetings? |
07:59 | <linusg> | maybe it's not seen in the instrumentation of browsers, but there are a lot of backend use cases for BigInt |
08:04 | <rbuckton> | Is bit math still slower on BigInt compared Number? I've wanted to switch to bigint for some of our flags in the TS compiler, but we only recently changed our minimum target to one that supports bigint natively. |
08:08 | <Mathieu Hofman> | Tooling can't address |
08:09 | <Chris de Almeida> | shu: yulia I captured the queue for JSSugar. do you want a continuation if we have time later? |
08:09 | <yulia> | I've already spoken with them, they are fine with it. But due to issues brought up from other parts of the web platform, regarding what TG2 has been standardizing, we are under heavier scrutiny. So, i'm just double checking with our internal stake holders. |
08:11 | <Mathieu Hofman> | I don't really care either way about regexp. Don't use eval or Function. |
08:11 | <rbuckton> | eval is not evil. there are ways to safely evaluate untrusted code. |
08:12 | <shu> | shu: yulia I captured the queue for JSSugar. do you want a continuation if we have time later? |
08:13 | <yulia> | I also reacted before seeing the issues, they look really minor |
08:14 | <yulia> | i honestly can't stress enough how having more time to review would help... |
08:14 | <nicolo-ribaudo> | I get excited whenever I see well organized data |
08:14 | <Ashley Claymore> | Maybe that proposal would have been split in two in the same way? Browsers initially only implement the Symbol and add implementations of the methods to the right web APIs. But the syntax part stays at JSSugar (at least initially) |
08:15 | <Ashley Claymore> | And then in the future Browsers implement the syntax part too when it's the right time for that to happen |
08:15 | <Chris de Almeida> | this is really cool... I know it's been a long day but... 👀 |
08:16 | <ljharb> | i'm also excited about the possibility of creating a polyfill for API things on-the-fly using es-abstract, so you can get an in-editor REPL for your spec change |
08:17 | <Mathieu Hofman> | In a sandbox, out of process, on another machine... |
08:18 | <shu> | https://github.com/tc39/Reflector/issues/539 |
08:19 | <rbuckton> | no in the same process, either different realm (ShadowRealm) or even same realm (Compartment in hardened Realm). Salesforce uses realms, we use Compartments in production, and Moddable uses compartments too in their devices. Let's not claim there is no way to securely run 3rd party JS in the same process |
08:20 | <Mathieu Hofman> | Ah yes, I thought you asked for all 3 ;) |
08:20 | <rkirsling> | https://github.com/tc39/Reflector/issues/539 |
08:21 | <shu> | are you getting an error? |
08:21 | <shu> | ljharb: ^ |
08:21 | <ljharb> | it should work fine. i'll check to make sure you're invited to the tc39-transfer org … invite sent. |
08:21 | <Mathieu Hofman> | It's a common reaction we hear from the browser implementors, but lots of production systems run untrusted JS code same process in some fashion, with some kind of sandbox of course |
08:22 | <rbuckton> | Ah yes, I thought you asked for all 3 ;) |
08:23 | <ljharb> | if it's on a separate machine it's definitely also out of process :-p |
08:23 | <rbuckton> | or maybe I should have clarified OOP (same machine) |
08:23 | <Marja Hölttä> | Mathieu Hofman: what's the one-sentence summary wrt how they get around Spectre & co when running in the same process? |
08:24 | <Mathieu Hofman> | deny or virtualize any API that allow measuring time |
08:25 | <Mathieu Hofman> | also that's if you're concerned about confidentiality. integrity doesn't need denying time tools |
08:25 | <ljharb> | does that include all i/o? because presumably you could approximate time measurements that way, but maybe it wouldn't be granular enough to matter |
08:26 | <Mathieu Hofman> | Yes and no. For example Cloudflare Workers pretend time only advances when making external requests. The time is updated to the time the request is processed. |
08:28 | <Mathieu Hofman> | From what I understand they have some smart logic when you make a request from one worker to another to avoid colluding workers measuring time |
08:28 | <justingrant> | I had the same question/concern: other than purely "sugar" features like pipeline, most interesting new JS features seem like they'd need some help from the lower-level runtime to have adequate performance and functionality. It'd be good to have some case studies of a few proposals to see what a JSSugar implementation would actually look like in practice. |
08:29 | <ljharb> | fancy |
17:22 | <bakkot> | proposal to move the https://github.com/tc39/proposal-type-annotations to https://github.com/tc39/proposal-types-as-comments? people are continually confused about it |
17:34 | <Rob Palmer> | Can we create a redirect? TaC is the old name. |
18:50 | <Rob Palmer> | Separate: Please could someone unmute @marjakh:matrix.org: |
18:54 | <Eli Grey> | wasn't able to participate yet but I'll be available remotely for days 2 & 3 -- could someone help forward remote attendance info? |
19:03 | <keith_miller> | It's in the reflector for the meeting https://github.com/tc39/Reflector/issues/537 there's a sign-in form that gives you the link |
20:15 | <Eli Grey> | thanks, I see it now |
22:29 | <Chris de Almeida> | Separate: Please could someone unmute @marjakh:matrix.org: |