05:58 | <ljharb> | * this was the precise suggestion you made for global , if you recall. |
07:00 | <littledan> | global was in a known web-incompatible state with no changes publicly proposed over the course of a year, so I think that's different. We don't have particular known issues for Temporal, and definitely not with respect to web compatibility. |
07:02 | <littledan> | (or did I say something about what should happen after the new name was proposed? I don't remember making that suggestion at that time.) |
07:02 | <ljharb> | very true that there's no web compat concern; it's not exactly the same |
07:02 | <ljharb> | but what i remember is that you argued (a position i disagreed with at the time, but have come around on and now agree with) that it should have dropped to stage 2 since the name was going to change |
07:03 | <littledan> | right, so that's a case of a change that needs to happen for something to be shippable, whereas we're not aware of changes that need to happen for Temporal for it to be shippable |
07:03 | <ljharb> | wasn't that the entire agenda item? it was too big to be shippable. |
07:04 | <littledan> | and we addressed it, we hope (modulo implementer feedback, which makes sense to seek during Stage 3) |
07:05 | <ljharb> | right. it's the "we hope" part that's been proven false in nearly every plenary for the last 4 years, and i'd think that (likely well) over 10 times bitten should at least produce once shy |
07:06 | <littledan> | "once shy"? |
07:07 | <ljharb> | lol i was trying to paraphrase "once bitten twice shy", i've been up for nearly 20 hours so it might not make sense |
07:07 | <Chris de Almeida> | once bitten, twice shy idiom —used to mean that a person who has failed or been hurt when trying to do something is careful or fearful about doing it again |
07:08 | <Chris de Almeida> | if the corrective action suggested here is to more liberally request consensus to regress proposals when it seems they should be regressed, that seems reasonable to me |
07:09 | <ljharb> | exactly that. which is something we've discussed multiple times in recent years, like with import attributes for example |
07:09 | <ljharb> | (to pretty consistently positive response, iirc) |
07:10 | <littledan> | so, for import attributes, it was retracted because a change was in progress, which is more similar to the globalThis case. |
07:10 | <ljharb> | the concept of a "scoped demotion" helped make that palatable, i think |
07:10 | <nicolo-ribaudo> | I wonder if the proposed action would have been "lets split the proposal in two and bring this part back to stage 2", rather than "lets remove this part", the stability impression would have been different |
07:11 | <littledan> | it was unfortunate that we didn't permit ourselves a scoped demotion. I think the committee agreed to the demotion partly because the strongly opinionated people agreed to scoping, even if the committee as a whole wasn't going to commit to scoping. |
07:11 | <ljharb> | or alternatively, at this point we could move it back to ~2 with a scope of "no design changes, only implementation-driven ones" - which sounds like stage 3, but, because of the scale of Temporal might be worthy of some flexibility |
07:11 | <littledan> | but there's no design changes proposed here, so I'm not sure what the criteria would be later for re-promotion |
07:11 | <ljharb> | dropping calendar and timezone were pretty massive design changes |
07:11 | <littledan> | right, but we don't have any further changes proposed |
07:11 | <ljharb> | oh sure. that's been the case after every plenary tho, until the next one |
07:12 | <littledan> | when import attributes were re-promoted, there was the idea raised, "even though we agree on these changes, should we wait longer to let things settle?" we decided no wait was needed, and that turned out just fine. |
07:12 | <ljharb> | since we won't have time to discuss temporal's stage this meeting, i guess we'll see either way :-) |
07:13 | <ljharb> | but if more changes come back in july, i think we should seriously consider demoting it until changes stop coming |
07:13 | <littledan> | since we won't have time to discuss temporal's stage this meeting, i guess we'll see either way :-) |
07:13 | <ljharb> | perhaps yall can indeed discuss it; i'm going to bed in an hour or so and won't be present after that. i sleepy. |
07:13 | <littledan> | ah OK good to know |
07:14 | <ljharb> | (presumably) my opinion is clear tho so i don't necessarily need to be there |
07:16 | <littledan> | I think we've made the points back and forth here; I'm not sure what more we should discuss |
07:17 | <ljharb> | it'd only be worth discussing imo if there's a decent chance of a demotion, otherwise it's probably more efficient to just wait til july and revisit if there's more changes |
07:36 | <Michael Ficarra> | maybe I wasn't clear? |
07:37 | <Michael Ficarra> | the question is NOT about whether there are only editorial changes remaining, it is about whether the remaining changes are considered "major", which is subjective |
07:37 | <rbuckton> | I understood "High level APIs and Syntax" to mean the rough design we want to proceed with. We've never been so strict for stage 2. |
07:38 | <rbuckton> | "Placeholders and TODOs are acceptable" |
07:38 | <rbuckton> | The description in the Purpose column describes the kinds of things Waldemar is discussing |
07:39 | <ptomato> | there have been proposals entering stage 2 with entire methods stubbed out |
07:39 | <littledan> | re Shane's topic: I think we do approve slideshows: we advance things based on conceptual agreements, which I think we have here. Stage 2.7 is where we look for the spec to be basically perfect. |
07:40 | <Michael Ficarra> | @littledan even stage 4 is advanced on conceptual agreements |
07:41 | <Chris de Almeida> | the question is NOT about whether there are only editorial changes remaining, it is about whether the remaining changes are considered "major", which is subjective |
07:41 | <Michael Ficarra> | the editor group often finds things in the 262 spec document that don't align to what we conceptually agreed to and we just fix them and notify committee at the next plenary |
07:42 | <Michael Ficarra> | part of the editor's job responsibilities is going back through consensus (written and in our memory) to confirm that the document aligns with it |
07:43 | <Rob Palmer> | Purpose of Stage 2:
|
07:45 | <rbuckton> | If we agree this is the right direction to go for Decimal, then Stage 2 seems perfectly reasonable. It means we've committed to that direction and now we want to flesh out the details. |
07:49 | <Chris de Almeida> | more greatest hits from the process doc, re: stage 2 status
|
07:50 | <littledan> | If Decimals overflow, please feel free to take time away from Signals (even if it means we don't get to it at all this meeting) |
07:50 | <Ben> | The DurationForrmat update is not going to even come close to filling its timebox, so that clears up time this afternoon |
07:51 | <Ben> | (I've reached out to Ujjwal about this) |
07:51 | <nicolo-ribaudo> | Duncan MacGregor When comparing floats there is the same beahvior: 1 < NaN is false, 1 > NaN is false, and 1 == NaN is false, so compare cannot return neither -1, nor 0, nor 1. |
07:53 | <mgaudet> | I'd like us to not over-rotate on API design based on the temporal experience |
07:54 | <nicolo-ribaudo> | Chrome is working on shipping the web neural network API, that has all the comparisons :) |
07:55 | <nicolo-ribaudo> | (just to put feedback on Chrome's code size into perspective) |
07:55 | <waldemar> | If we don't provide an equals method, users will test for = and ≠ via compare(…) == 0 and compare(…) != 0 respectively. This produces incorrect results. |
07:56 | <rbuckton> | Stage 1 is scouting the terrain and coming up with a battle plan. Stage 2 is starting the long march to battle and preparing fortifications. Stage 2.7 is checking your gear before the battle starts. Stage 3 is when you see how much of your plan survives contact with the enemy. Stage 4 is the parade. |
07:56 | <Duncan MacGregor> | Duncan MacGregor When comparing floats there is the same beahvior: Array.prototype..sort() turn a Nan value as +0. |
07:56 | <nicolo-ribaudo> | Ah right. Too used to comparison methods which return an int and so cannot return NaN. It is also worth noting that things like |
07:58 | <Chris de Almeida> | Eemeli's comment makes it sound like it's a foregone conclusion that a new primitive is not possible |
07:59 | <Chris de Almeida> | facts? |
07:59 | <ljharb> | that is browsers' position as i understand it, yes |
07:59 | <ljharb> | (which impacts both R&T and Decimal) |
08:00 | <nicolo-ribaudo> | I understand browsers position as "a primitive only makes sense if we see proof that it's actually going to be widely used", and I hope that decimal objects getting adoption will fulfill that |
08:00 | <Duncan MacGregor> | The .sort behavior seems good with the .compare behavior: "I don't know how to compare these two things, so I don't shuffle them around" |
08:01 | <Rob Palmer> | I do not see any route to convincing browsers that the juice is worth the squeeze on Decimal, other than the incremental route of proving it out first in API form. |
08:01 | <ljharb> | it can be proved out, though, without being in the spec - that's what npm is for |
08:01 | <Michael Ficarra> | The .sort behavior seems good with the .compare behavior: "I don't know how to compare these two things, so I don't shuffle them around" |
08:01 | <Chris de Almeida> | I do not see any route to convincing browsers that the juice is worth the squeeze on Decimal, other than the incremental route of proving it out first in API form. |
08:02 | <ljharb> | this constraint on primitives is pretty new so i'm not sure there is any precedent |
08:03 | <nicolo-ribaudo> | Ugh, that's annoying. In wonder wether we could extend the definition of consistent comparators to include "some values can consistently not be compared with any other value" |
08:03 | <Chris de Almeida> | it would be nice to hear from vendors if that sort of signal |
08:03 | <nicolo-ribaudo> | Because, NaN returned from .compare happens if and only if one of the arguments is a NaN |
08:04 | <nicolo-ribaudo> | I would have to check if implementations in practice are already doing it |
08:04 | <Richard Gibson> | very much related: https://matrix.to/#/!wbACpffbfxANskIFZq:matrix.org/$oOM8aZZATkGRuYJ1QzLp2veLMwV3yXlD1275Z1d6nBs?via=matrix.org&via=mozilla.org&via=igalia.com
|
08:04 | <nicolo-ribaudo> | Infinity - Infinity is NaN, right? |
08:04 | <Richard Gibson> | right |
08:05 | <Duncan MacGregor> | Yes |
08:05 | <Richard Gibson> | which is treated as zero, i.e. same-sign infinities are not differentiated by that kind of sorting |
08:06 | <waldemar> | agree, and I disagree with the characterization that we are having a meta discussion on process. we are talking about this proposal and what appear to be blocking possibly based on stage 2.7 or 3 entrance criteria rather than stage 2 |
08:06 | <eemeli> | Eemeli's comment makes it sound like it's a foregone conclusion that a new primitive is not possible |
08:07 | <Duncan MacGregor> | So the JVM's position on this is
|
08:09 | <Duncan MacGregor> | It ends up putting all the doubles at the end of a sorted array, which also seems to be what I see in Array.prototype.sort() implementations. |
08:09 | <Chris de Almeida> | That's an unfair characterization. A lot of folks making this claim are making assumptions about what's currently working and what isn't working in the spec. |
08:10 | <waldemar> | The spec is not even in a good enough state for Shane to be able to read and understand it. |
08:10 | <rbuckton> | Could we add Decimal as a class and later add a primitive version for it if we block off relevant functionality to allow for it in the future? i.e., you have to write new Decimal() for now while Decimal() and Decimal.prototype.valueOf() throw, and later we add decimal primitives treating new Decimal as the boxed primitive version? That would give us the opportunity to ship it and prove out its utility in the ecosystem. IIRC, shu's concern was that BigInt added too much complexity for something whose only significant use ended up being for unscrupulous cryptocurrency mining. |
08:11 | <littledan> | waldemar: What do you think about "conditional Stage 2" on fixing those spec issues? |
08:11 | <waldemar> | waldemar: What do you think about "conditional Stage 2" on fixing those spec issues? |
08:12 | <waldemar> | I want this to go to stage 2. It's just not ready at the moment, but it's getting there quickly. |
08:12 | <littledan> | That's fine by me. |
08:13 | <Duncan MacGregor> | I'm not convinced by the argument that Decimal is a good answer to solving rounding issues seen by inexperienced developers, but I do understand that Decimal is a good answer to a particular set of problems. |
08:14 | <littledan> | I think the existing libraries have tons of downloads, but maybe that is partly because of people depending on them when they don't really need them |
08:15 | <hax (HE Shi-Jun)> | About the diff with Decimal128 and Temporal, I think it's how people expect. For Decimal128 in non-primitive form, people will say: WTF! For Temporal, people will say: ok, it at least much much better than Date! |
08:15 | <Chris de Almeida> | 13,603,794 weekly downloads is tons or no? |
08:15 | <ljharb> | looking around on npm, i do see https://www.npmjs.com/package/bignumber.js which has 11m downloads, which is a pretty decent number |
08:15 | <jkup> | https://www.npmjs.com/package/decimal.js, https://www.npmjs.com/package/big.js, https://www.npmjs.com/package/bignumber.js |
08:15 | <sffc> | The spec intelligibility issues are not egregious enough to get in the way of Stage 2 for me; I think the committee sending a positive signal by promoting to Stage 2 is more important at this point in time |
08:15 | <jkup> | 50mil |
08:16 | <ljharb> | and indeed decimal.js has 17 million |
08:16 | <ljharb> | so that's a great indicator, thank you. (i'd still want the proposal readme to have a list ofc) |
08:16 | <littledan> | the polyfill is not being developed in a way where it intends to compete with other decimal libraries |
08:17 | <ljharb> | oh sure, i don't care that a specific package has low usage, to be clear, i just was not aware that any were significantly used; those 3 high-usage examples certainly addresses the "demand" point for me (but still not the "carries its weight" part) |
08:17 | <Luca Casonato> | the polyfill is not being developed in a way where it intends to compete with other decimal libraries |
08:17 | <Chris de Almeida> | might need to invite MikeMcl to the chat at some point |
08:17 | <nicolo-ribaudo> | The goal of the polyfill is to have spec-compliant semantics, not to be an optimized production-ready implementation Luca Casonato |
08:18 | <nicolo-ribaudo> | Same for temporal for example |
08:18 | <rbuckton> | Lets just add a single new primitive type that covers flexible user-defined data types and operator overloading and just base all other new primitives on that. |
08:18 | <nicolo-ribaudo> | Let's call this primitive "object" :) |
08:18 | <Luca Casonato> | oh i misread polyfill as spec 🤦♂️ |
08:19 | <Luca Casonato> | i read "this spec is not being developed in a way where it intends to compete with other decimal libraries" |
08:19 | <rbuckton> | Honestly, this was one of the things I wanted to do with my version of the struct proposal prior to Shu's version. |
08:19 | <Duncan MacGregor> | So I can say that operator overloading is a significant implementation overhead in Ruby, and we try very hard to boil it away as much as we can. It's tempting, but it has real downsides. |
08:19 | <rbuckton> | I would have just called the primitive "value" |
08:20 | <ljharb> | "tempting but has real downsides" is an understatement in my experience on both parts in any language i've used with the feature |
08:20 | <Duncan MacGregor> | 🤣 |
08:20 | <nicolo-ribaudo> | So I can say that operator overloading is a significant implementation overhead in Ruby, and we try very hard to boil it away as much as we can. It's tempting, but it has real downsides. |
08:20 | <ljharb> | i suspect that would remove a lot of the downsides |
08:22 | <Duncan MacGregor> | It would probably have to be lexically scoped to restrict the overhead to where you need it |
08:23 | <rbuckton> | Question to implementers, when bigint was added along with its necessary operator overloads, how much of an impact on performance did that have for other javascript code that didn't make use of bigint ? |
08:23 | <keith_miller> | Scoped overloads seems like a footgun how does a library support overloading in that case? |
08:24 | <ljharb> | i suppose it'd provide exports that can be "activated" inside a scope with syntax |
08:24 | <keith_miller> | Question to implementers, when |
08:24 | <ljharb> | like a special decorator or something |
08:24 | <keith_miller> | Or it wouldn't have shipped |
08:25 | <keith_miller> | On the === front you could say that if object identity is equal then it doesn't call your overload. I don't think that's a crazy rule. |
08:25 | <keith_miller> | littledan: CC^ |
08:25 | <Duncan MacGregor> | AFAIK, none |
08:25 | <littledan> | I think browsers want to be able to return "false" fast |
08:26 | <nicolo-ribaudo> | When we talk about performance, do we also include "time from when the user clicks on a link to when the page is available"? (i.e. loading time) |
08:26 | <nicolo-ribaudo> | Or just runtime performance? |
08:26 | <keith_miller> | You already have to look into your object to figure out if it's a string or BigInt though |
08:26 | <Duncan MacGregor> | I think we mean both. |
08:26 | <keith_miller> | At that point you can check for overloading, without too much cost in an IC |
08:27 | <rbuckton> | If we did provide a user-defined primitive capability with operator overloading in a similar vein, would it then be reasonable to assume that all performance overhead would be in interactions with those primitives, and not all other JS? |
08:28 | <keith_miller> | I don't understand what you mean by "user-defined primitive capability"? |
08:28 | <hax (HE Shi-Jun)> | something close to Tuple/Record |
08:29 | <Ashley Claymore> | Record & Tuple was also blocked from being a primitive |
08:29 | <keith_miller> | It would still be an object though so it's not really a primitive. It just looks kinda like a primitive unless you squint |
08:29 | <rbuckton> | I don't understand what you mean by "user-defined primitive capability"? |
08:29 | <Duncan MacGregor> | Oh, the area where we would likely see a performance degradation is if people can define new cases involving the existing primitives. |
08:30 | <mgaudet> | (Personal Hat on): User defined primitives are a fascinating design space that I think would provide a lot of value, and potentially could be done -- a path I would propose would be abstracting BigInt such that you could re-host BigInt atop the abstraction, then provide user access to the abstraction. But there's many, many dragons here |
08:30 | <rbuckton> | It would still be an object though so it's not really a primitive. It just looks kinda like a primitive unless you squint |
08:30 | <mgaudet> | (c.f. Project Valhalla etc) |
08:31 | <hax (HE Shi-Jun)> | For the purpose of this discussion, I mean some bespoke syntax to declare a user-defined "primitive" type, much like a class, except it isn't Object. |
08:31 | <Duncan MacGregor> | (c.f. Project Valhalla etc) |
08:31 | <rbuckton> | With the caveat that operator overloads on a user-defined "primitive" will likely be far slower than native primitives. |
08:31 | <Michael Ficarra> | I see where Jordan's coming from. I believe this proposal is much less motivated without the primitive. But I still think it is motivated enough by its other merits, and there is a path to a primitive in the future, so I support it. |
08:31 | <mgaudet> | Trigger warning, please. 😀 |
08:33 | <keith_miller> | Oh, the area where we would likely see a performance degradation is if people can define new cases involving the existing primitives. number + number |
08:33 | <keith_miller> | For both performance and sanity reasons |
08:33 | <rbuckton> | You don't pay the cost of operator overloading for all Objects, only this different thing. If you want to define a "primitive"-like type with operator overloading, you use this and not Object. Implementations only have to plumb this through once and it is a catch-all for any "primitive"-like type we might want to include in the standard library as well. |
08:34 | <Duncan MacGregor> | Yeah, I DEFINITELY don't think we can let users change e.g. |
08:34 | <rbuckton> | Yeah, I DEFINITELY don't think we can let users change e.g. |
08:34 | <ljharb> | what if both operands have a different overload? |
08:34 | <Duncan MacGregor> | That's another dragon. |
08:35 | <keith_miller> | You could say both have to have the same function? |
08:35 | <Duncan MacGregor> | Ruby does it by operators really being methods |
08:35 | <keith_miller> | Or an exception |
08:35 | <keith_miller> | idk |
08:35 | <Duncan MacGregor> | Other langauges do multi-argument dispatch |
08:35 | <rbuckton> | But if I have a matrix type I'd definitely want to be able to define number * matrix… This is where the dragons are. |
08:36 | <rbuckton> | We've investigated various mechanisms for operator overloading in the past. |
08:39 | <keith_miller> | But if I have a matrix type I'd definitely want to be able to define number * matrix… This is where the dragons are. object <op> primitive calling some overload too |
08:39 | <keith_miller> | But maybe there's dragons there I haven't thought through |
08:39 | <Luca Casonato> | Can someone advance the queue? |
08:40 | <littledan> | You don't pay the cost of operator overloading for all Objects, only this different thing. If you want to define a "primitive"-like type with operator overloading, you use this and not Object. Implementations only have to plumb this through once and it is a catch-all for any "primitive"-like type we might want to include in the standard library as well. |
08:40 | <rbuckton> | I had a very early draft for operator overloading syntax in my original
NOTE that this is not being considered for the current |
08:41 | <littledan> | sure if there's an easy to check tag on the object that says whether it has overloading |
08:42 | <mgaudet> | (There's another dimension here to operators, which is also identity; primitives bring both operators and a lack of identity, and there's no ability as a user to create a user-defined-thing that has no identity too -- c.f. earlier R&T) |
08:43 | <rbuckton> | Though I did spend some time fleshing out what a user-defined "primitive" might look like in my old struct proposal: https://github.com/rbuckton/proposal-struct |
08:43 | <keith_miller> | You don't pay the cost of operator overloading for all Objects, only this different thing. If you want to define a "primitive"-like type with operator overloading, you use this and not Object. Implementations only have to plumb this through once and it is a catch-all for any "primitive"-like type we might want to include in the standard library as well. |
08:43 | <mgaudet> | (a lack of identity also ties in immutability too) |
08:43 | <keith_miller> | But maybe that's different for other engines |
08:44 | <Duncan MacGregor> | Lack of guaranteed identity seems like a relatively small problem. |
08:44 | <mgaudet> | Lack of guaranteed identity seems like a relatively small problem. |
08:44 | <Richard Gibson> | Yeah, I could see |
08:44 | <rbuckton> | But maybe that's different for other engines with operators from ... syntax that littledan had proposed was primarily to address performance concerns raised by some implementations |
08:45 | <littledan> | My understand was that the |
08:45 | <littledan> | it's also to address the behavior injection concerns from a design/correctness perspective |
08:45 | <Duncan MacGregor> | Right, records, tuples, value decorators (hard for JS as there aren't good immutability guarantees without R&T…) lots of ways to do it in VM implementations. |
08:48 | <keith_miller> | My understand was that the Symbol.add but I'd have to hear the exact performance objections. I would imagine Symbol.add would behave the same as a getter in the IC. Most engines already have the infrastructure for getters so I'm a bit surprised such code couldn't be generalized for operators. |
08:49 | <rbuckton> | When I put together my old struct proposal I was looking for a way to unify the mechanics for R&T, a Decimal primitive, maybe Temporal as a "primitive", and other user-defined "primitive" types. |
08:49 | <littledan> | with operators from means a lot of requirements for bookkeeping. But it's easy to see when you're not inside of those things and you can use the ICs which don't have support for the new operator overloaded things |
08:51 | <rbuckton> | If we did have operator overloading, I'd much rather restrict it to a specific domain of values than support with operators from . with operators from would be a mess for TypeScript. |
08:52 | <keith_miller> | |
08:52 | <rbuckton> | And that's just type checking, we wouldn't downlevel operator overloading it would be to expensive based on our "no type-based emit" policy. |
08:52 | <keith_miller> | But, that said, I'm only intimately familiar with JSC's ICs |
08:53 | <littledan> | The whole point of ICs is that you only generate the cases you've seen though. So, I'm a bit surprised that would help anything. |
08:53 | <Duncan MacGregor> | I think the thing I wouldn't like about trying to add operator overloading to JS as currently defined is that we do various coercions on the two arguments and then perform the operation. Ruby and Python both tree all this stuff as a simple method call, so it is simply up to the left operand what is done to the right operand. |
08:54 | <keith_miller> | oh sorry I don't mean ICs, I guess I mean paths in the interpreter or something |
08:55 | <keith_miller> | Once you're in the non-primitive not-equal pointer case you're already doing slow stuff |
08:56 | <keith_miller> | Again, that's just JSC not necessarily other engines |
08:56 | <rbuckton> | Oh, also, my old struct proposal required "typed" field definitions to handle cases like size, alignment, packing, etc. You could, in theory, support === using the memory contents of the value. |
08:57 | <keith_miller> | I think the thing I wouldn't like about trying to add operator overloading to JS as currently defined is that we do various coercions on the two arguments and then perform the operation. Ruby and Python both tree all this stuff as a simple method call, so it is simply up to the left operand what is done to the right operand. |
08:58 | <Duncan MacGregor> | Why is it necessary to do coercions? GetValue and then ToPrimitive (which of course we don't actually need to do most of the time). |
08:59 | <nicolo-ribaudo> | Michael Ficarra I was going to answer that this is more of a question for the existing stage 3 proposal, that adds the concept of "sources" and wasm is already using it. This new proposal is only for defining what a JS source is. However, Guy can probably still answer that (I know well how this proposal works for JS, but my Wasm knowledge is more limited 😛) |
09:00 | <Michael Ficarra> | yeah but this is the first to introduce an import syntax, right? |
09:00 | <Duncan MacGregor> | So at the moment we do |
09:00 | <nicolo-ribaudo> | yeah but this is the first to introduce an import syntax, right? |
09:00 | <nicolo-ribaudo> | This only defines what using that syntax for importing JS files does |
09:00 | <Michael Ficarra> | oh maybe I'm confused |
09:00 | <Michael Ficarra> | can you send me a link? |
09:00 | <keith_miller> | The fact those are just used in operator coercion means we'd need to come up with a new way to spec that, and work out whether we look for overloads before or after doing those conversion. |
09:00 | <Michael Ficarra> | there's so many of these module proposals |
09:01 | <nicolo-ribaudo> | Stage 3: https://github.com/tc39/proposal-source-phase-imports this: https://github.com/tc39/proposal-esm-phase-imports/ |
09:01 | <nicolo-ribaudo> | there's so many of these module proposals |
09:04 | <Michael Ficarra> | Sorry about that, the space is huge and we ended up trying to split it in "independently motivated incremental changes", but maybe it ended up not being the best way 😅 |
09:05 | <nicolo-ribaudo> | I'm legitimately still confused 😭 |
09:05 | <Michael Ficarra> | Let's talk about that during lunch? :) |
09:08 | <jkup> | yes, please help me |
10:01 | <Christian Ulbrich> | Could someone from Zoom plz. post the slide deck link, here? |
10:08 | <Ashley Claymore> | cc Ben |
10:09 | <Ben> | https://notes.igalia.com/p/pj5uX_5nC#/ |
10:17 | <Duncan MacGregor> | Going back through meeting notes I have found the first reference to operator overloading and decimal here in section 9.iv.b "Decimal for stage 0". keith_miller . |
10:26 | <nicolo-ribaudo> | Going back through meeting notes I have found the first reference to operator overloading and decimal here in section 9.iv.b "Decimal for stage 0". keith_miller . |
10:27 | <nicolo-ribaudo> | And then https://web.archive.org/web/20161227042517/http://wiki.ecmascript.org/doku.php?id=proposals:operators some years later |
10:33 | <Michael Ficarra> | the problem with underscore is that you can't avoid shadowing an outer underscore variable |
10:33 | <Michael Ficarra> | void doesn't have this problem |
10:34 | <Michael Ficarra> | like I get the people who want underscore for aesthetics, but it's technically strictly worse |
10:34 | <shu> | get a custom ligature font that converts void to _ |
10:35 | <Duncan MacGregor> | It's much older (2002-04): https://web.archive.org/web/20161227042517/http://www.mozilla.org/js/language/js20-2002-04/core/operators.html Oh yeah, that was just the first ref I could find to operator overloading with reference to the decimal proposal, with a very FLT like comment
|
10:39 | <shu> | Michael Ficarra: i really do not think void operator is a thing JS developers know about? |
10:40 | <shu> | like the extent to which people will know about it is using (void 0) as an incantation for undefined |
10:40 | <nicolo-ribaudo> | Sometimes we get questions in Babel about what's that void 0 thing that we generate so much in our output |
10:40 | <jkup> | feeling a lot less imposter syndrome having just googled "mdn void operator" |
10:41 | <Richard Gibson> | https://github.com/search?q=%2F%5Cbvoid+%5Ba-z_%5D%2F+language%3AJavaScript+&type=code |
10:42 | <Richard Gibson> | looks like mostly minified code, but there is definitely intentional use |
10:42 | <Michael Ficarra> | other than void 0, void is often used in front of IIFEs or in arrow concise bodies |
10:43 | <nicolo-ribaudo> | Those results are mind blowing |
10:43 | <nicolo-ribaudo> | There are so many usages of void e in the catch block in a statement position |
10:43 | <nicolo-ribaudo> | I assume it's to workaround bad linters before that the catch binding was optional |
10:43 | <nicolo-ribaudo> | Than, many of the results "for JS" are actually C code 😛 |
10:44 | <Michael Ficarra> | this is a really good example from those search results |
10:44 | <shu> | yeah those results are quite surprising to me as well, fascinating |
10:46 | <Richard Gibson> | void undefined at https://github.com/inspect-js/is-equal/blob/1b8f8f4ffe6e652b0bce57b4563237c90898b150/why.js#L244 🙃 |
10:46 | <Michael Ficarra> | okay lol not all of them are good |
10:47 | <Michael Ficarra> | who knows, maybe there's a var undefined in there somewhere |
10:47 | <nicolo-ribaudo> | sent an image. |
10:47 | <nicolo-ribaudo> | https://github.com/everthis/tpp_script/blob/1e4b0f02adea066ccdb21df4a857ec9e2fe2fcd0/um.js#L1219 |
10:48 | <shu> | lol um.js is a great name |
10:48 | <jkup> | I like that the two most interesting examples are a why.js file and an um.js file |
10:51 | <sffc> | I searched over some large JS codebases I've worked on and I didn't find any references to void , except where it is used in TypeScript to mean "this function does not return a value" |
10:51 | <Ashley Claymore> | To explicitly not want to handle a promise https://typescript-eslint.io/rules/no-floating-promises/ void somePromiseChain |
10:56 | <Richard Gibson> | void undefined at https://github.com/inspect-js/is-equal/blob/1b8f8f4ffe6e652b0bce57b4563237c90898b150/why.js#L244 🙃 |
10:56 | <Ashley Claymore> |
I don't think that is true for SpiderMonkey, their tagging includes that info AFAIK |
10:57 | <Ashley Claymore> | belt and braces |
10:58 | <Duncan MacGregor> | I think I've seen Java code with annotations to suppress unnecessary type casts, which feels similar. |
11:10 | <Ashley Claymore> | note: we'll need to merge https://github.com/tc39/notes/pull/326/files for the meeting notes to pass CI when that time comes |
11:11 | <Michael Ficarra> | is that who was just speaking? |
11:11 | <nicolo-ribaudo> | Yes |
11:11 | <ryzokuken (TC39 🇫🇮)> | is there any reason not to just merge it right away? |
11:12 | <nicolo-ribaudo> | is there any reason not to just merge it right away? |
11:12 | <ryzokuken (TC39 🇫🇮)> | this issue means they were accepted as IE |
11:12 | <ryzokuken (TC39 🇫🇮)> | and are being onboarded |
11:13 | <ryzokuken (TC39 🇫🇮)> | done |
11:24 | <Ashley Claymore> | resume at hh:40 |
11:46 | <Michael Ficarra> | @ryzokuken (TC39 🇫🇮) please advance the queue so I can reply |
11:46 | <ryzokuken (TC39 🇫🇮)> | Michael Ficarra to waldemar's? |
11:46 | <ryzokuken (TC39 🇫🇮)> | ah yes nvm |
11:46 | <Michael Ficarra> | yes that's the topic we're on |
11:56 | <Chris de Almeida> | sounds like a good rule for the nascent guide to writing good spec text 🧐 |
11:59 | <nicolo-ribaudo> | I think the spec should not change meaning if you remove all green notes -- they should just clarify what you can otherwise infer |
12:07 | <Michael Ficarra> | @littledan please try not to jump queue topics like that |
12:07 | <littledan> | what? I was on the queue |
12:07 | <Michael Ficarra> | I really don't like when people read a TCQ topic and try to pre-reply to it, assuming what the person was going to say |
12:07 | <littledan> | sorry |
12:08 | <Michael Ficarra> | it's also speaking out of turn IMO |
12:08 | <littledan> | you mean how I used replies? |
12:09 | <littledan> | OK I'll be more careful about that, thanks |
12:09 | <Michael Ficarra> | if we have two topics, A and B, in TCQ in that order, a reply to A (or the submitter of topic A if different from B) shouldn't try to also address B before B has been introduced |
12:09 | <littledan> | oh, about testing? right, sorry I didn't want to presume what you were going to say, but yes my comment was off-topic for what I had put on the queue |
12:10 | <Michael Ficarra> | yes, thank you |
12:10 | <littledan> | (I had wanted to make that point independently from whether I was responding to you, just with respect to what Shu and Keith seemed to be assuming about the implications of normative text) |
12:11 | <keith_miller> | I guess I don't understand the point of having normative text that has no requirement? |
12:11 | <Michael Ficarra> | I have no hard feelings, it's just every time it happens, it makes me feel more pressure to fully express myself in the topic so nobody pre-replies to me with a misinterpretation of what I want to say |
12:12 | <littledan> | I guess I don't understand the point of having normative text that has no requirement? |
12:13 | <nicolo-ribaudo> | And Atomics.pause does have behavior, you just cannot test it within JS. Otherwise we wouldn't have this proposal at all |
12:13 | <keith_miller> | The notes should be for context; reading the normative text should be enough to build an implementation, even if we can't have tests for it |
12:14 | <littledan> | specs are allowed to say "should", it's not must or nothing. There's more that the spec can say than "does this conform, yes or no" |
12:14 | <littledan> | these are just communication devices for humans |
12:15 | <nicolo-ribaudo> | Example: step 7 of https://tc39.es/ecma262/#sec-suspendthisagent |
12:16 | <nicolo-ribaudo> | It waits for some time |
12:16 | <nicolo-ribaudo> | Example: step 7 of https://tc39.es/ecma262/#sec-suspendthisagent |
12:17 | <nicolo-ribaudo> | And the time in that case is implementation-defined (see step 24 of https://tc39.es/ecma262/#sec-dowait) |
12:18 | <keith_miller> | Example: step 7 of https://tc39.es/ecma262/#sec-suspendthisagent |
12:18 | <hax (HE Shi-Jun)> | what is p1/p2 in the slide? |
12:18 | <littledan> | what is p1/p2 in the slide? |
12:18 | <keith_miller> | I think it's a typo |
12:18 | <rbuckton> | what is p1/p2 in the slide? p1 is this and p2 is p |
12:23 | <justingrant> | Yeah, this change was made by the IANA TZDB maintainers in 2015. Of all the intra-country merges, I do wish we could find some principled excuse to make this exception for my Quebcois friends (my current startup is based in Montreal) while not opening the door for 100+ other intra-country merges that are justified. |
12:23 | <keith_miller> | That's definitively observable though. So it has actual requirements and is testable. Atomics.pause is outside the engine's or even OS's control in the third box. So would be impossible to do. Unless you want it to say is "For integral numbers N, Atomics.pause(N) should attempt to wait at most as long as Atomics.pause(N+1)."? Then I would agree that has some meaning. |
12:23 | <littledan> | yes, I agree that this "should" needs to be super non-binding. "should attempt to" SGTM. |
12:25 | <nicolo-ribaudo> | Yes I would be ok with that text |
12:25 | <keith_miller> | The first box would have to be something like: "Implementations are expected to implement a pause or yield instruction if some version of the best practices of the underlying architecture recommends such instructions in spin loops." |
12:25 | <justingrant> | The context is that adding Zones in TZDB was originally done pretty much arbitrarily. And the volunteer maintainer (Paul Eggert) who has maintained for the last 15 years has been trying to prune it ever since, using a basic rule that if rules have been the same since 1/1/1970 then they get merged. |
12:26 | <nicolo-ribaudo> | The question is: if you were to delete the green notes, would your implementation still behave the same as if you are implementing it by also taking the green notes into account? |
12:26 | <nicolo-ribaudo> | The answer should be "yes" |
12:26 | <keith_miller> | Since the best practices can change over time and the engine may not know the best practices for the particular CPU it's targeting |
12:26 | <hax (HE Shi-Jun)> | If we have such auto correlation incantation, could it also apply to normal class?? 😃 |
12:27 | <rbuckton> | If we have such auto correlation incantation, could it also apply to normal class?? 😃 |
12:28 | <keith_miller> | The question is: if you were to delete the green notes, would your implementation still behave the same as if you are implementing it by also taking the green notes into account? |
12:28 | <keith_miller> | Should they be considered non-spec compliant? |
12:29 | <nicolo-ribaudo> | |
12:29 | <nicolo-ribaudo> | N is for |
12:30 | <nicolo-ribaudo> | Oh I misread |
12:30 | <nicolo-ribaudo> | Should they be considered non-spec compliant? |
12:30 | <nicolo-ribaudo> | But that doesn't mean that the spec text shouldn't clearly communicate the intention / recommended behavior |
12:32 | <Luca Casonato> | rbuckton: is the manual correlation token the same as Mechanism 1? or was Mechanism 1 "manually add the prototype to all incoming shared structs"? I couldn't quite tell |
12:32 | <rbuckton> | Not quite the same, no |
12:33 | <Luca Casonato> | ok, so then i don't understand Mechanism 1 I think |
12:33 | <littledan> | The first box would have to be something like: "Implementations are expected to implement a pause or yield instruction if some version of the best practices of the underlying architecture recommends such instructions in spin loops." |
12:34 | <keith_miller> | If that's the consensus then I don't have a problem with normative should. Although, I would prefer a recommends but maybe should is well defined enough in TC39? |
12:34 | <littledan> | ok, so then i don't understand Mechanism 1 I think |
12:34 | <hax (HE Shi-Jun)> | No, how could it? Classes aren't shareable. |
12:34 | <littledan> | If that's the consensus then I don't have a problem with normative should. Although, I would prefer a recommends but maybe should is well defined enough in TC39? |
12:34 | <Luca Casonato> | no, it's like, at startup, thread A sends a message to thread B containing some magical reference to the Point class, and thread B hooks up that reference to its Point class |
12:34 | <Luca Casonato> | we'd still need some "key" for each shared struct? |
12:34 | <Ashley Claymore> | Something something module declarations |
12:35 | <littledan> | we'd still need some "key" for each shared struct? |
12:35 | <littledan> | but yes this is breaking new ground for postMessage |
12:35 | <mgaudet> | To clarify for myself.. if you don't have auto correlation, but you have imported the module on main and worker... it's just that points which are post-messaged will have no prototype; right? |
12:35 | <Luca Casonato> | ok - i still don't quite see how this isn't exactly the same as the auto correlation key |
12:36 | <littledan> | ok - i still don't quite see how this isn't exactly the same as the auto correlation key |
12:36 | <Luca Casonato> | oh i guess that each realm does not need to automatically resolve to the same key |
12:36 | <keith_miller> | either seems fine to me, I don't know what the difference is tbh |
12:36 | <Luca Casonato> | the shared structs on either side do not have to have the same "identity" - you manually have to tie the identities together? |
12:36 | <mgaudet> | (and, I have forgotten a bit) and if you don't import on a worker, and you recieve a shared struct... you can read them like they're just POJOs with a null proto? |
12:37 | <littledan> | ok - i still don't quite see how this isn't exactly the same as the auto correlation key |
12:37 | <littledan> | (and, I have forgotten a bit) and if you don't import on a worker, and you recieve a shared struct... you can read them like they're just POJOs with a null proto? |
12:37 | <littledan> | or maybe a "[[Prototype]] which throws" |
12:37 | <rbuckton> | To clarify for myself.. if you don't have auto correlation, but you have imported the module on main and worker... it's just that points which are post-messaged will have no prototype; right? |
12:37 | <littledan> | Not just postmessage. You can just set a shared struct value into a field on an existing shared struct |
12:38 | <mgaudet> | rbuckton: Ah that's a helpful reminder too |
12:39 | <rbuckton> | right, this is why the only thing needed with postMessage is this one-time setup |
12:40 | <Mathieu Hofman> | manual correlation does not have to weaken privacy |
12:41 | <rbuckton> | And I think having private state is an important capability for encapsulation, such as ensuring a field is only read/written atomically or under a lock via a method on the struct. |
12:41 | <Duncan MacGregor> | manual correlation does not have to weaken privacy |
12:42 | <littledan> | yeah I can see how autocorrelation could help us with private field sharing, but I don't see how we'd do it with manual sharing |
12:42 | <Mathieu Hofman> | You have to reify a sharable object for the type that describes the capability to attach behavior and access private data (that is not reachable simply from having an instance, or even the constructor) |
12:42 | <nicolo-ribaudo> | I would consider the identity of a ModuleSource to be specifier+(id of the realm where it was originally created), and not just the specifier |
12:42 | <nicolo-ribaudo> | Which means that what I and Dan said is not the same behavior |
12:43 | <littledan> | right so in particular it's much more convenient if you don't have to pass along the handle, and can just independently import the same specifier and have it autocorrelate |
12:43 | <nicolo-ribaudo> | Yes I agree it's more convenient |
12:43 | <nicolo-ribaudo> | It's also more magical |
12:43 | <littledan> | yes, so, the mechanism you're describing is a way to do a handshake without exposing "too powerful" APIs |
12:44 | <nicolo-ribaudo> | Yes right |
12:44 | <littledan> | somehow in between the two mechanisms |
12:44 | <littledan> | (and corresponds to what I proposed a while ago) |
12:44 | <Mathieu Hofman> | right, I would like "a type admin capability" to the basis of the implementation, and then we can consider sugar on top |
12:45 | <littledan> | what nicolo-ribaudo is proposing would give us plenty of rope to implement sharing private field names |
12:45 | <littledan> | but a more imperative mechanism would not |
12:46 | <Mathieu Hofman> | Not really if you start to consider wasm, and how some wasm code would correlate the type |
12:46 | <Mathieu Hofman> | a more imperative mechanism can conceptually give you access to private data (maybe not fields per se) |
12:47 | <littledan> | well, currently Wasm doesn't need to correlate types because it's all structural. But if it gets some nominal capacity, why not transmit it by postMessaging WebAssembly.Module instances? I guess the thing is, they don't contain any reference to their Realm/Agent right now. |
12:48 | <littledan> | (I really want Wasm to get this nominal capacity) |
12:48 | <rbuckton> | Yeah, do we know how it was thought it would? |
12:48 | <Mathieu Hofman> | well, currently Wasm doesn't need to correlate types because it's all structural. But if it gets some nominal capacity, why not transmit it by postMessaging WebAssembly.Module instances? I guess the thing is, they don't contain any reference to their Realm/Agent right now. |
12:49 | <littledan> | What restricts a module to contain only a single shared struct definition? |
12:49 | <littledan> | similar to us correlating by Parse Node |
12:50 | <littledan> | so it would be by specifier + allocating agent/realm + index |
12:52 | <Mathieu Hofman> | That really seems like forcing JS specific concepts onto wasm. Does that mean wasm needs a JS module if it wants to correlate types between its own threads ? |
12:53 | <littledan> | Wasm as agents and specifiers; not sure what you mean |
12:54 | <littledan> | Wasm on the web (theoretically, with ESM integration) has a module map per Realm, so it'd be natural to use that rather than agent |
12:55 | <Duncan MacGregor> | I'm glad it's not just me who didn't understand that thread safety argument. |
13:03 | <rbuckton> | littledan: I think auto-correlation could handle privacy just fine. |
13:03 | <littledan> | littledan: I think auto-correlation could handle privacy just fine. |
13:04 | <littledan> | I think nicolo-ribaudo 's handshake mechanism would also handle it fine. It's "even more lexical". |
13:04 | <nicolo-ribaudo> | I think nicolo-ribaudo 's handshake mechanism would also handle it fine. It's "even more lexical". |
13:05 | <Mathieu Hofman> | How would auto correlation work across languages in a way that doesn't require either language to hold objects specific to the other language (as each language may run without the other existing) |
13:06 | <rbuckton> | My concern with manual correlation (i.e., based on postMessage/exemplars) is that realm B could wire up a struct from realm A into a struct definition that exposes private state, so you have to guard against malicious code being able to spawn a Worker (CSP helps on the web, but not in NodeJS) that can be used to hijack a struct. |
13:06 | <Mathieu Hofman> | Aka how would 2 wasm threads correlate shared structs (to get access private data) without requiring it to know what a JS module is |
13:07 | <littledan> | My concern with manual correlation (i.e., based on postMessage/exemplars) is that realm B could wire up a struct from realm A into a struct definition that exposes private state, so you have to guard against malicious code being able to spawn a Worker (CSP helps on the web, but not in NodeJS) that can be used to hijack a struct. |
13:07 | <rbuckton> | How would auto correlation work across languages in a way that doesn't require either language to hold objects specific to the other language (as each language may run without the other existing) |
13:08 | <shu> | Does it need to work across languages? If JS private state is a uniquely JS mechanism, then WASM could interact with the struct via FFI calls into JS. |
13:08 | <littledan> | Does it need to work across languages? If JS private state is a uniquely JS mechanism, then WASM could interact with the struct via FFI calls into JS. |
13:08 | <shu> | you do some tearoffs that can exfiltrate private data and import them from the wasm side |
13:08 | <Mathieu Hofman> | My concern with manual correlation (i.e., based on postMessage/exemplars) is that realm B could wire up a struct from realm A into a struct definition that exposes private state, so you have to guard against malicious code being able to spawn a Worker (CSP helps on the web, but not in NodeJS) that can be used to hijack a struct. |
13:09 | <shu> | Mathieu Hofman: you're engaged in the nuts & bolts of how correlation could work. great! but i'm more interested in working through the very high level, "i feel this is unsafe" objection |
13:10 | <Mathieu Hofman> | Does it need to work across languages? If JS private state is a uniquely JS mechanism, then WASM could interact with the struct via FFI calls into JS. |
13:10 | <rbuckton> | some form of nominal correlation would be useful for Wasm, especially if Wasm wants to interact with JS in various threads and give prototypes to its objects |
13:10 | <shu> | Does wasm really have no notion of private data for objects? |
13:10 | <shu> | it's a target for compilers of higher level languages |
13:10 | <littledan> | Does wasm really have no notion of private data for objects? |
13:10 | <shu> | it doesn't have methods because you're supposed to just compile a vtable yourself |
13:10 | <shu> | not that it literally doesn't have methods |
13:12 | <Christian Ulbrich> | How is soon is now, I deployed dockerized TCQ reloaded to https://tcq.staging.tcq-reloaded.tcq.ninja/ , now with persistent storage, actual PR is at: https://github.com/zalari/tcq/pull/7 ; I will explain individual decisions. So I think, we can use TCQ reloaded next plenary! |
13:12 | <shu> | i feel like there's a lot of wishful thinking from opponents of the proposal |
13:12 | <shu> | yes, this is a difficult-to-program-correctly space |
13:12 | <rbuckton> | some form of nominal correlation would be useful for Wasm, especially if Wasm wants to interact with JS in various threads and give prototypes to its objects |
13:13 | <shu> | but adding on little guardrails doesn't really advance the goal of writing correct programs |
13:13 | <shu> | well, not even guardrails, just pointless friction imo |
13:13 | <rbuckton> | if you use forgeable type description, of course. Manual correlation has to be based on non forgeable type descriptors that need to be explicitly shared with the realm in the first place |
13:14 | <Mathieu Hofman> | Mathieu Hofman: you're engaged in the nuts & bolts of how correlation could work. great! but i'm more interested in working through the very high level, "i feel this is unsafe" objection |
13:14 | <shu> | mark literally just said that didn't work for java |
13:14 | <shu> | why do you think that'll move the safety needle here? |
13:15 | <shu> | i'd also request you ask yourself the question, what happens if you get thread unsafe code in JS/Wasm |
13:15 | <Mathieu Hofman> | you do some tearoffs that can exfiltrate private data and import them from the wasm side |
13:15 | <shu> | it's the wrong abstraction level |
13:18 | <Aki> | so who wants to volunteer to take a look at the print PDFs? they're in a state approaching publishable |
13:18 | <Mathieu Hofman> | What do you consider to be a "non forgeable type descriptor"? |
13:20 | <rbuckton> | Do we, as a committee, think JS privacy is a security feature? Would it be unforgivable if private state isn't really private at the realm boundary? If we could have struct S { #x; ... } in realm A mapped to struct S { x; ... } in realm B, would we consider that a security vulnerability? |
13:21 | <shu> | good question |
13:21 | <shu> | this is all echoes of hard constraints held by SES folks that are not clearly communicated as such, and so they feel like stop energy |
13:22 | <shu> | also like look, i'm fine with removing methods |
13:23 | <shu> | but i think that's actually worse for correctness! and i really don't get the arguments that it's better for correctness |
13:23 | <shu> | and it sounded like others share my confusion |
13:23 | <rbuckton> | In a shared struct, struct S { #x; ... } means that in the realm where it is defined, the private name #x refers to the first fixed storage field in the struct. in another realm you could have struct S { x; ... } that just says the field "x" refers to the first fixed storage field in the struct. If you manually correlate S in each realm, does the privacy need to be preserved? |
13:23 | <shu> | the only thing i can make sense of is, "if we don't have methods, i can mentally compartmentalize everything over in wasm land, so i can not think about it" |
13:24 | <shu> | but end-to-end that argument doesn't make sense |
13:24 | <Mathieu Hofman> | The equivalence of private fields has always been WeakMap, and the guiding principle is "how do you give access to the WeakMap instance to access private data". In JS, the WeakMap instance is an object capability like everything else. No-one should be able to get object references without explicitely receiving them. |
13:24 | <shu> | you can use shared structs as a WeakMap key in a per-thread WeakMap |
13:25 | <shu> | that's fine |
13:26 | <rbuckton> | Methods are just functions with lexical access to private state. The correlation mechanism is to make sure you're using the right functions (methods) in a given realm. Free functions provide no benefits. |
13:26 | <shu> | yeah exactly! |
13:26 | <Mathieu Hofman> | IMO the only interest to private data is to have it shared, so that it can be used for encapsulation |
13:27 | <shu> | i am going to become le joker |
13:27 | <rbuckton> | And if you want to guard your shared memory multithreading data structures and logic with a wrapper facade, as Mark suggested, you can do the same thing with methods. Methods vs functions has no impact on that. |
13:29 | <rbuckton> | IMO the only interest to private data is to have it shared, so that it can be used for encapsulation |
13:31 | <shu> | i want to be very clear on my thinking on footguns |
13:33 | <shu> | where something is already expressible, we should be thinking hard about not introducing alternative forms that are easy to get wrong, or easy to be slow, etc. because the incentive for a developer to do a thing is because it has the semantics the developer wants to do. so if choosing between form A and B that have more or less the same core behavior but differ in performance or some aspect of correctness, we shouldn't add forms that have higher likelihood of being slow or incorrect |
13:34 | <shu> | but if one's claim is that the likelihood of incorrectness comes from expressing the thing at all (like shared memory), banning alternate forms adds friction for zero gain! |
13:41 | <rbuckton> | In terms of TypeScript's "incremental adoption" story, most of our AST nodes are essentially "immutable" after they are created (though that's only enforced through type checking). Being able to produce AST nodes in parallel parsers and collect them in the main thread for checking, and then spin them out to parallel emitters would be essential for incremental adoption in TS. Public fields aren't really a concern since we could annotate them with a design-time only readonly modifier, though it would be interesting to add an actual concept of an init-only field, e.g., shared struct S { const x; ... } |
13:42 | <shu> | ah right, that reminds me i didn't respond to the narrow point that mark made about the Point example being not thread safe |
13:43 | <shu> | i also didn't show any code mutating .x and .y :) |
13:44 | <rbuckton> | But for incremental adoption to work those nodes would need to have methods, otherwise we would need to rewrite the entire compiler to even get started. |
13:58 | <Chris de Almeida> | Do we, as a committee, think JS privacy is a security feature? Would it be unforgivable if private state isn't really private at the realm boundary? If we could have |
14:00 | <rbuckton> | yes, yes, and yes. if I understand your example correctly, the private field on A being accessible from B, I would consider that a security vulnerability |
14:01 | <rbuckton> | But I also do not hold that private state is a security feature. |
14:07 | <Chris de Almeida> | But I also do not hold that private state is a security feature. |
14:08 | <Chris de Almeida> | to be clear I don't suggest that privacy (or encapsulation in general) is exclusively a security feature |
14:09 | <rbuckton> | I see it as a developer experience/convenience mechanism. It's not that I think it should be less "secure", per se, but that I don't consider private state to be trustworthy as there are limitations to its "security" in some situations. |
14:10 | <Chris de Almeida> | I agree with not relying on it completely as a protection mechanism |
14:10 | <shu> | would you agree that encapsulation is a security feature? |
14:11 | <Chris de Almeida> | that risks devolving into arguing what "security" means so i think of it in terms of SLAs and who's responsible for hitting those SLAs |
14:11 | <Chris de Almeida> | forgetting about security for the moment, the private field on A being accessible from B, is it not problematic that this is violating privacy/encapsulation in general? |
14:11 | <shu> | practically to me, as a SWE, "security" means the highest priority bug that we'll pull out all the stops for to fix |
14:12 | <shu> | forgetting about security for the moment, the private field on A being accessible from B, is it not problematic that this is violating privacy/encapsulation in general? |
14:13 | <shu> | if there were a bug with private fields, browser VMs aren't going consider it a "security bug" in that we're not going to be trying to get a fix ASAP, respin binaries for stable branch, etc |
14:13 | <shu> | but an application that depends on that private field might |
14:14 | <Chris de Almeida> | all bugs are problematic, i'm explaining the real world consequences of how problematic it's considered |
14:15 | <shu> | okay then ignore me, i don't think it's particularly important for this concrete topic |
14:20 | <justingrant> | IANA's rule for zone merges is that the largest-population city (at the time of the merge) wins. |
14:25 | <rbuckton> | If privacy is an important security concern, then you must have an unforgeable correlation mechanism. Auto-correlation by source location is unforgeable. I'll admit I still don't quite understand Mathieu Hofman's suggestion about an unforgeable type descriptor as it still seems unsound to me. |
14:26 | <justingrant> | They also do merges across country boundaries, which is the thing that CLDR (correctly, IMO and now according to the 402 PR we approved on Tuesday) backs out. But backing out intra-country merges too would make time zone picker UIs hugely confusing for end users, and backing out some but not others would generate political fuss that TC39 (and CLDR) wants to stay far away from. What's nice about the "don't merge across country codes" rule is that ISO 3166-1 decides what the country codes are, not CLDR or TC39. And IANA maps every country code to a Zone. So JS can just draft behind others. |
14:31 | <justingrant> | One more important detail: today, merges are really visible in JS because Intl.DateTimeFormat canonicalizes zone IDs. This behavior will change once Temporal is Stage 4. So if you create a Temporal.ZonedDateTime with America/Montreal, then it will stay America/Montreal. After Temporal Stage 4, the only place that merges will matter up in JS will be when the IDs come from ECMAScript built-ins: when reading the system's current time zone and when calling Intl.supportedValuesOf('timeZone'). Any time users provide IDs, JS won't touch them anymore. Vive La Quebec! |
14:31 | <justingrant> | Le Quebec? |
14:34 | <justingrant> | yeah that's an interesting typo that only an English speaker could make Yep, guilty as charged! I was in a hurry and made a typo. Thanks hax (HE Shi-Jun) for calling it out. I just corrected the slide. Sorry it's taken so long to respond, I'm just now catching up on matrix. |
14:37 | <Chris de Almeida> |
|
20:02 | <justingrant> | Yes, ICU and JS implementations tend to implement this historical part My understanding was that JS implementations don't actually use the data in
|
20:35 | <justingrant> | Could somebody re-explain to me this comment? 😅 Do databases use timezones that are not the timezones we are using in temporal? |
20:50 | <justingrant> | leftmostcat (UTC-7): I would like to start a proposal for declarative custom time zones. Would you be interested in co-championing this with me? I don't have the domain expertise in iCalendar/jCal/JSCalendar to turn their schemas into spec text, but if you (or someone you know) is interested in doing that part, then I'd be eager to help turn that into reality. |
20:55 | <leftmostcat (UTC-7)> | leftmostcat (UTC-7): I would like to start a proposal for declarative custom time zones. Would you be interested in co-championing this with me? I don't have the domain expertise in iCalednar/jCal/JSCalendar to turn their schemas into spec text, but if you (or someone you know) is interested in doing that part, then I'd be eager to help turn that into reality. |
21:17 | <justingrant> | I would be. |
21:26 | <bakkot> | speaking of timezones, people interested may wish to follow or contribute to the proposal for adding timezones to WASI https://github.com/WebAssembly/wasi-clocks/pull/61 |
21:50 | <ptomato> | I won't have time to look at it in detail for a while. At first glance it looks like they are exposing an "in DST" flag. Unfortunately that's not well defined for many time zones. |