tc39 / proposal-temporal

Provides standard objects and functions for working with dates and times.
https://tc39.es/proposal-temporal/docs/
Other
3.29k stars 149 forks source link

Naming of Temporal.Duration fields #325

Closed sffc closed 3 years ago

sffc commented 4 years ago

In Intl.DateTimeFormat, Intl.NumberFormat, Intl.DisplayNames, and even Temporal.DateTime, the date/time fields are singular: "second", "minute", "hour", "day", etc.

However, in Temporal.Duration, they are plural: "seconds", "minutes", etc.

I understand the reasoning, that it sounds more natural in English to say "seconds: 30" instead of "second: 30", but there are some downsides to the inconsistent naming:

  1. Users may want to use the same key as input to both Temporal.Duration and one of the other classes
  2. Non-native English speakers who don't care about language fluency have to learn to use singular in some cases and plural in others

Thoughts on making the Temporal.Duration field names singular?

meyerweb commented 3 years ago

I’ve been working on porting the Temporal documentation to MDN, which means I’ve been through the documentation several times now, and I didn’t once find the plural field values in Temporal.Duration bothersome. In fact, had they been singular, I’m pretty sure I’d have asked why that choice was made, because it would have seemed odd.

In part, the difference of singular in Temporal.PlainDateTime and plural in durations made sense to me because when using PlainDateTime, you’re working with a single exact moment in time. With Duration, you’re supplying or receiving some number of units of time, which will usually be in multiples—2 years, 5 days; 13 months; 17 minutes; or what have you. Even in the case where the number is singular, like one year, it would follow the human pattern “How many years is this?” “It’s one year.”

More to the point, whenever I’ve worked with APIs where a single value is supplied or returned, and that value can be multiple in the sense of more (or less) than one, the field names are usually plural. But, fearing a selective memory, I went and looked at some existing time APIs, and they all seem to use plural labels for durations. In moment.js:

moment.duration({
    seconds: 2,
    minutes: 2,
    hours: 2,
    days: 2,
    weeks: 2,
    months: '2',
    years: '2'
});

In Abseil:

constexpr absl::Duration ten_ns = absl::Nanoseconds(10);
constexpr absl::Duration min = absl::Minutes(1);
constexpr absl::Duration hour = absl::Hours(1);
absl::Duration dur = 60 * min;  // dur == hour
absl::Duration half_sec = absl::Milliseconds(500);
absl::Duration quarter_sec = 0.25 * absl::Seconds(1);

In Luxon:

Name Type
obj.years number
obj.quarters number
obj.months number
obj.weeks number
obj.days number
obj.hours number
obj.minutes number
obj.seconds number
obj.milliseconds number

For that matter in C++:

Type Definition
std::chrono::nanoseconds duration</*signed integer type of at least 64 bits*/, std::nano>
std::chrono::microseconds duration</*signed integer type of at least 55 bits*/, std::micro>
std::chrono::milliseconds duration</*signed integer type of at least 45 bits*/, std::milli>
std::chrono::seconds duration</*signed integer type of at least 35 bits*/>
std::chrono::minutes duration</*signed integer type of at least 29 bits*/, std::ratio<60>>
std::chrono::hours duration</*signed integer type of at least 23 bits*/, std::ratio<3600>>
std::chrono::days duration</*signed integer type of at least 25 bits*/, std::ratio<86400>>
std::chrono::weeks duration</*signed integer type of at least 22 bits*/, std::ratio<604800>>
std::chrono::months) duration</*signed integer type of at least 20 bits*/, std::ratio<2629746>>
std::chrono::years duration</*signed integer type of at least 17 bits*/, std::ratio<31556952>

…and in Rust:

#![feature(duration_constants)]
use std::time::Duration;

assert_eq!(Duration::SECOND, Duration::from_secs(1));

This all suggests that if Temporal uses singular labels in durations, developers will be more likely to typo the labels when trying to learn and use Temporal, which feels like unnecessary friction. It could also make more difficult the lives of developers who have to go back and forth between Temporal and other time-centric APIs as they work in legacy code versus new code.

FrankYFTang commented 3 years ago

But we discussed this above

Before Temporal group presented the proposal to TC39 for Stage 3 advancement, have any one bring up the following issues:

  1. ECMA262 has precedence to use plural names for LIST but not number in Internal Slots?
  2. ECMA262 has precedence to use plural names for API to return array / iterator but not a single value?
  3. ECMA402 has output unit in singular form in Intl.NumberFormat and Intl.RelativeTimeFormat ?

I understand the use of plural have been discussed with Temporal and the use of Intl.DateTimeFormat (which is a total different thing) have been discussed. But are you sure 1, 2, 3 above have been discussed?

The issue here is not which form a person like or dislike, but the consistency within ECMA262 / ECMA402 and the consequence impacting the shape of the other part of the standard and how would developer to use the output of one function to feed into the input of another function.

I would prefer that we consider Stage 3 proposals stable. https://tc39.es/process-document/ said the following:

Stage 3 Candidate Purpose: Indicate that further refinement will require feedback from implementations and users.

I am providing you feedback as someone who is planning on implementations. ECMA402 is also providing you feedback as users of Temporal (since ECMA402 would need to use Temporal to interact with Intl.DurationFormat (the round() in particular) and allow Temporal.Duration.prototype.toLocaleString to interact with Intl.DurationFormat.prototype.format . This is exactly "feedback from users" ( I would claim the design of Intl.DurationFormat to use Temporal.Duration.prototype.round a feedback from USER) and "feedback from implementations" ( I would claim to implementation Temporal.Duration.prototype.toLocaleString on v8 a "feedback from implementations".

THEREFORE, it is now the PERFECT TIME (which is designed by the process document) for us, who are implementations and users to provide TC39 the feedback. These feedback are hard to imaging until the spec text is stable enough to plan for implementation, and I discover these issue during my design planning, which is exactly the designed time from TC39 for us to report.

Acceptance Signifies The solution is complete and no further work is possible without implementation experience, significant usage and external feedback.

Have any of you already have "implementation experience", "significant usage", "external feedback" already? I am designing how to implement "7.3.24 Temporal.Duration.prototype.toLocaleString ( [ locales [ , options ] ] )" https://tc39.es/proposal-temporal/#sec-temporal.duration.prototype.tolocalestring now and I provide this feedback because I experience difficulty in the design.

Post-Acceptance Changes Expected Limited: only those deemed critical based on implementation experience

Yes Temporal is in Stage 3 already. But let me remind you it is not yet in Stage 4. In order to reach stage 4 you need to have

It can be stuck in Stage 3 for a very long time if the champion group ignore realistic and important feedback from people who are planning to work on implementation.

FrankYFTang commented 3 years ago

@meyerweb I love the reference you provided. However, none of them are related to the key issue of "consistency within ECMA262 and ECMA402". They all prove a good point that in OTHER environment plural form are used to represent a single numeric value. But none of them provide any support to deal with the "inconsistency" issue inside the ECMA262 and ECMA402.

Notice, I would not bring this issue up now if I didn't hit the consistency issue inside ECMA262 and ECMA402 during design. I have no personal preference of using singular or plural. If Temporal is not part of ECMA262 or ECMA402 and there are no need to interact with ECMA402 then I have no problem for you to use plural form. But that is not the case. The use of plural form have impact to the coherence and consistency of ECMA402. It will make the implementation difficult for future related proposal (remember Temporal delegated toLocaleString to ECMA402 - Intl.DurationFormat ) to interact between Temporal. And will make the users of ECMA402 which mix using different Intl object difficult and confusing. You cannot just look at how the user of Temporal think about the issue, you have to consider those users who already use Intl.NumberFormat and Intl.RelativeTimeFormat (which both are already Stage 4) and what kind of inconsistency Temporal may create to them. Temporal is propose to be 1) PART of ECMA262 and 2) Delegate some part of the spec behavior to ECMA402 and therefore the consistency with ECMA262 and ECMA402 is much more important than w/ other library such as moment.js.

The key problems we are facing now, are while we are 1) designing Intl.DurationFormat (as a user for Temporal.Duration) proposal, we found inconsistency (with other Intl object) if the proposal is going forward to be consist with Temporal and 2) designing how to implement Temporal - in particular how to implement the format method (toLocaleString) how to make it consistent with Intl.DurationFormat.prototype.format and how to make that consistent with Intl.DurationFormat.prototype.formatToParts and how could it be consistent with other preexisting Intl object in ECMA402

My bottomline are

  1. The output value of "unit" property in Intl.DurationFormat.prototype.formatToParts need to consistent with the output value of "unit" property in Intl.RelativeTimeFormat.prototype.formatToParts [both represent the number of days, years, months, etc]
  2. The output value of "smallestUnit" and "largestUnit" of Intl.DurationFormat.prototype.resolvedOptions need to be consistent with the output value of the "unit" property in Intl.NumberFormat.prototype.resolvedOptions [both are referring to the unit of a number of X]
  3. The output value of "unit" property in Intl.DurationFormat.prototype.formatToParts need to be consistent with it's input property name [which was established before - see Shane's presentation for the detail discussion in TC39 2019]
  4. The input property name for Intl.DurationFormat.prototype.formatToParts need to be consistent with the input property name of Intl.DurationFormat.prototype.format [This is necessary to keep both format conherant]
  5. The input property name of Intl.DurationFormat.prototype.format need to be consist with "7.2.2 Temporal.Duration.from ( item )" and therefore could be used by Temporal.Duration constructor "7.3.24 Temporal.Duration.prototype.toLocaleString ( [ locales [ , options ] ] )" consistently.
  6. The input property name of Intl.DurationFormat.prototype.format and formatToParts need to be consist with "7.3.15 Temporal.Duration.prototype.with ( temporalDurationLike )" in Temporal

Notice in https://tc39.es/proposal-temporal/#sec-temporal.duration.prototype.tolocalestring Temporal proposal states: "An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Temporal.Duration.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."

And we, who are working on ECMA402, are trying to specify the so-called "the Temporal.Duration.prototype.toLocaleString method as specified in the ECMA-402 specification." which not yet exist . And we provide you this feedback because it is difficult to produce such spec text without INCONSISTENCY. But the INCONSISTENCY is not acceptable.

FrankYFTang commented 3 years ago

The other way think about this issue is, not only it is a CONSISTENCY issue, it would create INTEROPERABILITY with other ECMA402 APIs if you keep the expected property name of the input of Temporal.Duration in plural form. Have INTEROPERABILITY issue got discussed with Temporal group before bringing up for Stage 3 proposal ?

meyerweb commented 3 years ago

I saw a proposal to have both singular and plural duration field names in Temporal, which I suppose is a possible path forward, but honestly it seems to me that Intl is the API that should allow both singular and plural field names, because its singular names are in conflict with every datetime API I found, some going back decades. Seems like that’s the real consistency issue here.

Beyond that possibility, isn’t it possible to create interoperability by having interpreters know that they should translate from the singular field names in Intl to the plural field names in Temporal, and vice versa? I can’t imagine there have been no other situations where the interface between two APIs had to be mapped between differing labels.

FrankYFTang commented 3 years ago

Intl is the API that should allow both singular and plural field names,

  1. The problem is the OUTPUT in the Intl API have to be in ONE but not both way. Namely- the string output by Intl.NumberFormat.resolvedOptions() and Intl.RelativeTimeFormat.prototype.formatToParts()

Intl.RelativeTimeFormat already take plural forms of name, but it will only output unit name in singular- which Temporal.Duration does not accept (see below). And that is one of the key problem.

  1. The key interoperability issue from Temporal to Intl is Temporal won't take singular names in Temporal.Duration.prototype.with ( temporalDurationLike ) https://tc39.es/proposal-temporal/#sec-temporal.duration.prototype.with and Temporal.Duration.from ( item ) https://tc39.es/proposal-temporal/#sec-temporal.duration.from

Notice in ECMA262 - all other plural are referring to a LIST of thing- a list of number a list of numbers, etc. So beyond INTEROPERABILITY issue, Temporal also introduce CONSISTENCY issue within ECMA262.

FrankYFTang commented 3 years ago

the real consistency issue here The consistency issue is important within the ECMA262 specification itself. We cannot produce a coherent standard if the standard is not consistent with other parts of the naming within the same specification.

FrankYFTang commented 3 years ago

some additional info of other Duration library in JS

so... not ALL javascript duration package only support plural forms

FrankYFTang commented 3 years ago

example of using singular in API on other programming languages:

ICU4J (Java) - Notice all unit is in singular form, not plural form

In Android API (Java) https://developer.android.com/reference/android/icu/text/MeasureFormat https://developer.android.com/reference/android/icu/util/MeasureUnit

In Microsoft .NET API

ICU4C

FrankYFTang commented 3 years ago

it seems to me that Intl is the API that should allow both singular and plural field names,

OK, I file ticket for Intl in https://github.com/tc39/ecma402/issues/564

But this is enough even if we change it. Would you agree to also let Temporal.Duration.prototype.with ( temporalDurationLike ) and Temporal.Duration.from ( item ) to accept singular form?

FrankYFTang commented 3 years ago

Also, international standard are using the singular form for the duration unit For example: Table 5 in https://ucum.org/ucum.html and https://physics.nist.gov/cuu/Units/outside.html https://unicode-org.github.io/cldr/ldml/tr35-general.html#Example_Units

littledan commented 3 years ago

However, none of them are related to the key issue of "consistency within ECMA262 and ECMA402".

On the consistency angle, if you take a look at the examples that @meyerweb gave above, there is a common pattern where the duration fields are plural and the date/time fields are singular:

(Some of the other examples above (e.g., C++ std::chrono and Rust std::time) seem to base their whole API on durations and so there's no distinct getter for date/time values. I don't think we'll do this radical kind of redesign for Temporal.)

I am providing you feedback as someone who is planning on implementations.

This is design-level feedback, even if it's coming from an implementer. TC39's process asks for all of this design-level feedback before Stage 3 and does not treat implementers specially in this respect. As the process doc says,

Given that consensus on Stage 3 means "the solution is complete" (i.e., all open design issues have been resolved including anticipated implementation and ecosystem compatibility issues), all TC39 participants should validate the design of proposals they care about before granting Stage 3 consensus. Stage 3 proposals which have fulfilled the acceptance criteria for Stage 4 may not be withheld from advancement unless the issue raised is related to implementation experience or identifies a problem or information which has not previously been discussed by the committee. The intention is to allow implementers to invest in implementations, and maintain the significance of stage 3 in the process.

I was assuming that, as a TC39 participant (and closely collaborating coworker of a proposal co-champion), @FrankYFTang would have the chance to review the Temporal proposal over the four-month period we gave between when the proposal was announced as "frozen" and when we asked the committee for Stage 3, even though Intl.DurationFormat was not yet under Stage 3 review. The issue being raised isn't about implementation experience, and it's also not about problems which were not previously discussed (given that @sffc raised the consistency issue in the start of this thread).

My understanding of TC39's process is:

FrankYFTang commented 3 years ago

However, none of them are related to the key issue of "consistency within ECMA262 and ECMA402".

On the consistency angle, if you take a look at the examples that @meyerweb gave above, there is a common pattern where the duration fields are plural and the date/time fields are singular:

  • Moment: Both singular and plural accessors (docs)
  • Luxon: Singular getters (e.g., hour)

    • with Luxon being a sort of v3, it sounds like the plural accessors are viewed as legacy in moment
  • Abseil: Singular getters (docs)

None of them are consistency WITHIN ECMA262 and ECMA402

FrankYFTang commented 3 years ago

it's also not about problems which were not previously discussed (given that @sffc raised the consistency issue in the start of this thread).

I do not believe @sffc ever raise issue of all other part of ECMA262 use plural form of name for "A list of thing" before. Do you agree that is a new consistency issue that Temporal committee never concern about before Temporal advanced into Stage 3?

FrankYFTang commented 3 years ago

The issue being raised isn't about implementation experience

What make you say so? I literally discovered the issue when I try to prototype how to format duration in v8 three weeks ago. It is my implementation experience bring me to figure out if we keep the Temporal proposal AS IS it will have conflict with the rest of ECMA402 implementation in V8 and hard to reuse code. (explicitly, the code to output formatToParts)

littledan commented 3 years ago

None of them are consistency WITHIN ECMA262 and ECMA402

Sure, if we consider the only reference points to be ECMA-262 and ECMA-402, then we have no precedents here.

I do not believe @sffc ever raise issue of all other part of ECMA262 use plural form of name for "A list of thing" before.

Lists don't arise here, so I don't see why this point is relevant.

It is my implementation experience bring me to figure out if we keep the Temporal proposal AS IS it will have conflict with the rest of ECMA402 implementation in V8 and hard to reuse code. (explicitly, the code to output formatToParts)

I don't think that this is a sufficiently significant implementation burden to affect what we want the design to be. It's more important to choose names that are intuitive, and the predominant evidence (both from comparing to other libraries and from feedback of people on this thread) is that plural makes more sense. If the implementation burden were much greater (e.g., if plural was somehow hugely slower), then the balance might be different, but a small amount of duplication does not seem to me to be enough of a cost.

FrankYFTang commented 3 years ago

Notice, Temporal is referring to ISO8601 and the definition of ISO8601 related to Duration are all in singular form, see "2.2 Time units, nominal durations and time intervals" http://www.loc.gov/standards/datetime/iso-tc154-wg5_n0038_iso_wd_8601-1_2016-02-16.pdf

justingrant commented 3 years ago
  • Moment: Both singular and plural accessors (docs)

Moment Durations are only documented using plural names. https://momentjs.com/docs/#/durations/

EDIT: date-fns also seems to use only plural names for durations: https://date-fns.org/v2.21.1/docs/intervalToDuration

justingrant commented 3 years ago

Additional platforms' durations:

I was unable to find examples of any platforms that use singular names for duration attributes.

justingrant commented 3 years ago

Meeting 2021-04-15:

justingrant commented 3 years ago
  • No normative change to Temporal spec

After investigation, there is one small normative change that is required: the singular 'week' option value is currently not accepted by Temporal methods (because there's no week property on any Temporal types) but if we make singular unit names the preferred form, then we'd need to accept 'week'. (Its synonym 'weeks' is already accepted.) See #1491.