00:39 | <littledan> | but numeric literals having Object semantics feels it is unprecedented in all of PL. would be fascinating to see an exception |
00:45 | <littledan> | to be clear i don't mean that we wish to make standards positions private, i mean that i don't consider it my job to publicize |
01:41 | <justingrant> | it's so strange to me that IETF would explicitly not want to support sub-minute offsets (catching up) Here's more context around IETF's reasoning, and more generally why restricting offset time zones to minutes seems OK to me: Existing RFC3339 timestamp strings (which the new IETF spec, aka "IXDTF", extends) only support HH:MM in the offset, e.g. In the new IETF spec, they didn't want to change anything about the RFC3339 portion of the IXDTF timestamp, only the stuff in brackets after the timestamp is what's new. Otherwise, existing RFC3339 parsers would break for the before-brackets portion. Of course, that's not necessarily related to what's in brackets. We could have different precision for the in-brackets portion because there's no legacy. But with IXDTF, the rule is that the RFC3339 offset must match the offset of the time zone in brackets. So For named time zones that have sub-minute precision, the new IETF spec handles it by being flexible about what "match" means: if the bracketed time zone's offset, when rounded to HH:MM, matches the offset in the RFC3339 portion of the string, then there's no error produced. So
Temporal does the same thing in reverse in Anyway, that's how it works for named time zones. But what about offset time zones? Because the offset in the RFC3339 portion of the string is constrained to HH:MM, the IETF folks felt that it'd be better to also limit the bracketed time zone to HH:MM too. There's nothing preventing us from extending the format in the future if there's customer demand, using the same rounding hack used for named time zones, so that But it's not clear (to me at least) that this customer demand will ever materialize. Offset time zones were really only added to Temporal and IXDTF for backwards compatibility with Java. It's not clear how much usage of offset time zones there will be in Temporal. Partly this is because all IANA time zones today are on 15-minute boundaries. Sub-minute offsets haven't been official in any country since the 1970s, and even then it was rare. And offset time zones intentionally dispense with the main value of time zones in Temporal: the ability to automatically adjust timestamps for DST and other time zone weirdness. Also, there's a storage advantage. If offset time zones are limited to minutes, then a Temporal.TimeZone can fit in a 16-bit union: 12 bits for offset time zones (±24h at minute-precision), 10 bits for the index into ~600 named time zones, and one bit to choose between them. Sub-minute offsets would require 50% more bytes to support a use case with questionable demand. Finally, any user who really needs an offset time zone with sub-minute precision can create a custom time zone with granularity down to nanoseconds. Which they'd have to do anyways for time zones like TAI which don't have constant offsets (thanks leap seconds!) so you can't use an offset time zone anyways. AFAICT, there has never been a real-world time zone that has had a non-minute-aligned offset whose offset has never changed. So I'm kinda skeptical that "offset time zones at sub-minute precision" are real things. P.S. - one concern raised was how RFC 5545 (aka iCalendar) supports second-precision offsets. But AFAICT, those offsets are never actually used for time zone identifiers. Rather, they're used to define the offsets of named time zones. And Temporal is already permissive with timestamp offset inputs, so we'll accept strings like Summary: restricting to minutes for built-in offset time zones seems like a safe initial bet that we can always extend later if needed. Thanks for coming to my obscure TED talk. |
02:29 | <justingrant> | It still seems like we should stop returning Saigon and Kiev despite the lack of a Temporal.TimeZone.prototype.equals There are two pieces required to fully solve this:
These two pieces are independent! Even though yesterday the committee agreed to hold (1) until Temporal.TimeZone ships, for (2) implementations are already free to return Europe/Kyiv, Asia/Kolkata, and Asia/Ho_Chi_Minh as canonical IDs. Firefox does this today, and Anba has argued (convincingly, IMO) that the FF behavior is more spec-compliant with current 402. V8 and JSC don't do this today because they rely on CLDR and ICU which never update renamed IDs. But nothing stops ICU-using implementations from doing what Firefox does and overriding the ~20 zones in CLDR that use out-of-date names. If an ICU solution will take 2 years, could V8 and JSC in the meantime just add a hard-coded mapping table of 20 IDs? It's not like renames happen often: less than once per year is the average. If you, shu , and Frank wanted to do this badly enough, I suspect it could get done fast! That said, it's a reasonable argument that doing (1) before (2), or at the same time, would reduce the negative impact to existing code because user-inputted zones wouldn't be affected. My suggestion:
Let me know how I can help! |
02:39 | <Richard Gibson> |
justingrant I was wondering about how this rounding handled midpoint values like -00:44:30 or +00:44:30 (specifically "ties away from zero" vs. "ties toward positive infinity" vs. "ties toward even"), but I don't see any mention of it at https://www.ietf.org/archive/id/draft-ietf-sedate-datetime-extended-08.html or https://github.com/ietf-wg-sedate/draft-ietf-sedate-datetime-extended/blob/main/draft-ietf-sedate-datetime-extended.md . Are you sure you're not thinking of Temporal InterpretISODateTimeOffset step 8.c.i RoundNumberToIncrement(candidateNanoseconds, 60e9, "halfExpand")? |
02:45 | <shu> | It doesn’t quite have to be your job to publicize it as such, but if you could give us (proponents of features) direction on what to say to others when they ask us about this, so as to accurately represent your position, that would be helpful. The scope of what you would like JS proposals to avoid has been a little ambiguous even to many committee members leading up to this meeting. |
03:20 | <shu> |
thanks for the detailed plan, i'd hate for it to get lost in the matrix chat, an issue to capture it would be great. for (2), good to know it's independent. i won't be the one to drive this work, so Frank, who's much closer to the i18n and ICU teams, would be the one for you to convince to do the heavy lifting. frankly i just don't have the domain expertise and don't have a nose for the impact here to make a decision |
03:59 | <bakkot> | do I read the schedule correctly that there's a 60 minute underflow before lunch? |
03:59 | <bakkot> | is there any thought of moving stuff up or is all the other stuff fixed in time? |
07:28 | <Rob Palmer> | We're open to ideas on filling the morning schedule. |
07:52 | <bakkot> | I ask mainly because I would like to know if I will miss anything if I sleep during the time that is currently dead |
07:52 | <bakkot> | that being 2am-4am pacific time |
07:53 | <bakkot> | i.e. hours that I would very much like to sleep through if I am not going to be missing anything |
07:53 | <Rob Palmer> | We will begin by asking for agenda items to fill the time. |
08:03 | <sffc> | my slides: https://docs.google.com/presentation/d/1MKceo1Pn1PvuMz1WkzGwIpbT5qRNZVZRxY3rgcPJOKI/edit#slide=id.p |
08:07 | <littledan> | We are likely to do a review of Stage 2 proposals during the spare time in the morning, and a presentation of research by people here in UiB in the afternoon, but details tbd for each. |
08:12 | <Rob Palmer> | We have brought forward Nicolo's Optional Chaining into this morning. Plus the two additions Dan mentioned. |
08:17 | <Michael Ficarra> | I have seen this exact complaint about not being able to shrink wasm memory before in one of the wasm issue trackers |
08:17 | <Michael Ficarra> | they're aware of a need here |
08:18 | <littledan> | |
08:18 | <bakkot> | https://github.com/WebAssembly/design/issues/1397 |
08:27 | <justingrant> |
https://github.com/tc39/ecma402/issues/806. Feedback welcome! |
08:33 | <justingrant> |
|
08:46 | <rbuckton> | Python's contextlib has a very tight coupling between decorators and context managers, such as contextlib.ContextDecorator : https://docs.python.org/3/library/contextlib.html#contextlib.ContextDecorator |
08:50 | <Luca Casonato> | On the topic of source phase imports, please vote on the keyword (or suggest other keywords): https://github.com/tc39/proposal-source-phase-imports/issues/54 |
08:53 | <Luca Casonato> | And you can discuss here: https://github.com/tc39/proposal-source-phase-imports/issues/53 |
09:11 | <littledan> | the new example should be new a?.() |
09:11 | <littledan> | I thought the example new a?.b() should already be legal (but would not be so useful) |
09:12 | <eemeli> | Do we have any valid syntax yet that considers the LHS in any way before attempting evaluation of the RHS? |
09:14 | <bakkot> | (a.b) = c being legal is an accident of history |
09:15 | <rbuckton> |
|
09:15 | <bakkot> | we made ([x]) = b illegal |
09:15 | <rbuckton> | so we are not consistent in all assignment cases |
09:19 | <Andreu Botella> | You can also treat this as being precedence-related, right? |
09:19 | <Andreu Botella> | whether ?. is prioritized over = |
09:19 | <bakkot> | not with the example on screen, no |
09:19 | <Michael Ficarra> | Andreu Botella: no? |
09:19 | <HE Shi-Jun> | (a.b)=c but not (test?a:b)=c which was supported in some other languages. |
09:19 | <Michael Ficarra> | Andreu Botella: definitely not |
09:20 | <rbuckton> | Its easy enough to say that (a?.b) is not a valid simple assignment target |
09:20 | <Michael Ficarra> | HE Shi-Jun: you're right, that is a strange inconsistency |
09:22 | <bakkot> | we could say a?.b = c is only legal in statement position |
09:22 | <rbuckton> | syntactically a?.b = c would likely be an OptionalChainAssignment, where the ?.b = c = d = 42 is part of the chain |
09:22 | <bakkot> | that would be kind of odd but like |
09:22 | <bakkot> | fine |
09:22 | <HE Shi-Jun> | a = b.x = c?.y = d = e = 42; this case is interesting, what's the behavior as current draft? |
09:23 | <rbuckton> | If you translate this example to the "setter-function" case, it is consistent:
would assign |
09:24 | <HE Shi-Jun> | so a and b.x would be undefined instead of 42 ? 🤔 |
09:24 | <rbuckton> | yes |
09:24 | <rbuckton> | maybe weaker than Statement and allow at , ? |
09:25 | <bakkot> | yeah, that also works |
09:25 | <bakkot> | really anywhere except the RHS of an assignment expression |
09:26 | <bakkot> | though, if the goal is to avoid observing the value, you do want "only in statement position" probably |
09:26 | <nicolo-ribaudo> | The goal is to "accidentally" observe the value |
09:26 | <rbuckton> | It should be feasible to forbid a = b?.x = c in the grammar |
09:26 | <bakkot> | x = (0, a?.b = c) assigns what value to x ? undefined or c ? |
09:26 | <nicolo-ribaudo> | i.e. something like a = (b?.c = d) might still be ok, assigning undefined |
09:29 | <rbuckton> | Not sure I want a?.b = c where c is evaluated if a is undefined. The point is to avoid the evaluation of c if it isn't going to be used, otherwise it is not a valid refactor from if (a) a.b = c |
09:30 | <rbuckton> | a?.b ?= c ? |
09:30 | <littledan> | |
09:30 | <bakkot> | Not sure I want |
09:31 | <littledan> | it feels like ne pas in French--agreement |
09:32 | <rbuckton> | ah, c'est vrai |
09:32 | <rbuckton> | (though I admit my french is limited and rusty) |
09:33 | <littledan> | same |
09:35 | <rbuckton> | a?.b is often intended to be read more like a ? .b or "if a exists then a.b", thus a?.b = c would be intended to be read as a ? .b = c or "if a exists then a.b = c". |
09:38 | <rbuckton> | Maybe? It feels like one ? should correspond to one instance of short-circuiting, but this has two ? to point to the same thing |
09:40 | <Michael Ficarra> | eemeli: I think you need to review what stage 1 means |
09:40 | <Michael Ficarra> | you are asking nonsensical questions |
09:40 | <Michael Ficarra> | a solution is not accepted to stage 1; a problem space is |
09:41 | <rbuckton> | I would like us to investigate this at Stage 1 to see if we can find a way to resolve concerns raised by some delegates. I think this would be very valuable to have in some form and is worth pursuing, even if we need to find unique syntax to accommodate concerns. |
09:41 | <nicolo-ribaudo> | a solution is not accepted to stage 1; a problem space is |
09:41 | <Michael Ficarra> | yes, often when a proposal is "overcooked", we end up in this kind of a situation |
09:42 | <Michael Ficarra> | people get too hung up on the specifics of a potential solution |
09:42 | <bakkot> | (fwiw I think that the MessageFormat proposal had the same problem) |
09:42 | <Michael Ficarra> | unfortunately, without them, it can be difficult to understand the problem space |
09:43 | <rbuckton> | I would say the problem space is "allowing assignment with similar ergonomics as optional chaining currently allows: avoiding repetition and handling conditional member references based on whether a part of the LHs is null/undefined" |
09:46 | <bakkot> | Bradford Smith: I do not think it will be hard to specify this |
09:46 | <rbuckton> | We can at least block a = b?.c = d via a static semantics rule, even if not in the grammar. |
09:46 | <bakkot> | or to write parsers for it |
09:46 | <rbuckton> | We block const a via static semantics, so this doesn't seem that bad |
09:47 | <bakkot> | like I expect this to be about an order of magnitude easier to specify and implement than the hideous async (x) cover grammar |
09:47 | <bakkot> | which, granted, I wouldn't want any new features of that complexity |
09:47 | <bakkot> | but this one doesn't seem bad at all |
09:48 | <littledan> | arrow functions should've been like ^x => y or something |
09:48 | <nicolo-ribaudo> | I know that I should have not written a spec for a stage 0 proposal, but the way it can be specified is nicolo-ribaudo.github.io/proposal-optional-chaining-assignment/ |
09:48 | <littledan> | everything would be way easier in that case |
09:48 | <Michael Ficarra> | λx. y |
09:49 | <bakkot> | sidebar: is someone breathing directly into one of the microphones? |
09:49 | <rbuckton> | We want to allow a?.b = c where its on the LHS, but disallow a = b?.c = d where its on the LHS and RHS, but not disallow a = b?.c where its on the RHS only. Possible with production parameters maybe, especially if the assignment is part of the OptionalChain production |
09:49 | <Bradford Smith> | Bradford Smith: I do not think it will be hard to specify this |
09:50 | <eemeli> | (fwiw I think that the MessageFormat proposal had the same problem) |
09:51 | <ryzokuken 🇳🇴> | It's hard to foresee these issues ahead of time tbf |
09:51 | <rbuckton> | Well I expect you're more familiar with the details of the grammar than I. ?? |
09:51 | <bakkot> | We want to allow |
09:51 | <bakkot> | alternatively you can just have an early error with prose |
09:52 | <rbuckton> | alternatively you can just have an early error with prose |
09:52 | <nicolo-ribaudo> | ryzokuken 🇳🇴 Rob Palmer TCQ is at the previous agenda item |
09:52 | <ryzokuken 🇳🇴> | oops |
09:53 | <ryzokuken 🇳🇴> | ptomato (at TC39, limited availability): could you add your item again? |
09:53 | <nicolo-ribaudo> | ptomato (at TC39, limited availability): could you add your item again? |
09:53 | <nicolo-ribaudo> | Or at least, I see it there |
09:54 | <bakkot> | "how should the committee proceed wrt the pipeline operator" -> we should not proceed with the pipeline operator |
09:55 | <Michael Ficarra> | personally, I think the pipeline operator may need a full re-justification |
09:55 | <bakkot> | (sorry to be blunt; in my defense it's 3am) |
09:55 | <Michael Ficarra> | (reviewed in the context of the language as it is today, not how it was when originally justified) |
09:56 | <ryzokuken 🇳🇴> | I think given all that transpired with pipeline, maybe it makes sense to deviate from both semantics and try to come up with something unique that would be a decent compromise? |
09:56 | <Andreu Botella> | it's odd that test262 seems to strongly rely on cleanupSome to test some GC things |
09:56 | <nicolo-ribaudo> | personally, I think the pipeline operator may need a full re-justification |
09:57 | <nicolo-ribaudo> | I like throw expressions |
09:58 | <Michael Ficarra> | same |
09:58 | <nicolo-ribaudo> | I like them even in a world with do expressions |
09:58 | <Michael Ficarra> | I really wish I could get some time to work on protocols again |
09:59 | <Michael Ficarra> | editor work unfortunately takes up most of my time allocated to TC39, and iterator helpers (and follow-ons) are definitely more popular in the community |
10:03 | <Andreu Botella> | it seems like if cleanupSome is withdrawn, it would have to be added to the test262 infrastructure |
10:03 | <rbuckton> | The direction that the pipeline operator took has had significant pushback from the community. There's a tremendous amount of interest in the feature, but choice to use Hack-style pipes didn't sit well with some of the major libraries in the FP community. |
10:03 | <Andreu Botella> | maybe in a simplified way, without taking a callback |
10:04 | <Rob Palmer> | Please could you write this (in an appropriate way) in the summary notes for this topic, Ron. |
10:04 | <rbuckton> | i accidentally a word. I've edited the comment |
10:04 | <rbuckton> | re: do expressions, I think some proposals like pattern matching are depending on it. |
10:04 | <rbuckton> | not to say that they can't work around that. |
10:04 | <bakkot> | yeah, though pattern matching is even more syntax than do is |
10:04 | <bakkot> | it is so much syntax |
10:05 | <rbuckton> | pattern matching is extremely valuable though, and I think is definitely worth its weight. |
10:05 | <bakkot> | yeah I'm not saying any of these things shouldn't be pursued, considered in isolation (except maybe pipeline) |
10:05 | <ptomato (at TC39, limited availability)> | which implementations have cleanupSome anyway? I don't think it works in most of them, at least not unflagged |
10:05 | <bakkot> | just that I think the community would be better served by us focusing on stdlib stuff over syntax, at the margin |
10:06 | <ptomato (at TC39, limited availability)> | it may well be that the test262 infrastructure that uses cleanupSome, was only added for testing cleanupSome |
10:06 | <Andreu Botella> | https://github.com/tc39/test262/blob/main/test/built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback-for-object.js |
10:06 | <Michael Ficarra> | I believe HE Shi-Jun was interested in championing the function.sent proposal |
10:07 | <Andreu Botella> | that test doesn't seem to be specifically for cleanupSome |
10:07 | <Andreu Botella> | and it uses asyncGC , which uses cleanupSome internally |
10:07 | <bakkot> | it does kind of claim to be testing cleanupSome ? |
10:07 | <bakkot> | at least, that's what the info section has |
10:07 | <Andreu Botella> | it includes cleanupSome in the features it uses, because otherwise engine262 and maybe other engines will not pass the right flags |
10:08 | <Andreu Botella> | but I don't think it is testing cleanupSome |
10:08 | <Andreu Botella> | I might be wrong though |
10:08 | <ptomato (at TC39, limited availability)> | well that's what I meant by my original question - I suspect that most/all consumers of test262 might just never run this test |
10:08 | <ptomato (at TC39, limited availability)> | anyway, I'll add this to the agenda for the next test262 maintainers meeting. I'm not too familiar with these tests |
10:09 | <Andreu Botella> | I ran into this when testing the interaction of AsyncContext with the FinalizationRegistry callback, and seeing what other FR tests did |
10:11 | <bakkot> | rbuckton: re:
might also work? |
10:12 | <bakkot> | in combination with a [lookahead ≠ throw] restriction in ExpressionStatement , to avoid ambiguity |
10:13 | <bakkot> | it's a little bit weird, but I think it avoids the throw a, b problem |
10:14 | <bakkot> | and lookahead restrictions at the end of productions are precedented in IfStatement |
10:15 | <rbuckton> | That could work, and is far simpler than what I was thinking, though it does mean that ThrowStatement and ThrowExpression wouldn't be symmetrical. |
10:15 | <bakkot> | yeah, but you only notice the asymmetry as an author (or implementer), not as a reader |
10:15 | <bakkot> | since as a reader you would simply never encounter throw a, b in expression position, so it would not come up |
10:16 | <rbuckton> | The alternative I had was this:
And you could potentially even drop ThrowStatement since it would be fully covered by ExpressionStatement (rather than a lookahead restriction in ExpressionStatement). |
10:17 | <bakkot> | the main place I'd expect you to notice the restriction as an author would be like function f(x = throw new Error('argument is not optional'), y) {] |
10:18 | <bakkot> | but, that case is one which is hard for readers who are familiar with ThrowStatement to read, so I am ok with authors having to deal with the restriction in that case |
10:19 | <rbuckton> | With the grammar I mention above, rather than the ambiguity of throw in an initializer, you would be forced to write it as function f(x = (throw new Error(...)), y) which helps with the ambiguity, with the downside that 99% of the places you'd want to use throw requiring parens. |
10:20 | <rbuckton> | I like your approach though, since I'd venture to guess that the number of throw statements that use , is vanishingly small. |
10:21 | <bakkot> | pretty small, though probably not vanishingly |
10:21 | <bakkot> | in particular, stuff like
|
10:21 | <bakkot> | so it's still a little annoying |
10:22 | <bakkot> | but, no ambiguity. |
10:22 | <bakkot> | and you fix it with parens and go on with your life |
10:22 | <rbuckton> | pretty small, though probably not vanishingly throw statements today. |
10:22 | <bakkot> | oh, sorry, yes, lots of throw statements with , because of minifiers |
10:22 | <rbuckton> | I'm happy with that though. If you really wanted to use , in your throw expression, you could parenthesize. |
10:22 | <bakkot> | minifiers love commas |
10:23 | <rbuckton> | oh, sorry, yes, lots of |
10:23 | <bakkot> | agreed |
10:23 | <bakkot> | reading the old thread, I have a comment which reads
I don't know why it didn't occur to me that you could trivially forbid it with a lookahead... |
10:24 | <rbuckton> | I am happy with ThrowExpression : `throw` AssignmentExpression [lookahead != `,`] |
10:24 | <rbuckton> |
|
10:24 | <bakkot> | since that comment, almost exactly two years, but for the proposal in general yes |
10:26 | <bakkot> |
|
10:26 | <bakkot> | annoying technical restrictions like this chafe a lot less when you are told immediately how to fix them |
10:27 | <bakkot> | seems like it ought to be possible |
10:27 | <rbuckton> | I do hope implementations / parsers are able to give a good error message in this case ("try wrapping the throw expression in parentheses") |
10:28 | <bakkot> | good good |
10:28 | <rbuckton> | I posted your suggestion here: https://github.com/tc39/proposal-throw-expressions/issues/10#issuecomment-1633978974 |
10:42 | <rbuckton> | Do we care about other restrictions aside from , ? any infix operator has the same kind of precedence issue, i.e., throw a = b as a statement vs. as an expression. Right now assignment isn't much of an issue in the proposal because the proposal does not allow ThrowExpression to be a valid assignment target, but other operators like && , || , ?? , etc. would have a different precedence. That said, you kind of may want to be able to write a && throw b || c , but throw b || c; has a different meaning. |
10:45 | <rbuckton> | Forcing parentheses (i.e., (throw err) ) does solve all of those precedence concerns, though. |
10:47 | <bakkot> | does it have the same issue? wouldn't a && throw b || c parse as a && (throw b || c) , like a && yield b || c does? |
10:48 | <rbuckton> | throw is currently specified as a UnaryExpression, so it doesn't have the same precedence as yield . a && yield b || c isn't legal. |
10:49 | <rbuckton> | YieldExpression is AssignmentExpression, so it can't be on the RHS of && . |
10:49 | <bakkot> | ah, right |
10:49 | <bakkot> | I forget yield is weird |
10:50 | <rbuckton> | And one of the motivators for throw was to use it with ?? , i.e. const a = b ?? throw new Error() , so it wouldn't work as yield precedence without parens. |
10:52 | <rbuckton> | But that's also an alternative to my CommaExpression idea. Instead, just make ThrowExpression an AssignmentExpression with the same trailing [lookahead != `,`] restriction. That would mean you could write a, throw b , but not throw a, b , which is a bit weird, tbh. |
10:53 | <bakkot> | I am not super worried about humans writing comma expressions |
10:53 | <bakkot> | they almost exclusively come up when reading minified code, in my experience |
10:53 | <bakkot> | occasionally in loop heads but I don't anticipate much use of throw there either |
10:54 | <bakkot> | so while I agree that it would be weird that you could write a, throw b but not throw a, b , my actual concern is preventing you from writing the second thing, and since I don't think anyone would write the first thing the inconsistency doesn't bother me |
10:58 | <rbuckton> | Do you have a position on the precedence for other infix operators differing between the statement and expression forms, or was , your only concern? |
11:00 | <bakkot> | Do we care about other restrictions aside from a && throw b || c does worry me. I'll have to think more about the tradeoff between that ambiguity and forcing more parens. |
11:01 | <bakkot> | it is a little less worrying that the , case because throw b || c isn't really a thing which comes up today, even in minified code, so I am less worried about people misreading it |
11:01 | <rbuckton> | Would you agree that forcing parens is a working solution, even if only as a fallback? |
11:01 | <bakkot> | yes, forcing parens solves the ambiguity |
11:01 | <rbuckton> | it is a little less worrying that the |
11:01 | <bakkot> | even minifiers don't output throw b || c in my experience |
11:02 | <littledan> | when you hear "dataflow", think "reactivity" |
11:02 | <rbuckton> | I expect that they do emit throw a && b though, since they often use && as a substitute for if |
11:02 | <Michael Ficarra> | littledan: FRP? |
11:04 | <bakkot> | I expect that they do emit if (!a) throw a; throw b; , but I think that pattern is rare enough to not have been special-cased |
11:04 | <bakkot> | && as a substitute for if is mainly useful when the rhs of the if is an expression |
11:06 | <bakkot> | looks like esbuild does in fact implement that, so it's just that I haven't run into it because it's rare enough |
11:09 | <bakkot> | another option, which I am... only kind of serious about, would be
|
11:09 | <bakkot> | this would be fine if everyone used semis consistently |
11:10 | <rbuckton> | Why would you disallow ) ? |
11:10 | <bakkot> | that's an allowlist, not a denylist |
11:10 | <Michael Ficarra> | the grammar sees source post-ASI |
11:10 | <rbuckton> | Ah, sorry. I see. |
11:11 | <bakkot> | the grammar sees source post-ASI |
11:11 | <rbuckton> | ish. true for most parsers, but the spec says "parse it. if parse fails, see if it parses after inserting ; " |
11:11 | <Michael Ficarra> | yes, it would have to be otherwise invalid |
11:12 | <bakkot> | in this case it would be though |
11:12 | <rbuckton> | the grammar has to see source pre-ASI for ASI to work. |
11:12 | <Michael Ficarra> | yeah |
11:12 | <rbuckton> | EOF isn't defined in the spec though. |
11:13 | <Michael Ficarra> | I thought we had a way to assert on end of input |
11:16 | <rbuckton> | "end of input" is mentioned only once in terms of White Space. We also have something like "parsed...with no tokens left over" for cover grammars |
11:17 | <rbuckton> | and "with no tokens left over" is mentioned in The Syntactic Grammar as well when discussing the Script and Module goals. |
11:18 | <rbuckton> | "end of the input stream" is mentioned in the rules for ASI |
11:18 | <bakkot> | the EOF isn't necessary because of the ASI thing |
11:18 | <bakkot> | strike it from my suggestion |
11:18 | <rbuckton> | Also, ] should be allowed as well. |
11:18 | <bakkot> | if you had a ?? throw b at the end of the program, ASI would add a ; so it would parse |
11:19 | <bakkot> | yup, agreed on ] |
11:19 | <rbuckton> | And maybe { for something like class extends a || throw b { ? |
11:19 | <bakkot> | also should add : |
11:19 | <rbuckton> | for case ? |
11:19 | <bakkot> | for a ? throw b : c |
11:19 | <bakkot> | might be easier to enumerate operators which should be disallowed instead, really |
11:20 | <rbuckton> | Ah, yes. but also case . There are a lot of tokens to consider and its possible that list would need to change if/when new syntax is added. |
11:20 | <bakkot> | yeah |
11:22 | <rbuckton> | Yeah, I think its easier to restrict to all of the infix operators, or maybe pull out part of OtherPunctuators in the lexical grammar. |
11:32 | <rbuckton> | It helped to write the using implementation in engine262 when writing tests as a way to verify both the implementation and the test itself. |
11:32 | <Bradford Smith> | Does the current process call for reviewers specifically to review the test262 tests? And if so, are there published guidelines for how to review them? |
11:33 | <ryzokuken 🇳🇴> | no, reviewers review the spec |
11:33 | <ryzokuken 🇳🇴> | test262 tests are reviewed by test262 maintainers |
11:35 | <ptomato (at TC39, limited availability)> | stage 3 reviewers are hereby enthusiastically invited to review the tests, though! |
11:35 | <ptomato (at TC39, limited availability)> | it really helps the maintainers if the real experts on a proposal weigh in |
11:35 | <rbuckton> | Though I'd contributed to test262 in the past, I found it very difficult to get started on the tests for using as I found the documentation was somewhat lacking in terms of how to set up the environment, and I had trouble running the tests on Windows and had to use WSL. |
11:36 | <ptomato (at TC39, limited availability)> | would you like to bring that up in #test262-maintainers:matrix.org and maybe contribute better documentation for that use case? |
11:36 | <rbuckton> | Plus there is a lot of hunting around to figure out what files you need to add to includes: [] for some assertions. The experience of working with test262 in an editor like VSCode wasn't great. |
11:37 | <rbuckton> | would you like to bring that up in #test262-maintainers:matrix.org and maybe contribute better documentation for that use case? |
11:37 | <ptomato (at TC39, limited availability)> | this is valuable feedback and I'd love to have a follow up on it |
11:39 | <rbuckton> | I forwarded the messages to the maintainers chat |
11:39 | <rbuckton> | What msaboff is saying is exactly why I wrote an implementation for engine262 to verify the tests themselves were accurate. |
11:40 | <bakkot> | I know michael used polyfills to exercise the iterator helpers tests |
11:46 | <littledan> | I think it's kinda inconsequential whether the reviews happen before or after tests are written, and it'd be fine to shift this later. I'd be uneasy about potentially weakening "Stage 3" which is why I like the numbering Michael used. |
11:48 | <Willian Martins> | Maybe stage 3 🔴 and 3 🟢? |
11:49 | <Andreu Botella> | Stage 3⁺ and Stage 3₋ |
11:52 | <Jesse (TC39)> | 3.-0 and 3.+0 |
11:56 | <shu> | littledan: i don't think it is actually, it should happen before tests are written |
11:56 | <shu> | reviews can trigger non-implementation-motivated normative changes, no? |
12:00 | <littledan> | please advance the queue |
12:01 | <nicolo-ribaudo> | I think it's kinda inconsequential whether the reviews happen before or after tests are written, and it'd be fine to shift this later. I'd be uneasy about potentially weakening "Stage 3" which is why I like the numbering Michael used. |
12:02 | <bakkot> | in my ideal world, implementations would start at stage 2.75, and would write tests, and then champions would do the work of getting those tests into test262 proper, and then get stage 3 |
12:03 | <littledan> | not sure why my topic was converted to a reply and pushed up |
12:03 | <littledan> | I'd prefer to wait to raise this separate topic |
12:12 | <Rob Palmer> | We will take the photo on the mezzanine floor at 14:20 |
12:20 | <Chris de Almeida> | Jesse (TC39): Michael Ficarra please let me know if you would indeed like to sacrifice the Decimal continuation for a continuation of the stage/process discussion |
12:24 | <Jesse (TC39)> | yes, sacrifice is OK |
12:27 | <Michael Ficarra> | I would accept additional time for the process topic |
12:29 | <HE Shi-Jun> | what diff between getUint8Clamped and getUint8 ? |
12:31 | <bakkot> | there is no difference |
12:33 | <Michael Ficarra> | they could literally be the same function object |
12:36 | <bakkot> | this proposal feels like a good reason for us to have introduced the "someone must explicitly second for it to advance" |
12:39 | <nicolo-ribaudo> | they could literally be the same function object [][Symbol.iterator] === [].values |
12:40 | <shu> | what is the .name |
12:40 | <nicolo-ribaudo> | I think "values" |
12:40 | <shu> | `"getUint8(Clamped)"` |
12:40 | <Michael Ficarra> | we only have 1 choice there |
12:40 | <shu> | oh no i meant for the DataView methods |
12:40 | <Michael Ficarra> | since the non-clamped one already has a name |
12:41 | <shu> | boo |
12:46 | <HE Shi-Jun> | let's add a directive: "no coercing" 😂 for the old APIs |
12:46 | <Michael Ficarra> | no need |
12:52 | <Michael Ficarra> | omg that padStart one was disgusting |
12:53 | <Christian Ulbrich> | I'd prefer 'ky'.padStart(5, Number) ! |
12:59 | <Michael Ficarra> | I can see people relying on primitive-to-string conversion |
12:59 | <Michael Ficarra> | I know Java devs love it |
13:03 | <Christian Ulbrich> | I never used coercion for params and I would not let someone pass in a review, if there were to use it... |
13:09 | <Christian Ulbrich> | TypeScript types for WebAPIs are usually stricter, than the APIs is, i.e. they won't allow using types, that are actually "supported" by coercion. |
13:09 | <ryzokuken 🇳🇴> | I can see people relying on primitive-to-string conversion |
13:11 | <Christian Ulbrich> | Although I have to say, that TypeScript is often too ambitious, dis-allowing undefined in many (WebAPI) places... |
13:13 | <rbuckton> | Although I have to say, that TypeScript is often too ambitious, dis-allowing |
13:14 | <Luca Casonato> | Anecdote here: a fun TypeScript case (WHATWG not TC39 api) on deciding when coercion is ok vs not ok. https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1568 |
13:20 | <Michael Ficarra> | so what do TypeScript developers use to convert String->Number? |
13:21 | <Michael Ficarra> | do they actually use the full variety of options as appropriate? |
13:21 | <Christian Ulbrich> | Hm. I kind have to retract my argument, having looked at my own code and blaming TypeScript, indeed I am using sth. like parseFloat(value) < 5 and I do rely on parseFloat(undefined) returning NaN ... and NaN < 5 being false ... |
13:21 | <ljharb> | having parseFloat return NaN for a non-string input seems ok to me too tho |
13:22 | <Christian Ulbrich> | I think it returns NaN because undefined is coerced into 'undefined' :) |
13:23 | <ljharb> | right - but i think it would be reasonable to return NaN because it's not a string, as well, instead of throwing |
13:23 | <Christian Ulbrich> | this is somewhat related to stuff, that TS does not like comparing with undefined , which to me totally makes sense... and seemingly not only me |
13:33 | <Jesse (TC39)> | do we document these kinds of things? Does this go, e.g., in the how-we-work document? |
13:33 | <Michael Ficarra> | yes, we've recently started documenting these sorts of things |
13:34 | <Michael Ficarra> | I'm sure Kevin will PR it after we're done |
13:34 | <ryzokuken 🇳🇴> | would this be an invariant then? |
13:34 | <Michael Ficarra> | no |
13:34 | <ryzokuken 🇳🇴> | I see, just a recommendation? |
13:34 | <Michael Ficarra> | https://github.com/tc39/how-we-work/pull/119 |
13:34 | <Michael Ficarra> | a convention |
13:34 | <ryzokuken 🇳🇴> | I see |
13:38 | <Christian Ulbrich> | rbuckton: I only skimmed through my code, at first glance I only found HTMLInputElement['value'] , this is typed as string , where in reality™ it also accepts null to reset the value... |
13:41 | <littledan> | littledan: FRP? |
13:41 | <nicolo-ribaudo> | rbuckton: I only skimmed through my code, at first glance I only found "" to reset the value, right? |
13:43 | <Christian Ulbrich> | It also accepts undefined , because this gets coerced to 'undefined' and sets the value to 'undefined' ... |
13:43 | <shu> | bakkot: we got consensus for not rounding non-integral, right? |
13:45 | <shu> | bakkot: btw i would like to discuss the thing i put on the queue, which is while i'm happy with requiring explicit coercions, the coercions people will reach for is like, String() and Number() which create wrapper objects, and not incantations like +"" . this is a performance footgun imo but maybe is not a big deal |
13:45 | <bakkot> | we did not |
13:45 | <shu> | oh i missed that, i thought we got consensus for rounding... huh |
13:45 | <shu> | there was opposition to that? |
13:45 | <bakkot> | sffc said he'd want more time to review implications for intl |
13:45 | <shu> | ah okay |
13:46 | <nicolo-ribaudo> | String(a number) does not create a wrapper object, right? |
13:46 | <bakkot> | String() and Number() don't create wrapper objects though |
13:46 | <bakkot> | only new String |
13:48 | <shu> | oh the [[Call]] behavior is different! |
13:48 | <shu> | awesome |
13:48 | <shu> | i mean not awesome for me, embarrassing for me to have forgotten that |
13:48 | <shu> | but great, no concern then |
13:51 | <Ashley Claymore> | all that C++ you're writing pushing out the JS again |
13:53 | <Michael Ficarra> | honestly, changing from stage numbers to stage names seems like a good idea |
13:53 | <Michael Ficarra> | where the names are the things that each stage is meant to signal |
13:54 | <shu> | i don't disagree |
13:54 | <shu> | but you're opening yourself up to like, an order of magnitude more hours of bikeshedding |
13:54 | <Chris de Almeida> | if we're bikeshedding the stage name, 2 splitting into to 2.a, 2.b seems better to me than 2, 2.75 |
13:54 | <littledan> | I think Rust went through this detailed bikeshedding exercise at some point |
13:54 | <ryzokuken 🇳🇴> | well, we technically have names |
13:54 | <littledan> | 2.b doesn't sound enough like "almost 3" to me |
13:54 | <Chris de Almeida> | why does it need to? |
13:55 | <shu> | because it is supposed to be almost 3 |
13:55 | <ryzokuken 🇳🇴> | strawperson/proposal/draft/... |
13:55 | <Chris de Almeida> | 2.z |
13:55 | <Michael Ficarra> | Chris de Almeida: we've had a request for that |
13:55 | <bakkot> | so that we don't argue about design decisions |
13:55 | <eemeli> | I've been mostly posting this on TDZ, but I seriously think we should go with stages 1, 2, e, π, 4. |
13:55 | <bakkot> | the reason to signal "almost stage 3" is because we want to explicitly signal "do not keep arguing about design" |
13:55 | <eemeli> | Then we'd have two three-ish stages. |
13:56 | <ryzokuken 🇳🇴> | I think renaming stage 3 is going to be hard |
13:56 | <Michael Ficarra> | eemeli: no |
13:56 | <ryzokuken 🇳🇴> | a lot of things out there use that |
13:56 | <ryzokuken 🇳🇴> | they might not depend as much on lower stages (like babel bundles IIRC?) |
13:59 | <sffc> | sffc said he'd want more time to review implications for intl |
14:01 | <bakkot> | data-driven exceptions seem better than data-driven not-the-right-answer |
14:02 | <sffc> | There's a big difference between "not the right answer" and "best effort answer". In Intl and i18n we're very much driven by doing a best effort acknowledging that we can never be always exactly "right". |
14:04 | <bakkot> | I think for APIs which accept integers, passing a non-integral value is generally a programmer error, rather than being a case where there is only a best-effort answer |
14:05 | <bakkot> | and I generally think programmer errors should be program exceptions, rather than trying to get a best-effort result |
14:05 | <Michael Ficarra> | RE the "spiraling", the thing we need to keep in mind is that it's fine if we have an implementation during stage 2.75 (Dan suggested polyfills/transpilers, but it can also be an engine), it's just the idea is to avoid recommending for general implementation, which is where that aggregate work is extremely high |
14:05 | <ljharb> | a best-effort answer doesn't necessarily mean you can't restrict inputs |
14:05 | <ljharb> | it just means the output doesn't have to be perfect |
14:08 | <rbuckton> | rbuckton: I only skimmed through my code, at first glance I only found [LegacyNullToEmptyString] on method parameters, we don't seem to handle it for properties. |
14:10 | <shu> | There's a big difference between "not the right answer" and "best effort answer". In Intl and i18n we're very much driven by doing a best effort acknowledging that we can never be always exactly "right". |
14:10 | <shu> | for 262 at least "approximation" is most definitely not the design principles for new APIs |
14:12 | <rbuckton> | rbuckton: I only skimmed through my code, at first glance I only found |
14:15 | <bakkot> | shu: I do think that, given that the committee is receptive to breaking with precedent for coercing stuff in at least some cases, it is maybe worth asking to break with precedent for any new TA things |
14:15 | <bakkot> | to avoid the awful user code coercions |
14:15 | <shu> | yeah, the TA problem is narrowly solvable |
14:15 | <shu> | it'd be nice to solve it generally but i'll take any improvement obv |
14:16 | <bakkot> | on the "coercing objects to strings is useful" point, one of the things I will ask about next time I bring this up is, just don't coerce objects to number, and continue coercing to string |
14:16 | <bakkot> | since, granted, there is some utility to coercing things like URL to string |
14:16 | <bakkot> | (even if I personally would prefer people do it explicitly) |
14:16 | <shu> | i'd also take "built-in toString methods only" but that's not that nice and hurts polyfills |
14:17 | <Christian Ulbrich> | rbuckton: Quite the service! Thanks for creating the bug. From my mind, there were other issues, I'll report them once I have some more time, currently only ~30 //@ts-ignore in our code base, not too bad. The other thing, was with NodeListOf being iteratable (sic!) but I have to give this a more thorough look on modern TypeScript (we are currently at 4.6.2 . |
14:18 | <shu> | actually let's generalize that, it'd be cool to have the dynamic extent of argument + receiver coercion to throw on user code, even if they continue to coerce |
14:21 | <sffc> | for 262 at least "approximation" is most definitely not the design principles for new APIs |
14:23 | <bakkot> | a best-effort answer doesn't necessarily mean you can't restrict inputs |
14:25 | <sffc> | I'm happy to iterate on the language surrounding when ToIntegerIfIntegral should be used versus truncation |
14:56 | <Richard Gibson> | I'm having difficulty in coming up with any scenario where we would prefer truncation other than for consistency with existing APIs. It's just such a mess that e.g. -0.2 is accepted as a non-negative integer or max + 0.1 is rejected where max - 1 + 0.1 is accepted as equivalent to max - 1 . |
15:07 | <sffc> | I'm having difficulty in coming up with any scenario where we would prefer truncation other than for consistency with existing APIs. It's just such a mess that e.g. |
15:34 | <Richard Gibson> | I definitely do disagree; that's a clear case where the truncation would be bad because "123.4 minutes" has a valid interpretation that should not be silently discarded in favor of equivalence with "123 minutes", making future support for respecting the fractional part more difficult. This is an analogue of the motivating use case in Temporal Durations, which couldn't lean on the fuzziness inherent to ECMA-402 formatting (that might leave a sufficient gap for future extension, but then again might not) as justification. |
15:53 | <sffc> | The counter-point is that if we were to enable that type of extension in the future, it's not inherently bad that older engines operate with the approximate behavior. Many programmers will not think about catching the exception in older engines, causing those browsers to needlessly break when they would otherwise get close-but-not-quite-right output. |
15:54 | <sffc> | As an example, we executed on this successfully when we deployed the "interpret strings as decimals" change in Intl.NumberFormat.prototype.format. |
16:51 | <TabAtkins> | I'm with sffc here that this is a very debatable case that has a reasonable argument for truncation. (But I'm generally for the "stop coercing/truncating everywhere" proposal.) |
16:58 | <TabAtkins> | just that I think the community would be better served by us focusing on stdlib stuff over syntax, at the margin |
17:11 | <TabAtkins> | The justification of "make everything method-chainable" is still valid. It would be good to do another review of everything trying to do similar things. But I don't think protocols clash in any meaningful way. |
17:12 | <TabAtkins> | Like if you squint they're both doing similar things (playing in the method space, without messing with prototypes) but protocols use-case, justifications, and abilities are quite distinct. |