Skip to content

ECMA-402 layering is incorrect #95

@gibson042

Description

@gibson042

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_.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions