-
Notifications
You must be signed in to change notification settings - Fork 9
Consider error checking for using dateStyle/timeStyle together with other options #2
Comments
👍 When orthogonal options are used together, it's a clear API misuse. It helps development to get an error early than having the API to silently pick one option over the other. PS: Out of the scope here, but a similar scenario happens on https://github.com/sffc/proposal-unified-intl-numberformat, e.g., using |
My understanding from the ECMA 402 meeting a few months ago was that it was desirable behavior to silently ignore options that are unused in the options bag. It's not always API misuse. See Eemeli's comment here: https://github.com/tc39/ecma402/blob/master/meetings/notes-2018-03-16.md
|
We discussed this issue in the September 2018 |
Did you post this from the future? ;) How about creating separate but symmetrical API methods for each |
@mathiasbynens We already decided not to do that for currency. I don't really understand the purpose of the multi-method approach; could you elaborate? |
You wouldn’t need the What’s the benefit of stuffing both features into the same method? It encourages polymorphism for seemingly no good reason. |
@mathiasbynens, a dedicated method Intl.UnitFormat was the initial proposal, but like @littledan mentioned, NumberFormat already includes (the orthogonal) currency (since the old 1st version of Ecma-402 API) and then the unified API proposal gained traction. In the unified API proposal, Intl.NumberFormat is extended to support units (orthogonal to number and currency) and also extra options: some are common to all (e.g., compact notation, sign display), some are specific to particular features (e.g., currency accounting format for currency only). Given this context, are you in line with the path this is going? Any ideas? |
There are a lot of ways that we could design multiple different styles, each with a different set of options. Here are just a few:
All of these options have advantages and disadvantages. We decided on the first one when discussing the units proposal, which is a precedent that we should follow in similar APIs. We can reopen that discussion while the NumberFormat proposal is still in Stage 2, but I personally don't see a super compelling case for any of the other options over the first. |
With regard to the comment about separate methods: Let's say we split currency, unit, percent, and standard number formatting all into different API functions. Fine; we have 4 methods, all of which accept the same options for rounding style, notation, etc. However, next year we realize that fraction rounding needs a different set of options than significant digits rounding. Since we want to split everything up into separate methods, now we have 8 methods, one for each combination of style and rounding. Things get ugly very fast. In Java, the style set forth by libraries like Google Guava is the "fluent" pattern. It looks like this:
That's fine, and it enforces at compile time a namespace to make sure you don't have conflicting settings or settings that have no effect at runtime. However, we're in JavaScript, not Java. Java has no notion of object literals, which are a foundational building block of JavaScript APIs. It would be artificial and unauthentic to take the Java notion of methods and map it onto JavaScript. |
It's not my goal to extend (and rehash) this much... Anyway, one quick question:
The 4 methods would accept the new options, no? Sorry, I didn't follow the 8 methods... |
The reason that was suggested for separating styles into separate methods was to avoid the problem of passing an option to the object literal that is used in some situations but not in others. (By the way, I don't like the word "style"; "unit type" would be more precise.) What I'm trying to say is that this issue is not unique to the four styles. Rounding strategies and notation are two examples of things besides styles that have different settings depending on which type you choose. For example, maximumFractionDigits is implicitly ignored when maximumSignificantDigits is set. Soon, the setting compactDisplay will be ignored if a non-compact notation is chosen. If you wanted to be truly "type-safe" within the framework where all settings are specified in a single object literal, you need something like this, where each constructor accepts a very specific set of options in the object literal:
This is where I got the explosion from 4 to 8. Adding in the three notation types explodes that again to 24. |
Thanks for the clarification, makes sense |
Should we discuss this again in an Intl meeting? |
To recap, there are at least two reasons specifically in favor of ignoring unused options:
My opinion is still that we should keep with existing behavior and silently ignore unused options. I don't think it should be part of the spec, but maybe we could add a feature to eslint that catches when unused properties are hard-coded into an options object. I think the people with an opinion on this issue have already commented, and we've already discussed it at two ECMA 402 meetings. I don't see a reason to add it to the agenda unless there are new revelations. |
I like the eslint idea. Is anyone interested in trying out an implementation? (Would this be possible with TS types?) |
Making concrete, here is the author failure mode: new Intl.DateTimeFormat('en', {
dateStyle: 'short',
// The following values are disregarded:
year: 'numeric',
month: 'long',
day: 'numeric'
});
I don't find providing a hard |
I know this issue was resolved over a year ago, but I've had some changing feelings on it. The main argument I had made in favor of ignoring unused options was the precedent of ignoring unused options in Intl.NumberFormat. However, the situation is a bit different when it comes to user expectations. A user would have less of a reasonable expectation for "currencyDisplay" to do anything when style is set to "unit". In dateStyle/timeStyle, though, I can see users legitimately trying to use the other options to override certain fields in dateStyle/timeStyle. Examples: // OK: obviously, currencyDisplay won't do anything here.
new Intl.NumberFormat(undefined, {
style: "unit",
unit: "meter",
currencyDisplay: "narrow"
});
// Hmm, a user could have legitimate expectations for the following.
new Intl.DateTimeFormat(undefined, {
dateStyle: "short",
month: "long"
}); Another advantage of throwing would be that if we did decide to add interop with the other options in the future, such as suggested in #40, we can do that only if we throw today. If we ignore today, we have a higher risk of breaking the web. |
IIRC we decided at the time to make an exception for So, we wanted to have this to work: new Intl.DateTimeFormat("en-US", {
timeStyle: "short",
hourCycle: "h24"
}); For other fields, my thoughts are:
I don't have enough insight to claim which one is more likely to have an impact on the outcome, so my initial thought would be to postpone it till |
My fault for posting in a closed issue. I copied your comments to #40. Let's discuss over there. |
The current spec text does not read the other options if dateStyle/timeStyle are set. Another option would be to throw some sort of error in this case. This might be better for debugging. cc @rxaviers
The text was updated successfully, but these errors were encountered: