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

Function on Intl vs method on Intl.Locale #4

Open
littledan opened this issue Jun 11, 2018 · 14 comments
Open

Function on Intl vs method on Intl.Locale #4

littledan opened this issue Jun 11, 2018 · 14 comments

Comments

@littledan
Copy link
Collaborator

@nciric originally suggested this feature as a method on Intl.Locale, rather than a function property Intl. Personally, I was originally thinking that we would eventually go with this as a method on locales. There's a third possibility, of making a display name factory, analogous to other Intl formatters. Let's discuss the pros and cons of each path here:

In favor of a Locale method

  • Example
var t = new Intl.Locale('sr')
t.languageNameOf('en')   // Енглески
t.regionNameOf('GB')     // Велика Британија

var x = new Intl.Locale('sr-Latn')
x.languageNameOf('en')   // Engleski
x.regionNameOf('GB')     // Velika Britanija
  • Pro
    • Terse and ergonomic
  • Con
    • First time we're attaching data lookup to Intl.Locale
    • Doesn't support locale negotiation

In favor of an Intl function

  • Example
let langs = getLanguageDisplayNames(["pl"], ["fr", "de", "en", "sr-Latn-XK"]);
langs === ["Francuski", "Niemiecki", "Angielski", "Serbski"];

let regs = getRegionDisplayNames(["pl"], ["US", "CA", "MX"]);
regs === ["Stany Zjednoczone", "Kanada", "Meksyk"];

let locs = getLocaleDisplayNames(["pl"], ["sr-RU", "es-MX", "fr-CA", "sr-Latn-XK"]);
locs === ["Serbski (Rosja)", "Hiszpański (Meksyk)", "Francuski (Kanada)", "Serbski (Łacińskie, Kosowo)"];
  • Pro
    • Supports locale negotiation (where a method on Locale could only return undefined to indicate failure)
    • Amortize costs by operating on an array
  • Con
    • Sustainable top-level use of Intl namespace?
    • Result of locale negotiation isn't exposed (as it is for

In favor of a factory object

  • Example
var n = new Intl.DisplayName('sr')
t.languageNameOf('en')   // Енглески
t.regionNameOf('GB')     // Велика Британија

var x = new Intl.DisplayName('sr-Latn')
x.languageNameOf('en')   // Engleski
x.regionNameOf('GB')     // Velika Britanija
  • Pro:
    • Gives a way to query the result of locale negotiation through resolvedOptions()
    • Consistent with all the other formatters
    • Might be able to amortize certain costs (TODO: evaluate this)
  • Con:
    • Wordy
    • Creates another constructor which doesn't do much

After writing all that out, I'm leaning slightly towards the last one, but my main intention in writing this up was so we could all think this through. Do you see any more pros or cons for particular options?

@jungshik
Copy link

See also tc39/ecma402#31 . It proposes Intl.DisplayName.
We also need options for name variants (official, causal, in-sentence, for menu item, etc).

@zbraniecki
Copy link

See also tc39/ecma402#31 . It proposes Intl.DisplayName.

This is potentially a separate API. We implemented both: Intl.getDisplayNames and Intl.get{Language|Region|Locale}DisplayNames:

I'm happy to revisit and unify, but I believe that the reason we kept locale in particular as a separate API is that it does pattern operation on language/region pair. getDisplayNames just returns names from CLDR. (of course that means that getDisplayNames could cover standalone language and standalone region, just not the locale).

@zbraniecki
Copy link

The reason I want for of what Daniel describes as a second variant is because all our usecases were lists. It almost never happened that a user needs to retrieve a display name of 2 locales. In some cases its one, but in almost all cases its a high number of locales - usually for a language/region/locale selection list/menu etc.

@rxaviers
Copy link

of course that means that getDisplayNames could cover standalone language and standalone region, just not the locale

@zbraniecki please could you give examples for standalone language and standalone region?

@rxaviers
Copy link

rxaviers commented Jul 16, 2018

@littledan let's also compare the space complexity of each proposal. It seems like individual functions such as Intl.getLanguageDisplayNames makes available specific portions of i18n data (i.e., CLDR), while other flavors would make available a much more broader portion (i.e., all supported features) of CLDR for later use.

@littledan
Copy link
Collaborator Author

@rxaviers Do you mean this as a vote in favor of the constructor-based approach?

@rxaviers
Copy link

Sure, let me clarify. Not a vote yet because I don't know if there are real implications...

I am wondering what's the cost in terms of storage for the different proposals. I guess both constructor-based approaches (i.e., the Locale method and factory object) would need to carry the complete set of data when initialized, because it doesn't know beforehand which "subfeatures" user would use (e.g., region display names, language display names, etc). How much space does this instance cost? Is this data already available in memory or does it have to be initialized? What's the cost for multiple instances?

The specific Intl function such as Intl.getLanguageDisplayNames already defines the scope, i.e., in this example the language display names only. Therefore, it requires a smaller data subset, a smaller footprint. It's worth to point out the same could be achieved on the constructor-based approaches if it took a "scope" option such as new Intl.DisplayName("sr", {languages: true}).

That being said, I'd like to hear about folks who have already implemented this and know the details. :)

@littledan
Copy link
Collaborator Author

I'd be surprised if the instances had nontrivial size. I thought they would just be views onto whatever data exists in a data file and might be loaded into memory on demand, or all at once at startup (not sure how ICU loads this data exactly).

@jungshik
Copy link

No heap allocation. Icu data is usually memory-mapped.

@rxaviers
Copy link

Ok thanks for clarifying...

@FrankYFTang
Copy link
Collaborator

sorry. made some mistake in the UI and accidentally close it.

@FrankYFTang
Copy link
Collaborator

In favor of a factory object

I am in favor of the "factory object" approach

@FrankYFTang
Copy link
Collaborator

Hi all- I am taking over the champion of this proposal now. Somehow, as a novice of github I messed up the transfer process and use a different process that won't carry all the fired issues to https://github.com/tc39/proposal-intl-displaynames. Could you refile your issue in https://github.com/tc39/proposal-intl-displaynames/issues ? Check my two proposed changes on https://github.com/tc39/proposal-intl-displaynames/pulls first. I think that address the issue you have here. I would like to ask to abandon this old one but move all discussion to https://github.com/tc39/proposal-intl-displaynames/issues instead.

@littledan
Copy link
Collaborator Author

Please either close this issue or refile this and other issues in that other repo so everything can be tracked together. I think this one can be closed, right? We have sort of settled on the factory approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants