Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

era/eraYear are missing in 262 #2169

Closed
ljharb opened this issue May 3, 2022 · 30 comments · Fixed by #2442
Closed

era/eraYear are missing in 262 #2169

ljharb opened this issue May 3, 2022 · 30 comments · Fixed by #2442
Assignees
Labels
editorial spec-text Specification text involved
Milestone

Comments

@ljharb
Copy link
Member

ljharb commented May 3, 2022

Per tc39/test262#3516, it seems like the era and eraYear prototype accessors are only defined in the Intl sections in this proposal.

This is hopefully a mistake, since 402 should generally be overriding 262 things, not adding otherwise-nonexistent things.

I would expect that absent Intl, these accessors exist, and either throw or return undefined.

@FrankYFTang
Copy link
Contributor

get Temporal.PlainDate.prototype.era
get Temporal.PlainDate.prototype.eraYear
get Temporal.PlainDateTime.prototype.era
get Temporal.PlainDateTime.prototype.eraYear
get Temporal.PlainYearMonth.prototype.era
get Temporal.PlainYearMonth.prototype.eraYear
get Temporal.ZonedDateTime.prototype.era
get Temporal.ZonedDateTime.prototype.eraYear

Are getter, so I think it will always return undefined w/o chapter 15 (intl) anyway. So I think even if you do not defined them in first 14 chapters, the behavior will always be return undefined anyway.

In the other hande,
Temporal.Calendar.prototype.era
Temporal.Calendar.prototype.eraYear

are not getter but function so that will have some impact

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

To be specific, typeof Object.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, 'era').get === 'function', and the same for the others - this requires that they be explicitly defined in the non-intl portion of the Temporal spec, and it doesn't appear that they are.

@FrankYFTang
Copy link
Contributor

oh I see. yes, i think you are right.

@FrankYFTang
Copy link
Contributor

@sffc @ryzokuken

@sffc
Copy link
Collaborator

sffc commented May 3, 2022

The concept of era and eraYear is unique to 402 calendars.

The current state of the spec is based on the idea that we don't know ahead of time the full set of calendar-specific fields that all calendars might need. For example, there might be some new calendar in the future that needs to add "stardate" as a field. Such a field would be defined on the Calendar object for that calendar, and getters would be added to Date, DateTime, etc., to proxy into the calendar.

At one point, we had also discussed the idea of making all undefined property accesses on Date automatically proxy to the calendar, but we didn't move forward with that idea.

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

I am completely content having calendars work this way - where the default 262 Calendar need not have every property that additional 402-provided calendars do.

However, the base Temporal types shouldn’t have accessors for properties that 262 doesn’t know about, just like if a userland calendar class adds an arbitrary property (and 262 won’t have an accessor for it).

@sffc
Copy link
Collaborator

sffc commented May 3, 2022

IIRC, we had said that userland calendars could add the proxy methods to the base types if they didn't already exist; performing that check would be an operation done in the calendar constructor.

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

They can certainly do that because of the nature of the language, but we also said we wouldn’t be encouraging users to mutate objects they don’t own, given that that’s a decades-old horrifically bad practice.

@ptomato
Copy link
Collaborator

ptomato commented May 3, 2022

See #1046 for previous discussion.

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

I’m not sure that contains an explicit consensus decision about this particular aspect of the issue.

I think that either 262 needs to provide these accessors on all the non-Calendar Temporal types, or 402 needs to not provide them. Either choice is consistent and fine with me.

@FrankYFTang
Copy link
Contributor

@ljharb could you clarify what would be the short coming if we keep the status quo and not define era/eraYear for (Plain(Date(Time)?|YearMonth)|ZonedDateTime) ?

Regardless what is the conclusion, I think test262 tc39/test262#3516 should be changed anyway since even if we define them, the behavior under 262 should be return undefined and those tests are still bad AS IS. See tc39/test262#3517

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

@FrankYFTang it would mean that the shape of these builtins would be meaningfully different in portable code (which can never assume the presence of Intl) versus in code that can assume the presence of Intl.

To be able to reliably borrow an accessor - that will exist whether Intl is present or not - is a valuable property I want to retain.

@FrankYFTang
Copy link
Contributor

I am completely content having calendars work this way - where the default 262 Calendar need not have every property that additional 402-provided calendars do.

