tc39 / tc39/proposal-amount

ECMA-402 layering is incorrect

Open
#95 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
58
Forks
12
Avg merge
2h 35m
Merged PRs (30d)
2

Description

It will be necessary for ECMA-402 operations to supersede those in ECMA-262, but the current spec text handles that incorrectly—ECMA-402 requires GetAmountConvertToOptions to provide locale and usage by reading properties from options [at the right time], while ECMA-262 requires absence of such [[Get]] operations. This proposal currently defines a GetAmountConvertToOptions that is documented to return a Record with fields [[Locale]] and [[Usage]], but fails to do so.

There's also what looks to me like an uncomfortable about of redundancy between the ECMA-262 Amount.prototype.convertTo and the ECMA-402 Amount.prototype.convertTo which makes it difficult to observe what is actually different.

I think things would be well-structured like so:

  • There is a single common GetAmountConvertToOptions, with the reading and validation of locale, localeMatcher, and usage required by ECMA-402 but absent in ECMA-262 being handled as either normative optional steps (analogous to ToBoolean) or as calls to operations with no-op default implementations and superseding definitions in ECMA-402 (analogous to ECMA-262 Array.prototype.toLocaleString and its ECMA-402 replacement).
  • The majority of Amount.prototype.convertTo is likewise common to both specs, delegating to an operation like Let targetUnit be ? SelectUnitConversionTarget(sourceValue, sourceUnit, validatedOpts) with definitions like the following:
    • ECMA-262:
      1. Let _unit_ be _validatedOpts_.[[Unit]].
      1. If _unit_ is *undefined*, throw a *TypeError* exception.
      1. Return _unit_.
      
    • ECMA-402:
      1. Let _unit_ be _validatedOpts_.[[Unit]].
      1. Let _requestedLocales_ be _validatedOpts_.[[RequestedLocales]].
      1. Let _usage_ be _validatedOpts_.[[Usage]].
      1. If _unit_ is not *undefined*, then
        1. If _requestedLocales_ is not *undefined* or _usage_ is not *undefined*, throw a *TypeError* exception.
        1. Return _unit_.
      1. If _requestedLocales_ is *undefined* and _usage_ is *undefined*, throw a *TypeError* exception.
      1. NOTE: The following steps do not yet provide or utilize data associated with Unicode locale extension sequence keys <code>rg</code> (Region Override), <code>ms</code> (Unicode Measurement System Identifier), or <code>mu</code> (Measurement Unit Preference Override), despite their relevance to the algorithms of <a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">UTS #35 Part 6 Supplemental, Unit Preferences</a>.
      1. Let _availableLocales_ be an Available Locales List which includes all language tags corresponding with locales for which CLDR file <a href="https://github.com/unicode-org/cldr/blob/main/common/supplemental/units.xml"><code>units.xml</code></a> defines unit preferences in <code><unitPreferenceData></code>. If the implementation supports additional unit preferences, _availableLocales_ should also include their corresponding language tags.
      1. Let _localeMatcher_ be _validatedOpts_.[[LocaleMatcher]].
      1. Let _relevantExtensionKeys_ be a new empty List.
      1. Let _localeResolution_ be ResolveLocale(_availableLocales_, _requestedLocales_, the Record { [[localeMatcher]]: _localeMatcher_ }, _relevantExtensionKeys_).
      1. Let _resolvedLocale_ be _localeResolution_.[[Locale]].
      1. Let _region_ be the result of running the <a href="https://unicode.org/reports/tr35/tr35-info.html#compute--regions">UTS #35 Part 6 Supplemental, Compute regions</a> algorithm with input locale identifier _resolvedLocale_.
      1. Let _sourceConversionRecord_ be ? GetUnitConversionFactor(_sourceUnit_).
      1. Let _category_ be _sourceConversionRecord_.[[Category]].
      1. If _usage_ is *undefined*, set _usage_ to *"default"*.
      1. Set _unit_ to the result of running the <a href="https://unicode.org/reports/tr35/tr35-info.html#compute-the-preferred-output-unit">UTS #35 Part 6 Supplemental, Compute the preferred output unit</a> and <a href="https://unicode.org/reports/tr35/tr35-info.html#search-the-ranked-units">UTS #35 Part 6 Supplemental, Search the ranked units</a> algorithms with inputs _category_, _usage_, and _region_ for an input measure corresponding with _sourceValue_ and _sourceUnit_.
      1. Return _unit_.
      
  • To better accommodate the above, ResolveLocale parameter localeData is made optional:
     1. Let _foundLocale_ be _r_.[[locale]].
    +1. Let _result_ be a new Record.
    +1. If _localeData_ is not present, then
    +  1. Assert: _relevantExtensionKeys_ is an empty List.
    +  1. Set _result_.[[LocaleData]] to *undefined*.
    +1. Else,
    -1. Let _foundLocaleData_ be _localeData_.[[<_foundLocale_>]].
    -1. Assert: _foundLocaleData_ is a Record.
    -1. Let _result_ be a new Record.
    -1. Set _result_.[[LocaleData]] to _foundLocaleData_.
    +  1. Let _foundLocaleData_ be _localeData_.[[<_foundLocale_>]].
    +  1. Assert: _foundLocaleData_ is a Record.
    +  1. Set _result_.[[LocaleData]] to _foundLocaleData_.
    

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with GetAmountConvertToOptions and the ECMA-262 and ECMA-402 Amount.prototype.convertTo sections, then review the ResolveLocale algorithm and the proposed layering examples. Compare the shared and superseding steps, and consider the issue resolved when the ECMA-262/ECMA-402 interaction and optional locale-data handling are specified consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.