Closed sffc closed 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'
});
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);
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.
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:
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.
@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
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.
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 ?
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.
Intl
is the API that should allow both singular and plural field names,
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.
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.
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.
some additional info of other Duration library in JS
so... not ALL javascript duration package only support plural forms
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
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?
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
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:
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:
None of them are consistency WITHIN ECMA262 and ECMA402
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?
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)
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.
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
- 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
Additional platforms' durations:
I was unable to find examples of any platforms that use singular names for duration attributes.
Meeting 2021-04-15:
smallestUnit
, largestUnit
, and unit
option values. Duration.from
, Duration.p.with
, and any other method where duration-like object literals are accepted. Conversely, non-Duration types will ONLY accept singular property names in methods that accept object literals. smallestUnit
, largestUnit
, or unit
option values. Even though Temporal option values can accept singular or plural unit names, the singular variant will now be preferred for all Temporal types, including Duration. This is a change from the current preference of plural unit names in Duration-related docs but singular unit names for other types. The impact of this change in preference will be:
Duration.p.round
, Duration.p.total
, Duration.p.toString
, and all other types' until
and since
methods will change to prefer the singular variant. The docs will also note that the plural variant is accepted.smallestUnit
, largestUnit
, or unit
option values will all change to use singular variants. smallestUnit
, largestUnit
, and unit
option values will change to prefer singular values. The singular values will be marked as non-deprecated and the plural variants will be marked as deprecated.
- 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.
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:
Thoughts on making the Temporal.Duration field names singular?