I do not quit understand why such argument does not ALSO cause concern on Temporal.Calendar.prototype.era/eraYear ?
If the shape of PlainDate|PlainDateTime|PlainYearMonth|ZonedDateTime builtins would be meaningfully different in portable code, then how would Calendar won't have meaningfully different in portable code if we do not also define them? Wouldn't everything the code would rely on PlainDate|PlainDateTime|PlainYearMonth|ZonedDateTime could also rely on Calendar?

Shouldn't we have consistent policy amount them too?

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

No, because individual calendars can't be used generically without extra knowledge (like is it ISO, etc). That isn't and shouldn't be the case for the rest of the Temporal types.

@sffc
Copy link
Collaborator

sffc commented May 3, 2022

It's also worth mentioning that the idea was for there to be additional calendar-specific getters, such as yearType for Hebrew and cyclic year getters in Chinese (you can imagine "what animal is it this year"). The broad scope of these getters is out of scope of ECMA-262, but it would be a major ergonomics hit if they weren't consistently available on Temporal.* objects.

I’m not sure that contains an explicit consensus decision about this particular aspect of the issue.

The consensus was in the form of Stage 3 approval. The issue was discussed, settled, and spec'd out almost 6 months before we got to Stage 3. I can check if it was also discussed in a Temporal Stage 2 Update presentation.

I think that either 262 needs to provide these accessors on all the non-Calendar Temporal types, or 402 needs to not provide them. Either choice is consistent and fine with me.

Here are the outcomes that are fine with me:

  1. Status quo: 402 adds additional getters that aren't present when in 262-only mode
  2. Temporal objects unconditionally delegate to the calendar for any undefined field

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

@sffc imo this proposal is far too large to claim that stage 3 approval actually constitutes explicit approval of all decisions made.

I don't see how option 2 is feasible unless Temporal objects are exotic, and that would be a pretty major change that would not achieve consensus.

Why is it a major ergonomics hit to have code that does x.calendar.foo instead of x.foo? That seems like an ergonomics improvement to me for things that are, in fact, calendar-specific.

@sffc
Copy link
Collaborator

sffc commented May 3, 2022

Why is it a major ergonomics hit to have code that does x.calendar.foo instead of x.foo? That seems like an ergonomics improvement to me for things that are, in fact, calendar-specific.

It's a difference between x.foo and x.calendar.foo(x), because x.calendar is stateless.

imo this proposal is far too large to claim that stage 3 approval actually constitutes explicit approval of all decisions made.

Understood. I only ask for reciprocal understanding that changes at this stage should meet a high bar.

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

I do understand that it's a high bar.

Are there any other things that 402 adds, besides the Intl global itself, that don't exist in 262? I don't believe there are, but I am not familiar with the entirety of 402.

@sffc
Copy link
Collaborator

sffc commented May 3, 2022

I do understand that it's a high bar.

Let's see if we can solve this with editorial massaging, and perhaps shifting things between 262 and 402, so that there isn't any real impact on the implementations.

Are there any other things that 402 adds, besides the Intl global itself, that don't exist in 262? I don't believe there are, but I am not familiar with the entirety of 402.

The obvious one is Object.prototype.toLocaleString, although that appears in 262 as basically a stub. It says:

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Array.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.

Could we include similar spec text in Temporal? Something like this, in 262:

An ECMAScript implementation that includes the ECMA-402 Internationalization API may include additional getters on Temporal.Date.prototype that delegate to the inner calendar object. If an ECMAScript implementation does not include the ECMA-402 API, all properties other than those specified here must return undefined.

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

Let's see if we can solve this with editorial massaging, and perhaps shifting things between 262 and 402, so that there isn't any real impact on the implementations.

Adding accessors to 262 that return undefined seems like it would achieve that.

that appears in 262 as basically a stub.

toLocaleString is indeed the primary example I'm thinking of; 262 intentionally contains "stubs", and that's what i expect for era/eraYear.

The spec text you suggest isn't similar in that it does not explicitly enumerate what 402 is allowed to do - namely, it gives 402 too much latitude, which it's not supposed to have.

@sffc
Copy link
Collaborator

sffc commented May 3, 2022

toLocaleString is indeed the primary example I'm thinking of; 262 intentionally contains "stubs", and that's what i expect for era/eraYear.

The issue is that both in theory and in practice, era/eraYear is not the full set of fields. If it were, there would be no problem. The full set of fields may contain additional ones that ECMA-402 adds as more calendars get added to CLDR.

@ljharb
Copy link
Member Author

ljharb commented May 3, 2022

I don't think 402 should be just adding properties willy-nilly to any object besides the one it owns, Intl. 402 can certainly make a new Calendar subclass with anything on it, but the shapes of everything that's defined in 262 should be unchanged after 402 is layered on top.

@ptomato ptomato added spec-text Specification text involved meeting-agenda normative Would be a normative change to the proposal labels May 6, 2022
@ptomato
Copy link
Collaborator

ptomato commented May 24, 2022

It occurred to me that we might consider this point moot if we adopt #2193.

@sffc
Copy link
Collaborator

sffc commented May 24, 2022

#2193 means that 402 does not "add" the fields, but we still have the situation where different 262 implementations having different sets of calendars have different fields on the Date prototype. Is that okay?

@ptomato
Copy link
Collaborator

ptomato commented Sep 15, 2022

We discussed this in the Temporal champions meeting of 2022-09-15. @sffc pointed out that TG2 is currently deciding how to specify the Chinese calendar which will require cycle and cycleYear fields. (This is the first instance I'm aware of where one of the CLDR calendars actually requires defining a getter that is not era or eraYear.) We would like to avoid the situation where CLDR adds a calendar after Temporal reaches Stage 4, which requires other fields than era, eraYear, cycle, and cycleYear, and TG2 has to block shipping that calendar until TG1 agrees to add accessors for its extra fields to the Temporal prototype objects.

@ljharb
Copy link
Member Author

ljharb commented Sep 15, 2022

TG2 can't ship anything without TG1's agreement anyways, right?

@FrankYFTang
Copy link
Contributor

I would like to states my position about this
for adding the definintion of (Plain(Date(Time)?|YearMonth)|ZonedDateTime).prototype.era(Year)?
to the first 14 chapters of Temporal.

After I read carefaully of what @ljharb stated, I prefer we define the following functions, all return undefined in the first 14 chapters:

get Temporal.PlainDate.prototype.era
get Temporal.PlainDate.prototype.eraYear
get Temporal.PlainDateTime.prototype.era
get Temporal.PlainDateTime.prototype.eraYear
get Temporal.PlainYearMonth.prototype.era
get Temporal.PlainYearMonth.prototype.eraYear
get Temporal.ZonedDateTime.prototype.era
get Temporal.ZonedDateTime.prototype.eraYear
Temporal.Calendar.prototype.era
Temporal.Calendar.prototype.eraYear

(yes, including Temporal.Calendar)

@sffc
Copy link
Collaborator

sffc commented Nov 29, 2022

@rbuckton suggested:

Yeah, I'd lean towards something like a .getCalendarField("era"), etc. instead, so that the shape remains stable. It also avoids needing to add more properties in the future that are potentially unused based on the locale/calendar in use. It also could be .calendarData.era, where .calendarData is spec'd as a getter that just returns an empty object by default.

@ptomato
Copy link
Collaborator

ptomato commented Dec 1, 2022

This was discussed in the TC39 plenary meeting (slides). Notes will follow, but the conclusion was that TC39 prefers a "narrow yes" solution where we will add informative notes to ECMA-262 saying where ECMA-402 extends prototypes with additional properties.

We discussed this in the Temporal champions meeting of 2022-12-01 and will add such notes to the proposal.

@ptomato ptomato added editorial and removed meeting-agenda normative Would be a normative change to the proposal labels Dec 1, 2022
ptomato added a commit that referenced this issue Dec 1, 2022
As per TC39 plenary, the specification should include informative notes
indicating where ECMA-402 extends prototypes with additional properties.

Closes: #2169
@ptomato
Copy link
Collaborator

ptomato commented Dec 1, 2022

Possible language for this in #2442, have a look and see what you think.

@ptomato ptomato self-assigned this Dec 1, 2022
@ptomato ptomato added this to the Stage "3.5" milestone Dec 8, 2022
ptomato added a commit that referenced this issue Feb 1, 2023
As per TC39 plenary, the specification should include informative notes
indicating where ECMA-402 extends prototypes with additional properties.

Closes: #2169
Aditi-1400 pushed a commit to Aditi-1400/proposal-temporal that referenced this issue Mar 7, 2023
As per TC39 plenary, the specification should include informative notes
indicating where ECMA-402 extends prototypes with additional properties.

Closes: tc39#2169
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editorial spec-text Specification text involved
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants