profile
viewpoint
Daniel Ehrenberg littledan Igalia http://twitter.com/littledan Working on V8 and web standards, especially TC39.

push eventlittledan/proposal-symbols-as-weakmap-keys

Daniel Ehrenberg

commit sha c28c866f8f32684dec627fec9418c9847400f073

Update README.md

view details

push time in 2 hours

issue commenttc39/proposal-record-tuple

Names of `Tuple.prototype.*` methods

Let's continue discussing this, trying out code in the playground, and be open to revisiting names until Stage 3.

rauschma

comment created time in 4 hours

fork littledan/proposal-boxing-objects

A proposal for boxing objects into primitive types

fork in 5 hours

issue commenttc39/proposal-module-attributes

Avoid adding a new keyword for static imports (`with`)

  1. I think both versions are pretty easy to parse. (Definitely easier than import statements as a whole!)
  2. Yeah, I agree this is subjective; I guess I have the opposite opinion. I think positional arguments, generally, have the potential to increase confusion.
  3. I don't know whether you really want these things to be in 100% the same--import declarations are hopefully a bit nicer to use in general.
  4. Yes, the idea is to be comma-separated. We're open to including the curly brackets in the import statement, see #5 for more discussion

As for whether import() should have the one-level or two-level argument, that's another kind of orthogonal decision that we could bikeshed over, and has been discussed previously in this repo (sorry I'm not sure where exactly, maybe @xtuc has a cross-reference).

For depcache and integrity, I think these are better expressed out-of-band exclusively. When we have a piece of metadata that makes sense both in-band and out-of-band, we can think more concretely about how we could let users do either. I'd imagine, out-of-band could set a baseline, and in-band could add more things to that.

michael-ciniawsky

comment created time in 6 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.resolvedOptions">+      <h1>Intl.DurationFormat.prototype.resolvedOptions ()</h1>++      <p>This function provides access to the locale and options computed during initialization of the object.</p>++      <emu-alg>+        1. Let _df_ be the *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).+        1. For each row of <emu-xref href="#table-durationformat-resolvedoptions-properties"></emu-xref>, except the header row, in table order, do+          1. Let _p_ be the Property value of the current row.+          1. Let _v_ be the value of _df_'s internal slot whose name is the Internal Slot value of the current row.+          1. Assert: _v_ is not *undefined*.+          1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_).+        1. Return _options_.+      </emu-alg>++      <emu-table id="table-durationformat-resolvedoptions-properties">+        <emu-caption>Resolved Options of DurationFormat Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Locale]]</td>+            <td>`"locale"`</td>+          </tr>+          <tr>+            <td>[[NumberingSystem]]</td>+            <td>`"numberingSystem"`</td>+          </tr>+          <tr>+            <td>[[Style]]</td>+            <td>`"style"`</td>+          </tr>+          <tr>+            <td>[[Fields]]</td>+            <td>`"fields"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-instances">+    <h1>Properties of Intl.DurationFormat Instances</h1>++    <p>Intl.DurationFormat instances inherit properties from %DurationFormatPrototype%.</p>++    <p>Intl.DurationFormat instances have an [[InitializedDurationFormat]] internal slot.</p>++    <p>Intl.DurationFormat instances also have several internal slots that are computed by the constructor:</p>++    <ul>+      <li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li>+      <li>[[NumberingSystem]] is a String value with the `"type"` given in Unicode Technical Standard 35 for the numbering system used for formatting.</li>+      <li>[[Style]] is one of the String values `"long"`, `"short"`, `"narrow"`, or `"dotted"` identifying the duration formatting style used.</li>+      <li>[[Fields]] is a List value specifying which duration fields are required to be printed.</li>+      <li>[[Templates]] is a Record value containing template strings for each of the supported units for duration formatting.</li>

It looks like it's still not updated.

ryzokuken

comment created time in 6 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Why should -0 be normalized to 0 when placed in Records and Tuples, but not elsewhere in the language? I can understand how IEEE754 is confusing and not the best choice for the JS's long-time only numeric type (that's part of why I worked on BigInt and now Decimal), but I don't understand why "putting a value in a Record or Tuple" is the place we should intervene and "fix" things, any more than we could've decided something like, if you assign a Number to a let or const-bound variable, then -0 is normalized to 0.

bakkot

comment created time in 6 hours

push eventtc39/agendas

Sven Sauleau

commit sha 1379e900a61ae2adcab0dd780ea8eb4ce00b17fc

Update 06.md

view details

push time in 7 hours

PR merged tc39/agendas

Add module-attributes slides
+1 -1

0 comment

1 changed file

xtuc

pr closed time in 7 hours

issue commenttc39/proposal-module-attributes

Avoid adding a new keyword for static imports (`with`)

I haven't seen another discussion of this particular alternative. Could you say something about why you see this option as preferable? (Personally, I thought a keyword would be in keeping with the rest of the syntax of import statements.)

michael-ciniawsky

comment created time in 9 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

We previously proposed starting with as in TC39 and got very strong negative feedback, including from @bmeck.

devsnek

comment created time in 9 hours

issue commenttc39/proposal-record-tuple

Names of `Tuple.prototype.*` methods

@rauschma Can you say more about why a similar and terse name gets confusing? I thought it would be helpful... (I guess we should use the name reversed not reverse)

rauschma

comment created time in 10 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I'm not yet sold on normalizing -0 to 0. I would prefer if we could let all primitives be represented in Records and Tuples unscathed. Otherwise I worry this becomes yet another case for people to think about and consider whether it affects them. Users can always choose to normalize -0 to 0 themselves when constructing a Record or Tuple if that is what they want.

bakkot

comment created time in 10 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

@jkrems There are basically three options that the proposal lets host choose between: 1) Race and use the first value 2) Error if a second value occurs 3) Make two copies of the module when values disagree. All are permitted by the spec. I personally see 1 and 2 as bad for composition, and would aim to avoid them if I were designing a host.

@boneskull This proposal doesn't change how to import normal JS modules, so you are safe.

@eemeli I agree that we should be conservative in what module attributes and type values we add. However, we got strong feedback from various potential users (including @bmeck) that we should not make this proposal specific to the type, and permit other attributes on an equal syntactic footing. For now, IIUC the Babel parser only permits type to discourage fragmentation, but of course that can be revisited.

devsnek

comment created time in 10 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).

Could you file an issue to track this? I guess I'm asking the question because I'm surprised by the behavior here.

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma, Younies Mahmoud </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for Duration instances, and which is also used to key Records of templates to format individual Duration components: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+      <table class="real-table">+        <thead>+          <tr>+            <th>Internal Slot</th>+            <th>Property</th>+          </tr>+        </thead>+        <tr>+          <td>[[Years]]</td>+          <td>`"year"`</td>+        </tr>+        <tr>+          <td>[[Months]]</td>+          <td>`"months"`</td>+        </tr>+        <tr>+          <td>[[Weeks]]</td>+          <td>`"weeks"`</td>+        </tr>+        <tr>+          <td>[[Days]]</td>+          <td>`"days"`</td>+        </tr>+        <tr>+          <td>[[Hours]]</td>+          <td>`"hours"`</td>+        </tr>+        <tr>+          <td>[[Minutes]]</td>+          <td>`"minutes"`</td>+        </tr>+        <tr>+          <td>[[Seconds]]</td>+          <td>`"seconds"`</td>+        </tr>+        <tr>+          <td>[[Milliseconds]]</td>+          <td>`"milliseconds"`</td>+        </tr>+        <tr>+          <td>[[Microseconds]]</td>+          <td>`"microseconds"`</td>+        </tr>+        <tr>+          <td>[[Nanoseconds]]</td>+          <td>`"nanonseconds"`</td>+        </tr>+      </table>+    </emu-table>++    <emu-note>The [[Weeks]] field is still under discussion in Temporal. For more, check out the <a href="https://github.com/tc39/proposal-temporal/issues/532">Github thread</a> on the Temporal issue tracker.</emu-note>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. Let _result_ be a new empty List.+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. Let _patternParts_ be PartitionPattern(_durationFormat_.[[Templates]]).+          1. For each _patternPart_ in _patternParts_, do+            1. Let _p_ be _patternPart_.[[Type]].+            1. If _p_ is `"literal"`, then+              1. Append _patternPart_ to the end of _result_.+            1. Else if _duration_[[&lt;_p_&gt;]] is not *undefined* and _p_ exists in _durationFormat_.[[Fields]], then+              1. Let _num_ be FormatNumeric(_durationFormat_.[[NumberFormat]], _duration_[[&lt;_p_&gt;]]).+              1. Append the new Record { [[Type]]: _p_, [[Value]]: _num_ } to the end of _result_.+        1. Else,+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+            1. If _val_ is not *undefined* and _field_ exists in _durationFormat_.[[Fields]], then+              1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+              1. Let _pr_ be ! ResolvePlural(_durationFormat_.[[PluralRules]], val).+              1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].[[&lt;_pr_&gt;]].+              1. Let _parts_ be ! MakePartsList(_template_, _field_, _num_).+              1. Let _concat_ be an empty String.+              1. For each _part_ in _parts_, do+                1. Set _concat_ to the string-concatenation of _concat_ and _part_.[[Value]].+                1. If _part_ has a [[Unit]] field, then+                  1. Set _concat_ to the string-concatenation of _concat_ and _part_.[[Unit]].+              1. Append the new Record { [[Type]]: _field_, [[Value]]: _concat_ } to the end of _result_.+          1. Set _result_ to ! CreatePartsFromList(_durationFormat_.[[ListFormat]], _result_).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[PluralRules]] to ! Construct(%PluralRules%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>++    <emu-note>It's currently being discussed what the best strategy for field selection would be. For more information, check out the corresponding <a href="https://github.com/tc39/proposal-intl-duration-format/issues/3">Github thread</a>.</emu-note>

Nit: It'd be clearer if you said s/strategy/API/

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>

Good fix

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).

Right, you should not create a ListFormat in the "dotted" case. The pattern will just handle everything.

I don't understand whether users would want to select the list format style separately, or whether that'd feel too low-level. This is probably good to explore in an issue.

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.

Well, not in the "dotted" case. That's part of why I think the ListFormat logic should be up in PartitionDurationFormatPattern, and you shouldn't be iterating over the record here.

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.resolvedOptions">+      <h1>Intl.DurationFormat.prototype.resolvedOptions ()</h1>++      <p>This function provides access to the locale and options computed during initialization of the object.</p>++      <emu-alg>+        1. Let _df_ be the *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).+        1. For each row of <emu-xref href="#table-durationformat-resolvedoptions-properties"></emu-xref>, except the header row, in table order, do+          1. Let _p_ be the Property value of the current row.+          1. Let _v_ be the value of _df_'s internal slot whose name is the Internal Slot value of the current row.+          1. Assert: _v_ is not *undefined*.+          1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_).+        1. Return _options_.+      </emu-alg>++      <emu-table id="table-durationformat-resolvedoptions-properties">+        <emu-caption>Resolved Options of DurationFormat Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Locale]]</td>+            <td>`"locale"`</td>+          </tr>+          <tr>+            <td>[[NumberingSystem]]</td>+            <td>`"numberingSystem"`</td>+          </tr>+          <tr>+            <td>[[Style]]</td>+            <td>`"style"`</td>+          </tr>+          <tr>+            <td>[[Fields]]</td>+            <td>`"fields"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-instances">+    <h1>Properties of Intl.DurationFormat Instances</h1>++    <p>Intl.DurationFormat instances inherit properties from %DurationFormatPrototype%.</p>++    <p>Intl.DurationFormat instances have an [[InitializedDurationFormat]] internal slot.</p>++    <p>Intl.DurationFormat instances also have several internal slots that are computed by the constructor:</p>++    <ul>+      <li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li>+      <li>[[NumberingSystem]] is a String value with the `"type"` given in Unicode Technical Standard 35 for the numbering system used for formatting.</li>+      <li>[[Style]] is one of the String values `"long"`, `"short"`, `"narrow"`, or `"dotted"` identifying the duration formatting style used.</li>+      <li>[[Fields]] is a List value specifying which duration fields are required to be printed.</li>+      <li>[[Templates]] is a Record value containing template strings for each of the supported units for duration formatting.</li>

Looks like you added PluralRules in general but forgot to go back and fix up this part

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.resolvedOptions">+      <h1>Intl.DurationFormat.prototype.resolvedOptions ()</h1>++      <p>This function provides access to the locale and options computed during initialization of the object.</p>++      <emu-alg>+        1. Let _df_ be the *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).+        1. For each row of <emu-xref href="#table-durationformat-resolvedoptions-properties"></emu-xref>, except the header row, in table order, do+          1. Let _p_ be the Property value of the current row.+          1. Let _v_ be the value of _df_'s internal slot whose name is the Internal Slot value of the current row.+          1. Assert: _v_ is not *undefined*.+          1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_).+        1. Return _options_.+      </emu-alg>++      <emu-table id="table-durationformat-resolvedoptions-properties">+        <emu-caption>Resolved Options of DurationFormat Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Locale]]</td>+            <td>`"locale"`</td>+          </tr>+          <tr>+            <td>[[NumberingSystem]]</td>+            <td>`"numberingSystem"`</td>+          </tr>+          <tr>+            <td>[[Style]]</td>+            <td>`"style"`</td>+          </tr>+          <tr>+            <td>[[Fields]]</td>+            <td>`"fields"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-instances">+    <h1>Properties of Intl.DurationFormat Instances</h1>++    <p>Intl.DurationFormat instances inherit properties from %DurationFormatPrototype%.</p>++    <p>Intl.DurationFormat instances have an [[InitializedDurationFormat]] internal slot.</p>++    <p>Intl.DurationFormat instances also have several internal slots that are computed by the constructor:</p>++    <ul>+      <li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li>+      <li>[[NumberingSystem]] is a String value with the `"type"` given in Unicode Technical Standard 35 for the numbering system used for formatting.</li>+      <li>[[Style]] is one of the String values `"long"`, `"short"`, `"narrow"`, or `"dotted"` identifying the duration formatting style used.</li>

Where is this template stored?

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma, Younies Mahmoud </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for Duration instances, and which is also used to key Records of templates to format individual Duration components: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+      <table class="real-table">+        <thead>+          <tr>+            <th>Internal Slot</th>+            <th>Property</th>+          </tr>+        </thead>+        <tr>+          <td>[[Years]]</td>+          <td>`"year"`</td>+        </tr>+        <tr>+          <td>[[Months]]</td>+          <td>`"months"`</td>+        </tr>+        <tr>+          <td>[[Weeks]]</td>+          <td>`"weeks"`</td>+        </tr>+        <tr>+          <td>[[Days]]</td>+          <td>`"days"`</td>+        </tr>+        <tr>+          <td>[[Hours]]</td>+          <td>`"hours"`</td>+        </tr>+        <tr>+          <td>[[Minutes]]</td>+          <td>`"minutes"`</td>+        </tr>+        <tr>+          <td>[[Seconds]]</td>+          <td>`"seconds"`</td>+        </tr>+        <tr>+          <td>[[Milliseconds]]</td>+          <td>`"milliseconds"`</td>+        </tr>+        <tr>+          <td>[[Microseconds]]</td>+          <td>`"microseconds"`</td>+        </tr>+        <tr>+          <td>[[Nanoseconds]]</td>+          <td>`"nanonseconds"`</td>+        </tr>+      </table>+    </emu-table>++    <emu-note>The [[Weeks]] field is still under discussion in Temporal. For more, check out the <a href="https://github.com/tc39/proposal-temporal/issues/532">Github thread</a> on the Temporal issue tracker.</emu-note>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. Let _result_ be a new empty List.+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. Let _patternParts_ be PartitionPattern(_durationFormat_.[[Templates]]).+          1. For each _patternPart_ in _patternParts_, do+            1. Let _p_ be _patternPart_.[[Type]].+            1. If _p_ is `"literal"`, then+              1. Append _patternPart_ to the end of _result_.+            1. Else if _duration_[[&lt;_p_&gt;]] is not *undefined* and _p_ exists in _durationFormat_.[[Fields]], then+              1. Let _num_ be FormatNumeric(_durationFormat_.[[NumberFormat]], _duration_[[&lt;_p_&gt;]]).+              1. Append the new Record { [[Type]]: _p_, [[Value]]: _num_ } to the end of _result_.+        1. Else,+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+            1. If _val_ is not *undefined* and _field_ exists in _durationFormat_.[[Fields]], then+              1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+              1. Let _pr_ be ! ResolvePlural(_durationFormat_.[[PluralRules]], val).+              1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].[[&lt;_pr_&gt;]].+              1. Let _parts_ be ! MakePartsList(_template_, _field_, _num_).+              1. Let _concat_ be an empty String.+              1. For each _part_ in _parts_, do+                1. Set _concat_ to the string-concatenation of _concat_ and _part_.[[Value]].+                1. If _part_ has a [[Unit]] field, then+                  1. Set _concat_ to the string-concatenation of _concat_ and _part_.[[Unit]].+              1. Append the new Record { [[Type]]: _field_, [[Value]]: _concat_ } to the end of _result_.+          1. Set _result_ to ! CreatePartsFromList(_durationFormat_.[[ListFormat]], _result_).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.

I guess this is a TODO, to fill in with the actual logic?

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma, Younies Mahmoud </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for Duration instances, and which is also used to key Records of templates to format individual Duration components: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+      <table class="real-table">+        <thead>+          <tr>+            <th>Internal Slot</th>+            <th>Property</th>+          </tr>+        </thead>+        <tr>+          <td>[[Years]]</td>+          <td>`"year"`</td>+        </tr>+        <tr>+          <td>[[Months]]</td>+          <td>`"months"`</td>+        </tr>+        <tr>+          <td>[[Weeks]]</td>+          <td>`"weeks"`</td>+        </tr>+        <tr>+          <td>[[Days]]</td>+          <td>`"days"`</td>+        </tr>+        <tr>+          <td>[[Hours]]</td>+          <td>`"hours"`</td>+        </tr>+        <tr>+          <td>[[Minutes]]</td>+          <td>`"minutes"`</td>+        </tr>+        <tr>+          <td>[[Seconds]]</td>+          <td>`"seconds"`</td>+        </tr>+        <tr>+          <td>[[Milliseconds]]</td>+          <td>`"milliseconds"`</td>+        </tr>+        <tr>+          <td>[[Microseconds]]</td>+          <td>`"microseconds"`</td>+        </tr>+        <tr>+          <td>[[Nanoseconds]]</td>+          <td>`"nanonseconds"`</td>+        </tr>+      </table>+    </emu-table>++    <emu-note>The [[Weeks]] field is still under discussion in Temporal. For more, check out the <a href="https://github.com/tc39/proposal-temporal/issues/532">Github thread</a> on the Temporal issue tracker.</emu-note>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. Let _result_ be a new empty List.+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. Let _patternParts_ be PartitionPattern(_durationFormat_.[[Templates]]).

I guess I'm having trouble finding where this becomes a pattern... isn't this always supposed to be a Record with the duration-like fields?

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma, Younies Mahmoud </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for Duration instances, and which is also used to key Records of templates to format individual Duration components: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+      <table class="real-table">+        <thead>+          <tr>+            <th>Internal Slot</th>+            <th>Property</th>+          </tr>+        </thead>+        <tr>+          <td>[[Years]]</td>+          <td>`"year"`</td>+        </tr>+        <tr>+          <td>[[Months]]</td>+          <td>`"months"`</td>+        </tr>+        <tr>+          <td>[[Weeks]]</td>+          <td>`"weeks"`</td>+        </tr>+        <tr>+          <td>[[Days]]</td>+          <td>`"days"`</td>+        </tr>+        <tr>+          <td>[[Hours]]</td>+          <td>`"hours"`</td>+        </tr>+        <tr>+          <td>[[Minutes]]</td>+          <td>`"minutes"`</td>+        </tr>+        <tr>+          <td>[[Seconds]]</td>+          <td>`"seconds"`</td>+        </tr>+        <tr>+          <td>[[Milliseconds]]</td>+          <td>`"milliseconds"`</td>+        </tr>+        <tr>+          <td>[[Microseconds]]</td>+          <td>`"microseconds"`</td>+        </tr>+        <tr>+          <td>[[Nanoseconds]]</td>+          <td>`"nanonseconds"`</td>+        </tr>+      </table>+    </emu-table>++    <emu-note>The [[Weeks]] field is still under discussion in Temporal. For more, check out the <a href="https://github.com/tc39/proposal-temporal/issues/532">Github thread</a> on the Temporal issue tracker.</emu-note>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>

"which must be a Record" this should probably cross-reference the above table.

ryzokuken

comment created time in 16 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>

That doesn't make it the same list...

ryzokuken

comment created time in 17 hours

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma, Younies Mahmoud </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for Duration instances, and which is also used to key Records of templates to format individual Duration components: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+      <table class="real-table">+        <thead>+          <tr>+            <th>Internal Slot</th>+            <th>Property</th>+          </tr>+        </thead>+        <tr>+          <td>[[Years]]</td>+          <td>`"year"`</td>+        </tr>+        <tr>+          <td>[[Months]]</td>+          <td>`"months"`</td>+        </tr>+        <tr>+          <td>[[Weeks]]</td>+          <td>`"weeks"`</td>+        </tr>+        <tr>+          <td>[[Days]]</td>+          <td>`"days"`</td>+        </tr>+        <tr>+          <td>[[Hours]]</td>+          <td>`"hours"`</td>+        </tr>+        <tr>+          <td>[[Minutes]]</td>+          <td>`"minutes"`</td>+        </tr>+        <tr>+          <td>[[Seconds]]</td>+          <td>`"seconds"`</td>+        </tr>+        <tr>+          <td>[[Milliseconds]]</td>+          <td>`"milliseconds"`</td>+        </tr>+        <tr>+          <td>[[Microseconds]]</td>+          <td>`"microseconds"`</td>+        </tr>+        <tr>+          <td>[[Nanoseconds]]</td>+          <td>`"nanonseconds"`</td>+        </tr>+      </table>+    </emu-table>++    <emu-note>The [[Weeks]] field is still under discussion in Temporal. For more, check out the <a href="https://github.com/tc39/proposal-temporal/issues/532">Github thread</a> on the Temporal issue tracker.</emu-note>

Nit: <emu-note type=editor> (here and in your other notes that point to issues)

ryzokuken

comment created time in 17 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

Note, we couldn't simultaneously (1) Omit module attributes from the cache key (2) Expose them (e.g., as import.meta.attributes) (3) ignore the unknown attributes, because it would lead to the "race" that whoever imports the module first sets the attributes. Or, if you did an early check that it was always loaded with the same attributes across the whole module graph, then it could blow up if you combined two packages which work independently. (Such a blow-up/race choice would also be faced by tooling which combines out-of-band attributes for two packages which are used together.)

devsnek

comment created time in 16 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

Sorry, right, I believe I was convinced by you in a more oblique way. If we specified that none of the module attributes are part of the cache key, it'd rule out a very large fraction of the module attributes use cases that have been posited (e.g., capabilities for Wasm modules, reinterpreting things with different options, etc). That's why I felt like, the unknown attributes should be an error--to enable those in the future.

devsnek

comment created time in 17 hours

issue openedlegendecas/proposal-async-context

What does this API do?

The description of the problem space and priorities in the README is great. For the solution, I see a signature of the classes and some high-level explanation of their role, but it'd be great to also have an explanation of what each of the classes represents in a bit more detail, and what each of the methods do. Right now, it's hard for me to understand.

created time in 17 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

In the module attributes proposal, all JS engines are required to support type: "json", but this is still a potential risk for other attributes. Our past discussion: https://github.com/tc39/proposal-module-attributes/issues/21 : I've argued, we should throw on unknown attributes, to minimize the concerns @jkrems raises. Fellow OpenJSF TC39 delegate @gibson042 argued, we should ignore them, and that it's safe to do so. The current draft leaves this decision up to hosts. I'd be open to tightening the requirements one way or another, or making an informal recommendation to hosts. Ultimately, I think the same compatibility/evolution issues would apply to an out-of-band format as well, about how we treat unrecognized metadata (in terms of ignore vs cause an error).

devsnek

comment created time in 17 hours

issue commenttc39/proposal-record-tuple

Classes for Records

Tuple is a primitive, and when it's wrapped into an object (implicitly, e.g., through Object(#[])), that has a prototype which is Tuple.prototype. This process is like what Number does. What's complicated is the way that we'd map user-defined record classes to their prototype.

The readme notes these as "const classes", but maybe that's too obscure. PRs welcome to make that note more clear.

rumkin

comment created time in 17 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@devsnek Sorry for being unclear; I'm still pushing for === having Object.is semantics on Records and Tuples. I mean, I don't see why element-wise IEEE754-style equality comparison on Records and Tuples is more common/important than element-wise < or +.

bakkot

comment created time in 17 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

To respond to the concerns (if this goes on for much longer we should probably move to issues in the module attributes repo):

  • Per-module cache break from (resolver, specifier) pairs
    • Possible fix: enforce that all metadata matches within module
    • Possible fix: something like for import 'x' use type: 'json' at top of file

In general, there may be two types of module attributes: those which just "check" what the module is (and type is required to be that), and those who change the interpretation of the module (several were suggested in the repo. For a simple example: imagine if you had one that freezes the JSON module. Or: give certain capabilities to a WASI module). I think the latter type should be part of the cache key, and it should be fine to load the same (specifier, referrer) pair multiple times with different values here. If you reuse the same "change" settings multiple times, you'd get the same module.

  • Global cache break in real world implementations
    • Possible fix: validate that all attributes applied to live module record are exactly the same, early error otherwise

If you use "check" attributes wrong, then you'll get an error at module load time. Isn't this early enough? Which other kinds of mismatch/"cache break" cases are you worried about?

  • Modules cannot portably access metadata

Giving metadata to modules would only make sense if those pieces of metadata were part of the cache key. Otherwise, there would be a race to see who loads it first, and that would determine the metadata. An environment could do this with all unknown attributes, maybe. The only reasonable place to expose it is on import.meta, which is currently entirely environment-defined. I'm still not sure what the use case for accessing this metadata is, though; I think module attributes, just like the specifier, are for asking for things from the host.

If we had out-of-band module metadata, we'd face analogous issues: if each package had a file declaring what the metadata for its imports is, then we'd have to somehow merge these files all into one some time during startup/build. Then, we'd have to figure out how to deal with conflicts, just like if the unknown module attributes weren't part of the cache key.

Overall, I think it'd be a bit weird to non-compositionally throw due to mismatches from different import statements in the module graph, whether we use in-band or out-of-band metadata. Instead, each import does its own individual checking, and would individually fail if it doesn't pass the type check. This way, combining packages doesn't blow up randomly, just from differing metadata--you could run the tests in the packages individually and get the error isolated.

  • Standardized handling of parameters
    • Host-specific metadata is not portable

The idea of the proposal is to define as much host-independent stuff as we can (e.g., type: "json"), but also allow hosts to do more (e.g., on the Web, maybe HTML and CSS modules; maybe CJS/ESM assertions as described in https://github.com/openjs-foundation/standards/issues/91#issuecomment-634322044). I hope that, when there's environment-independent things in the future, we can define them in TC39. Isn't this all par for the course for JS, where some things are portable and others aren't? I think, with out-of-band metadata, we'd also want some non-portable, host-specific metadata.

  • Security invariants may be broken if a host ignores an attribute or interprets it incorrectly

Yeah, hosts have the ability to subvert security in all sorts of ways.... I don't really have a fix for that (documentation for host authors??), or understand how module attributes face this in a different way from anything else in JS.

devsnek

comment created time in 17 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

To clarify about mandatory vs optional:

  • For existing JS modules, types definitely aren't mandatory; that would break everything
  • For JSON modules, it's mandatory that environments support with type: "json"; environments can then decide whether or not they want to support implicit JSON modules (the Web won't, but Node.js could)
  • If with type: were used for other things, like ESM/CJS? I don't understand those issues well enough to understand the implications. Certainly I don't see how the module attributes proposal could/would make the user-side type declaration mandatory, if the Node Module team already has a solution worked out without this proposal.
devsnek

comment created time in 18 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@devsnek Leaving aside how we should define ===, if this were standard library functionality, I don't really understand why element-wise === is any more common/important of an operation than element-wise < or + (which certainly have their own use cases).

bakkot

comment created time in 18 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

In addition to hearing from other projects in the OpenJSF foundation, I wonder if we could hear more from Node.js collaborators. If this proposal is bad for Node.js, I think that'd be a serious enough issue, even if other parts of the OpenJSF don't have particular concerns. However, it's championed by a Node.js collaborator (@MylesBorins), while another Node.js collaborator (@devsnek) expressed serious concerns, so it's unclear how to read that. Can we reach out for broader feedback among Node.js collaborators to learn more?

devsnek

comment created time in 19 hours

issue commentopenjs-foundation/standards

Discuss foundation TC39 delegate expectations

I was really hoping that the OpenJSF representation at TC39 could be focused on gathering feedback from OpenJSF projects (and Node.js in particular) and bringing that to committee, ensuring that they're represented. One part is getting people in the room (which I'm glad we've accomplished), and another, equally important part is ensuring the constituency is represented.

It's been quite confusing for TC39 in the past to interpret what's going on when people talk with the voice of projects without having had some broader discussion with project participants. I've tried to gather broad feedback a little bit when I presented on TC39 topics at past Node Collaborator Summits, and was hoping that this would become more institutionalized with OpenJSF joining TC39.

This discussion comes at a really unfortunate time, where I have an obvious conflict of interest due to #91 . My intuition on what OpenJSF does sort of aligns with @MylesBorins FWIW. Nevertheless, consensus, blocking, and TC39 are all social processes; I think that, regardless of what we say in this thread, given their history in committee and past invited expert status, @ljharb and @devsnek will be able to say "I object" and it will be taken seriously. We don't have any written rules on whether invited experts can or can't object, so there you go.

ljharb

comment created time in 20 hours

issue commenttc39/proposal-record-tuple

Should Record wrappers have a null prototype?

@ljharb The two were never in contrast...

bmeck

comment created time in 21 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Ah, right, but I guess that's not the definition of Object.is but rather #[-0].

bakkot

comment created time in 21 hours

push eventtc39/proposal-module-attributes

Daniel Ehrenberg

commit sha 9811975a7533f4b3c03ae581f5a7096d46d5b04d

Fix caption

view details

push time in 21 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

There's only one plausible definition of Object.is for Records and Tuples--it recursively compares them for Object.is. That's not the topic of this issue.

bakkot

comment created time in 21 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I want to be unambiguous about this concept of "the same value": If two things are reliably distinguishable at all (e.g., through Object.is), I don't see them as the same "whole value". Maybe at some high level, but not in the sense I'm trying to get at. There are clearly multiple ways to define the semantics here; people in this thread have expressed that they'd find either way surprising, so we have to decide who we're OK with surprising.

bakkot

comment created time in a day

issue commenttc39/proposal-record-tuple

Should Record wrappers have a null prototype?

@Jack-Works To select option B, we'd have to be OK with ruling out Symbols as property keys for Records in the future (or being OK with them not having these same integrity properties). I'm currently leaning towards option A.

bmeck

comment created time in a day

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

right so... given different people have different intuitions, and that we have both === and Object.is in the language, why not enable both?

I hope we can settle on one general mental model for how this feature fits into the language; smooshing together multiple conflicting ones doesn't feel like it'll lead to good outcomes. So, I don't think different intuitions is a good reason to enable both things. Different use cases can be. That's why we've been discussing use cases, and how important/prevalent/necessary they are.

=== is a lot more terse and well-known than Object.is, so I think that we're likely choosing the semantics of the "default" comparison operator when we decide on === semantics, unless we work hard to educate JS programmers not to do === on Records and Tuples. I don't think it's a level/neutral comparison.

It also means you don't have to explain it like "they have the identity of their children except for certain double bit patterns".

I'm not sure what you mean; is this a comment about how the normalization of -0 to 0 would be bad? I guess that wouldn't affect the identity really, it'd be more a property of how construction of records and tuples affects certain double bit patterns. I guess I agree this would be a bit weird, but I don't think it'd complicate what identity is.

In all these alternatives, Records and Tuples would fully have the identity of their children in any case; the question is whether === should compare Records and Tuples by identity or recursively do === on the contents.

bakkot

comment created time in a day

issue commenttc39/proposal-record-tuple

Collect developer feedback about the ergonomics of `#{ }`/`#[ ]`

I'm fine to keep discussing this, but I still feel like the preponderance of the feedback so far has been towards #{}/#[], from being easier to type and just as clear. I'm saying this after my initial intuition was also to go with {| |}/[| |].

littledan

comment created time in a day

issue commenttc39/proposal-record-tuple

Collect developer feedback about the ergonomics of `#{ }`/`#[ ]`

As we're converging on #{}/#[], I removed the "undecided point" tag and added "solution proposed".

littledan

comment created time in a day

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Apologies for missing the previous example. I've updated my earlier post, and also mentioned that @waldemarhorwat had previously raised the possibility of complex numbers. I share @erights ' interest in further examples.

Now we know that it's possible to construct a case where -0/NaN semantics may be useful, I think the next step would be, how do we prioritize this vs other invariants/goals that have been posited.

I can think of other things that would be useful for these point/complex number cases--for example, it'd be great if < could compare their magnitude, right? It would also be great if I could make my own string-like rope type such that I could use === for comparison, and it'd compare the string contents, not the details of the structure, which would allow libraries to have further control over rope heuristics and performance (cc @sebmarkbage who requested this kind of thing).

But at some point we draw a line and say, "even though I can think of a use case, this can be accomplished other ways, and doesn't need to be part of the built-in semantics of JS". The existence of some use cases doesn't make the other committee members' goals go away; they remain in tension, and we have the opportunity of drawing a tradeoff one way or another. In particular, the idea to apply === and == recursively is in tension with the goal of not making them any harder to understand then they are right now; there's already a lot of cases.

Some possible solutions for the scenarios above:

  • As long as we don't normalize, you should be able to (very easily) write a comparison function in JS. This would be in parallel to how you have to write comparison functions for everything else in JS, and just get to use === if you're asking if your user-declared type is actually the same value, with the one-off exception of Numbers.
  • In a future value types proposal (if we figure out how to do one), we could make a declarative way to note that particular fields are compared IEEE754-wise. Points and complex numbers would fit into such a scheme.
  • (Operator overloading could implement < and == maybe, but this is a tangent)

Personally, I do still think this comes down to the category difference @erights raised above. That === on Numbers compares them in their domain through mathematical rules doesn't rule out === on Records comparing to see if they're the same Record (just like === on Objects compares them to see if they're the same Object).

Unlike APL and its descendants (which I think have a very cool programming model), we don't have much of a pattern in JavaScript of operators transparently applying recursively into data structures' contents; it's very unclear to me why this is the place we need to start.

bakkot

comment created time in a day

issue openedtc39/proposal-record-tuple

JSON.parseImmutable reviver interpretation

In the SES group review of Records and Tuples, someone (can't remember who, maybe @ajvincent?) suggested that, maybe, we want to change the interpretation of the second reviver parameter in JSON.parseImmutable. Or maybe we'll find we want to remove it. Someone should go through the JSON parse algorithm with a fine-toothed comb and figure out what, if any, changes need to be made. This should be part of the spec text going into Stage 2.

created time in a day

push eventtc39/proposal-record-tuple

Daniel Ehrenberg

commit sha cc6f60969e73b8be0a9c9bc4f8ae7dd7363e51e5

Update issue_template.md Remove old name of proposal

view details

push time in a day

issue commenttc39/proposal-record-tuple

Expand the FAQ. What's your question that you'd like to see answered?

@ZaidRehman That sounds more like a feature request than an FAQ entry. We could add that to the standard library, or people could implement it themselves in JS. I think many of the use cases with APIs and Records and Tuples are met by JSON.parseImmutable (which parses JSON into Records and Tuples) and JSON.stringify (which Just Works (TM) on Records and Tuples). In particular, I wouldn't want to encourage people to do JSON.parse and then invoke the conversion function--that's likely to be slower. If you could say more about use cases, that could help us figure out whether it's well-motivated to put in the standard library.

littledan

comment created time in a day

issue commenttc39/proposal-module-attributes

Use object-literal-like notation for attributes?

@gibson042 I guess I'm still not convinced that we shouldn't solve that within the key/value-only syntax. Nevertheless, I'm not extremely against brackets, it's more of a minor preference.

Do you think we need to resolve this brackets-or-no-brackets question before Stage 2, or can we continue discussing it between Stage 2 and 3?

justinfagnani

comment created time in a day

issue commenttc39/proposal-operator-overloading

Operator overloading class syntax using TS-like method overloading and "extension" classes

I like the idea of making more ergonomic syntax for classes with operator overloading. Do you have an idea of the algorithm you'd use for determining which overload to select? Do you like the one described in this proposal, or do you prefer another one?

sirisian

comment created time in a day

issue commenttc39/proposal-record-tuple

Concerns of value types using prototypes.

@ljharb @bmeck @rricard @rickbutton @devsnek and I had a call where we discussed this issue. To summarize some key points:

  • @bmeck and I share the goal that, when doing string-keyed property access on Records, this operation should have integrity--it should only give the entries contained in the Record. Such integrity is analogous to how, for Records and Strings, integer-indexed property access similarly "has integrity" and doesn't forward up the prototype chain.
  • I argued that, as far as protocols which may be on Object.prototype, we will always need to provide a path for Objects with a null prototype, and Records could take this path. Further, as Records generally "have integrity", this is the path that we should follow. (I'm not sure whether @ljharb found this persuasive.)
  • @ljharb pointed out two more issues with a null prototype which I didn't understand previously from this thread:
    • If we don't have any sort of valueOf or Symbol.toPrimitive method, then there's no operation which brand-checks Records. We agreed that Record.isRecord would fit the bill--I'd be up for adding that (and generally, Type.isType checks, but we can go incrementally as we did with Array.isArray).
    • If we don't end up finding valueOf or Symbol.toPrimitive methods on Records, then we'd need extra logic in ToPrimitive if we wanted it to convert Record wrappers to Records.

After the call, I looked at the callers of ToPrimitive, and I think they all should throw when applied to Records and Tuples. Maybe we could think of ToPrimitive as "convert to atomic primitives" which doesn't include Records and Tuples--that seems to be what the current callers are after.

We discussed two possible paths A: Record wrappers have a null prototype with the Record.isRecord check (and possibly extra ToPrimitive logic, but now that seems unnecessary to me) B: Be exotic in that Records forward up symbol accesses to their prototype chain, while not forwarding up string property accesses. - Then, we could support a Symbol.toPrimitive method which converts Records wrappers to Records, lessening the urgency of Record.isRecord and removing the need from considering any extra ToPrimitive logic. We could also support monkey-patchable protocols in the future. - @rickbutton notes that this would permanently prevent us from permitting Symbol keys in Records

@ljharb concluded that, if we take the integrity goals at high priority, that he'd prefer A to B, as B seemed a bit too exotic.

I have trouble understanding the concern about wrappers being exotic objects, since lots of things (e.g., String and Tuple wrappers, and TypedArrays) behave exotically with integer indices, and Record wrappers will likely be specified as exotic objects anyway, but I'm fine with settling on A.

I'd like to tentatively conclude that, for now, we'd have a null prototype and follow option A, but be open to considering B until Stage 3, when we should draw a final conclusion. I think this exploration of the design space, where we've found multiple plausible options including one good enough for experimentation in the playground, is sufficient for demonstrating viability for Stage 2.

bmeck

comment created time in a day

issue commentrickbutton/proposal-deep-path-properties-for-record

Should deep path properties work in Objects too?

@ljharb Do you have any cross-references to those requests, so we can understand their needs better? This could help us get the semantics right for those cases.

littledan

comment created time in 2 days

Pull request review commenttc39/ecma262

Editorial: Make numeric values and operations default to mathematical values

 <h1>Static Semantics</h1>     </emu-clause>     <emu-clause id="sec-mathematical-operations">       <h1>Mathematical Operations</h1>-      <p>This specification makes reference to trhee kinds of numeric values:</p>+      <p>This specification makes reference to three kinds of numeric values:</p>

I don't think we need to refrain from referring to numbers in the normal sense in spec text in general. That would seem a bit overboard.

caiolima

comment created time in 2 days

push eventtc39/proposal-module-attributes

Daniel Ehrenberg

commit sha 20591398445b037a5998aea36de1fa6a86143deb

Two small typo fixes

view details

push time in 2 days

issue commenttc39/proposal-module-attributes

Module Import Headers

The standardized hook for implementers to provide their header is called HostResolveImportedModule . It's where the fetching happens, and the module attributes are passed to it.

Randy-Buchholz

comment created time in 2 days

issue commenttc39/proposal-module-attributes

Module Import Headers

This is a good topic to discuss, and we're discussing it in some other issues here, such as #24, e.g., https://github.com/tc39/proposal-module-attributes/issues/24#issuecomment-627096878. Ultimately, ECMA-262 isn't going to say which headers are sent to the server--this is up to host environments, like HTML. I'm proposing that we come to a good conclusion on how some of those environments would work before Stage 3, but ultimately, that we will leave it up to them to make these calls. What do you think?

Randy-Buchholz

comment created time in 2 days

issue commenttc39/proposal-record-tuple

Classes for Records

I think this is an interesting area for investigation. I share your observation that we need to do something special for instantiation, to make sure that the fields are set up right the first time.

Given that record classes add a large amount of complexity (e.g., how is the greet method associated with the User Record?), I'd like to categorize this as something for a follow-on proposal. How would you feel about that, @rumkin ?

rumkin

comment created time in 2 days

issue commenttc39/proposal-module-attributes

Privilege of a type

It's a core goal of module attributes to provide a mechanism to prevent this sort of privilege escalation, so I think it's great to talk these things through ahead of time. I'd say, we should create some sort of norm that the interpretation of a type value does not change in that way: if it starts out not being able to execute scripts, you should have to use a new type value to allow it to execute scripts.

I'm not sure whether this should be a normative requirement in ECMA-262, or more like something we'd put in W3C TAG design principles; maybe the latter would make more sense, as this is somewhat of a vague property.

annevk

comment created time in 2 days

issue openedrickbutton/proposal-deep-path-properties-for-record

Deep path properties in Tuples

This proposal doesn't work for Tuples as the outermost structure, just Records, since Tuples don't have a way to index a particular element in a literal. Instead, they have a with method to change an index. This works fine for shallow updates, but it would be nice to have something for deep updates. I was wondering if it would make sense to do this with :-based syntax, as follows:

const tup1 = #[1, 2, 3, 4, 5]
const tup2 = #[...tup, [1]: 100]  // #[1, 11, 3, 4, 5]

const tup3 = #[#{a: 1, b: 2}]
const tuple4 = #[...tup4, [0].a: 3]   // #[#{a: 3, b: 2}]

As another example, [1, 2, 3, [5]: 6] would be equivalent to [1, 2, 3,,,,6]. (I guess we'd add a runtime error for Tuples if people used this syntax to create a hole.)

What do people think?

This is an orthogonal proposal from the rest of records and tuples and deep path properties, as it applies to Arrays as well, with shallow paths. However, I don't know if this is something we want to encourage on Arrays, since holes are Bad(TM).

created time in 2 days

issue openedrickbutton/proposal-deep-path-properties-for-record

Should deep path properties work in Objects too?

When we discussed this proposal with @erights, he suggested that it should be permitted in objects too. I'd prefer to omit objects, as described in #3 , but especially because deep paths implicitly "clone" an object through the equivalent of {...obj} freely, as if it's the identity. While this is the identity for Records and Tuples, that's not the case for Objects, which lose many things about them. I think it would be weird if deep paths implicitly made many of those go away. In the discussion, we couldn't think of a good syntax which would express the way that, on objects, you'd be spreading away n levels of detail from the object.

created time in 2 days

issue commenttc39/proposal-record-tuple

Interaction with CompositeKey?

I'm having trouble seeing what could be addressed in this proposal. Records and Tuples satisfy some of the uses of CompositeKey, but CompositeKey could point to objects, so you'd need some additional thing (such as Symbols as WeakMap keys) to build something analogous. So, this might be considered to subsume that, but I don't see what we'd change in either proposal.

ajvincent

comment created time in 2 days

push eventWebAssembly/spec

Travis CI

commit sha 7907eddb96eba4a426374778419bef19e2f4773e

Deploy to GitHub Pages: a7a1856cc8e0e9cb6378acb083bb9c43494d05b1

view details

push time in 2 days

push eventWebAssembly/spec

Travis CI

commit sha 2402513f7f8d7ee1bd3d9ad9d738c7a6968e7171

Deploy to GitHub Pages: 951e2617026d4c4d75adc240a542e862cdc74e45

view details

push time in 2 days

issue commenttc39/proposal-record-tuple

toString() should return the same for #{b, a} as #{a, b}

Yes, there will be no way to observe the differences. I'd expect toString() to print out the keys sorted in the same sort order we use for Reflect.ownKeys. I think this will become more clear when we have the draft spec text written, and just fall out of the semantics.

ajvincent

comment created time in 2 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Aside from consistency (which is, in general, a totally valid argument), does anyone have an application/use case where it would be useful to get this sort of nested treatment of NaN/-0 in ==/===?

Separately, if you expect this recursive treatment for === in NaN/-0, do you expect == on Records and Tuples to do things like compare BigInts and Numbers as equal when they have the same mathematical value?

Personally, I think all of these expectations around recursiveness face the category error @erights pointed out: because we don't have a syntactically convenient "are these exactly the same thing" vs "are these IEEE754/mathematically the same" operator difference, people are going to use === when, for Records and Tuples, the real goal is to find whether they are exactly the same thing.

I claim that "are these the same thing" is actually what people are trying to ask when they compare Records and Tuples with ===. I'd say, we should go with the answer to the question they're intending to ask, and let programmers manually recurse and apply the right IEEE754/mathematical comparison operator if that's what they really want.

If someone had a use case for the recursive "are these IEEE754/mathematically the same" semantics, that might convince me otherwise on this question. My current intuition is, mathematical comparisons in these contexts is just a footgun, not the intended semantics at usage sites.

I'm not sure how you'd all weigh this objective, but one goal of this proposal is to permit implementations to optimize ===, taking advantage of how the structures will never change. But if === is an operation on an equivalence class of objects, such an optimization through techniques like "hash consing" (reusing the same structure if the contents are the same, so === is cheap if they are the same) become impractical/impossible. (Aside: Not all engines will do this optimization, though, and it's likely that it sometimes won't kick in even on engines that do perform it. Ultimately, the situation would be similar to strings, where only some engines optimize with rope data structures internally, and they differ in their heuristics.)

(I'd be OK, I guess, with normalizing -0 to 0--it seems like the least harmful option in this thread--but I still don't really understand the motivation, and it seems a little unfortunate to sort of randomly lose the ability to represent -0 within a Record/Tuple. So I agree with @bakkot 's comments at the start of this thread)

bakkot

comment created time in 2 days

push eventWebAssembly/spec

Travis CI

commit sha cbbb20a47ad723ad5b83fa3413fc4757b506b240

Deploy to GitHub Pages: 47a20d6ac5c68c56f6d67690796e9381d5e8bd5a

view details

push time in 2 days

issue commentrickbutton/proposal-deep-path-properties-for-record

Should optional chaining be allowed in deep path properties?

I dunno, I don't see any problems this causes, but it feels intuitively like we should support this iff we support optional chaining assignment, which we decided to omit.

chicoxyzzy

comment created time in 4 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Cc @erights

bakkot

comment created time in 4 days

issue commenttc39/proposal-temporal

Rename Temporal.Absolute to Temporal.Timestamp?

Thanks for these thoughts. I can see how the juxtaposition of "Time" and "Timestamp" is rather confusing. I guess my current preference is to stick with the name Temporal.Absolute.

littledan

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>

There also has to be a field for the dotted formats, of a schema similar to Intl.DateTimeFormat.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma

Make sure to list Younies here as well :) This is based on his earlier work.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>

This needs to be keyed by PluralRules form as well.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>

Let's require that this match Intl.NumberFormat's list.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).

Shouldn't we forward the style along to the ListFormat? (Or, is the style related in some other way than 1:1?)

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).

It would be good to link from here to an open issue about whether DurationFormat should do balancing.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.

I don't think we should return a Record from this algorithm; instead, we want to return a list of parts records, which the caller can either concatenate the text of, or convert into objects.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.resolvedOptions">+      <h1>Intl.DurationFormat.prototype.resolvedOptions ()</h1>++      <p>This function provides access to the locale and options computed during initialization of the object.</p>++      <emu-alg>+        1. Let _df_ be the *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).+        1. For each row of <emu-xref href="#table-durationformat-resolvedoptions-properties"></emu-xref>, except the header row, in table order, do+          1. Let _p_ be the Property value of the current row.+          1. Let _v_ be the value of _df_'s internal slot whose name is the Internal Slot value of the current row.+          1. Assert: _v_ is not *undefined*.+          1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_).+        1. Return _options_.+      </emu-alg>++      <emu-table id="table-durationformat-resolvedoptions-properties">+        <emu-caption>Resolved Options of DurationFormat Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Locale]]</td>+            <td>`"locale"`</td>+          </tr>+          <tr>+            <td>[[NumberingSystem]]</td>+            <td>`"numberingSystem"`</td>+          </tr>+          <tr>+            <td>[[Style]]</td>+            <td>`"style"`</td>+          </tr>+          <tr>+            <td>[[Fields]]</td>+            <td>`"fields"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-instances">+    <h1>Properties of Intl.DurationFormat Instances</h1>++    <p>Intl.DurationFormat instances inherit properties from %DurationFormatPrototype%.</p>++    <p>Intl.DurationFormat instances have an [[InitializedDurationFormat]] internal slot.</p>++    <p>Intl.DurationFormat instances also have several internal slots that are computed by the constructor:</p>++    <ul>+      <li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li>+      <li>[[NumberingSystem]] is a String value with the `"type"` given in Unicode Technical Standard 35 for the numbering system used for formatting.</li>+      <li>[[Style]] is one of the String values `"long"`, `"short"`, `"narrow"`, or `"dotted"` identifying the duration formatting style used.</li>

For the "dotted" case, we should have a single template which covers all the fields, similar to Intl.DateTimeFormat.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.resolvedOptions">+      <h1>Intl.DurationFormat.prototype.resolvedOptions ()</h1>++      <p>This function provides access to the locale and options computed during initialization of the object.</p>++      <emu-alg>+        1. Let _df_ be the *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _options_ be ! ObjectCreate(%ObjectPrototype%).+        1. For each row of <emu-xref href="#table-durationformat-resolvedoptions-properties"></emu-xref>, except the header row, in table order, do+          1. Let _p_ be the Property value of the current row.+          1. Let _v_ be the value of _df_'s internal slot whose name is the Internal Slot value of the current row.+          1. Assert: _v_ is not *undefined*.+          1. Perform ! CreateDataPropertyOrThrow(_options_, _p_, _v_).+        1. Return _options_.+      </emu-alg>++      <emu-table id="table-durationformat-resolvedoptions-properties">+        <emu-caption>Resolved Options of DurationFormat Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Locale]]</td>+            <td>`"locale"`</td>+          </tr>+          <tr>+            <td>[[NumberingSystem]]</td>+            <td>`"numberingSystem"`</td>+          </tr>+          <tr>+            <td>[[Style]]</td>+            <td>`"style"`</td>+          </tr>+          <tr>+            <td>[[Fields]]</td>+            <td>`"fields"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-instances">+    <h1>Properties of Intl.DurationFormat Instances</h1>++    <p>Intl.DurationFormat instances inherit properties from %DurationFormatPrototype%.</p>++    <p>Intl.DurationFormat instances have an [[InitializedDurationFormat]] internal slot.</p>++    <p>Intl.DurationFormat instances also have several internal slots that are computed by the constructor:</p>++    <ul>+      <li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li>+      <li>[[NumberingSystem]] is a String value with the `"type"` given in Unicode Technical Standard 35 for the numbering system used for formatting.</li>+      <li>[[Style]] is one of the String values `"long"`, `"short"`, `"narrow"`, or `"dotted"` identifying the duration formatting style used.</li>+      <li>[[Fields]] is a List value specifying which duration fields are required to be printed.</li>+      <li>[[Templates]] is a Record value containing template strings for each of the supported units for duration formatting.</li>

I don't think the entries here can simply contain template strings directly. Instead, they may have different templates for each PluralRules form (this is how CLDR does it).

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).+        1. Else+          1. Throw a *TypeError* exception.+        1. Set _durationFormat_.[[NumberFormat]] to ! Construct(%NumberFormat%, &laquo; _locale_ &raquo;).+        1. Set _durationFormat_.[[ListFormat]] to ! Construct(%ListFormat%, &laquo; _locale_ &raquo;).+        1. Return _durationFormat_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-constructor">+    <h1>Properties of the Intl.DurationFormat Constructor</h1>++    <p>The Intl.DurationFormat constructor has the following properties:</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype">+      <h1>Intl.DurationFormat.prototype</h1>++      <p>The value of `Intl.DurationFormat.prototype` is %DurationFormatPrototype%.</p>++      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.supportedLocalesOf">+      <h1>Intl.DurationFormat.supportedLocalesOf ( _locales_ [ , _options_ ] )</h1>++      <p>When the `supportedLocalesOf` method is called with arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. Let _availableLocales_ be %DurationFormat%.[[AvailableLocales]].+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. Return ? SupportedLocales(_availableLocales_, _requestedLocales_, _options_).+      </emu-alg>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat-internal-slots">+      <h1>Internal slots</h1>++      <p>The value of the [[AvailableLocales]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++      <p>The value of the [[RelevantExtensionKeys]] internal slot is &laquo; `"nu"` &raquo;.</p>++      <p>The value of the [[LocaleData]] internal slot is implementation defined within the constraints described in <emu-xref href="#sec-internal-slots"></emu-xref> and the following additional constraints for all locale values _locale_:</p>++      <ul>+        <li>[[LocaleData]].[[<_locale_>]].[[nu]] must be a List that does not include the values `"native"`, `"traditio"`, or `"finance"`.</li>+        <li>[[LocaleData]].[[<_locale_>]] must have a [[formats]] field. The value of this field must be a record, which must have fields with the names of the three formatting styles: `long`, `short`, and `narrow`. Each of those fields must be records themselves, and each must have fields with the names of the supported units: `nanonseconds`, `microseconds`, `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years`. Each of those values must be a template string.</li>+      </ul>++      <emu-note>+        It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at <a href="http://cldr.unicode.org/">http://cldr.unicode.org/</a>).+</emu-note>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-properties-of-intl-durationformat-prototype-object">+    <h1>Properties of the Intl.DurationFormat Prototype Object</h1>++    <p>The Intl.DurationFormat prototype object is itself an ordinary object. <dfn>%DurationFormatPrototype%</dfn> is not an Intl.DurationFormat instance and does not have an [[InitializedDurationFormat]] internal slot or any of the other internal slots of Intl.DurationFormat instance objects.</p>++    <emu-clause id="sec-Intl.DurationFormat.prototype.constructor">+      <h1>Intl.DurationFormat.prototype.constructor</h1>++      <p>The initial value of `Intl.DurationFormat.prototype.constructor` is the intrinsic object %DurationFormat%.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype-@@tostringtag">+      <h1>Intl.DurationFormat.prototype [ @@toStringTag ]</h1>++      <p>The initial value of the @@toStringTag property is the string value `"Intl.DurationFormat"`.</p>+      <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>+    </emu-clause>++    <emu-clause id="sec-Intl.DurationFormat.prototype.format">+      <h1>Intl.DurationFormat.prototype.format ( _duration_ )</h1>++      <p>When the `format` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append _val_ as the last element of _list_.+        1. Let _result_ be ? FormatList(_df_.[[ListFormat]], list).+        1. Return _result_.+      </emu-alg>+    </emu-clause>+    <emu-clause id="sec-Intl.DurationFormat.prototype.formatToParts">+      <h1>Intl.DurationFormat.prototype.formatToParts ( _duration_ )</h1>++      <p>When the `formatToParts` method is called with an argument _duration_, the following steps are taken:</p>++      <emu-alg>+        1. Let _df_ be *this* value.+        1. Perform ? RequireInternalSlot(_df_, [[InitializedDurationFormat]]).+        1. Let _record_ be ? ToPartialDuration(_duration_).+        1. Let _formatted_ be ? PartitionDurationFormatPattern(_df_, _duration_).+        1. Let _list_ be an empty List.+        1. For each row of <emu-xref href="#table-duration-components"></emu-xref> except the header row in table order, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _formatted_.[[&lt;_field_&gt;]].+          1. If _val_ is not *undefined*, then+            1. Append a new Record { [[Type]]: _field_, [[Value]]: _val_ } as the last element of _list_.+        1. Return _result_.

This is the first time you mention result. I guess you're missing a call to the ListFormat logic... Actually, I think we should be calling CreatePartsFromList (or actually something based on it that would be refactored to forward through the parts list) as part of PartitionDurationFormatPattern and keep these callers simple.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>

Given that whether "weeks" is a component of Duration is an open question, we should point to an issue an highlight this in the spec.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).

Isn't it an open issue whether we do this explicit "fields" approach or the higher-level smallestField/largestField + maybe have a parameter to switch intermediate zeroes? Maybe we could point to the issue for discussion here.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>+            1. Set _result_.[[&lt;_field_&gt;]] to _applied_.+        1. Return _result_.+      </emu-alg>+    </emu-clause>+  </emu-clause>++  <emu-clause id="sec-intl-durationformat-constructor">+    <h1>The Intl.DurationFormat Constructor</h1>++    <p>The DurationFormat constructor is the <dfn>%DurationFormat%</dfn> intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in <emu-xref href="#sec-internal-slots"></emu-xref>.</p>++    <emu-clause id="sec-Intl.DurationFormat">+      <h1>Intl.DurationFormat ( [ _locales_ [, _options_ ] ] )</h1>++      <p>When the `Intl.DurationFormat` function is called with optional arguments _locales_ and _options_, the following steps are taken:</p>++      <emu-alg>+        1. If NewTarget is *undefined*, throw a *TypeError* exception.+        1. Let _durationFormat_ be ? OrdinaryCreateFromConstructor(NewTarget, `"%DurationFormatPrototype%"`, &laquo; [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[Fields]], [[Templates]] &raquo;).+        1. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).+        1. If _options_ is *undefined*, then+          1. Let _options_ be ObjectCreate(*null*).+        1. Else+          1. Let _options_ be ? ToObject(_options_).+        1. Let _opt_ be a new Record.+        1. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, &laquo; `"lookup"`, `"best fit"` &raquo;, `"best fit"`).+        1. Set _opt_.[[localeMatcher]] to _matcher_.+        1. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, `undefined`, `undefined`).+          1. If _numberingSystem_ does not match the Unicode Locale Identifier `type` nonterminal, throw a `RangeError` exception.+        1. Set _opt_.[[nu]] to _numberingSystem_.+        1. Let _localeData_ be %DurationFormat%.[[LocaleData]].+        1. Let _r_ be ResolveLocale(%DurationFormat%.[[AvailableLocales]], _requestedLocales_, _opt_, %DurationFormat%.[[RelevantExtensionKeys]], _localeData_).+        1. Let _locale_ be r.[[locale]].+        1. Set _durationFormat_.[[Locale]] to _locale_.+        1. Set _durationFormat_.[[NumberingSystem]] to _r_.[[nu]].+        1. Let _style_ be ? GetOption(_options_, `"style"`, `"string"`, &laquo; `"long"`, `"short"`, `"narrow"`, `"dotted"` &raquo;, `"long"`).+        1. Set _durationFormat_.[[Style]] to _style_.+        1. If _style_ is `"dotted"`, then+          1. Set _durationFormat_.[[Templates]] to a new empty Record.+        1. Else+          1. Let _dataLocale_ be _r_.[[dateLocale]].+          1. Let _dataLocaleData_ be _localeData_.[[&lt;_dataLocaleData_&gt;]].+          1. Let _templates_ be _dataLocaleData_.[[formats]].[[&lt;_style_&gt;]].+          1. Set _durationFormat_.[[Templates]] to _templates_.+        1. Let _fields_ be ? Get(_options_, `"fields"`).+        1. If _fields_ is *undefined*, then+          1. Let _list_ be a new empty List.+          1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+            1. Let _field_ be the Property value.+            1. Append _field_ as the last element of _list_.+          1. Set _durationFormat_.[[Fields]] to _list_.+        1. Else if IsArray(_fields_) is *true*, then+          1. Set _durationFormat_.[[Fields]] to ? CreateListFromArrayLike(_fields_).

I guess the logic in PartitionDurationFormatPattern will end up ignoring unknown fields, but do you think that's the behavior we want? Another alternative would be to throw an exception in the constructor.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>+        1. Let _result_ be a new empty Record.+        1. For each row in <emu-xref href="#table-duration-components"></emu-xref> except the header row, do+          1. Let _field_ be the Property value.+          1. Let _val_ be _duration_.[[&lt;_field_&gt;]]+          1. If _val_ is *undefined* or _field_ does not exist in _durationFormat_.[[Fields]], then+            1. Set _result_.[[&lt;_field_&gt;]] to `undefined`.+          1. Else,+            1. Let _num_ be ! PartitionNumberPattern(_durationFormat_.[[NumberFormat]], val).+            1. Let _template_ be _durationFormat_.[[Templates]].[[&lt;_field_&gt;]].+            1. <mark>TODO: figure out an efficient way to apply _template_ onto _num_.</mark>

Meta: we don't think about "efficiency" in specs; we're just developing a correct description.

I guess this is a pretty simple pattern, with a single "{0}" in it, that gets replaced by the output of PartitionNumberPattern. Overall, I think this text should look a lot like RelativeTimeFormat's logic, including the selection through PluralRules of the right template.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>++    <emu-table id="table-duration-components">+      <emu-caption>Components of Duration Instances</emu-caption>+        <table class="real-table">+          <thead>+            <tr>+              <th>Internal Slot</th>+              <th>Property</th>+            </tr>+          </thead>+          <tr>+            <td>[[Years]]</td>+            <td>`"year"`</td>+          </tr>+          <tr>+            <td>[[Months]]</td>+            <td>`"months"`</td>+          </tr>+          <tr>+            <td>[[Weeks]]</td>+            <td>`"weeks"`</td>+          </tr>+          <tr>+            <td>[[Days]]</td>+            <td>`"days"`</td>+          </tr>+          <tr>+            <td>[[Hours]]</td>+            <td>`"hours"`</td>+          </tr>+          <tr>+            <td>[[Minutes]]</td>+            <td>`"minutes"`</td>+          </tr>+          <tr>+            <td>[[Seconds]]</td>+            <td>`"seconds"`</td>+          </tr>+          <tr>+            <td>[[Milliseconds]]</td>+            <td>`"milliseconds"`</td>+          </tr>+          <tr>+            <td>[[Microseconds]]</td>+            <td>`"microseconds"`</td>+          </tr>+          <tr>+            <td>[[Nanoseconds]]</td>+            <td>`"nanonseconds"`</td>+          </tr>+        </table>+      </emu-table>+    </emu-table>++    <emu-clause id="sec-partitiondurationformatpattern" aoid="PartitionDurationFormatPattern">+      <h1>PartitionDurationFormatPattern ( _durationFormat_, _duration_ )</h1>++      <p>The PartitionDurationFormatPattern abstract operation is called with the arguments _durationFormat_ (which must be an object initialized as a DurationFormat) and _duration_ (which must be a Record), and creates the corresponding parts according to the effective locale and the formatting options of _durationFormat_. The following steps are taken:</p>++      <emu-alg>+        1. If _durationFormat_.[[Style]] is `"dotted"`, then+          1. <mark>TODO: decide what to do for this style.</mark>

I guess for these, we're looking for a single pattern which brings everything together (and this corresponds to durationUnit in CLDR). Let's find this pattern in a way that's analogous to Intl.DateTimeFormat.

ryzokuken

comment created time in 4 days

Pull request review commenttc39/proposal-intl-duration-format

Add spec text

 <!doctype html> <meta charset="utf8">-<link rel="stylesheet" href="./spec.css">-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">-<script src="./spec.js"></script> <pre class="metadata">-title: Proposal Title Goes Here-stage: -1-contributors: Your Name Goes Here+title: Intl.DurationFormat+stage: 1+contributors: Ujjwal Sharma </pre>+<emu-biblio href="./biblio.json"></emu-biblio>+<emu-clause id="durationformat-objects">+  <h1>DurationFormat Objects</h1> -<emu-clause id="sec-demo-clause">-  <h1>This is an emu-clause</h1>-  <p>This is an algorithm:</p>-  <emu-alg>-    1. Let _proposal_ be *undefined*.-    1. If IsAccepted(_proposal_),-      1. Let _stage_ be *0*.-    1. Else,-      1. Let _stage_ be *-1*.-    1. Return ? ToString(_proposal_).-  </emu-alg>+  <emu-clause id="sec-intl-durationformat-abstracts">+    <h1>Abstract Operations for DurationFormat Objects</h1>++    <p>Several DurationFormat algorithms use values from the following table, which provides internal slots and property names for the components of date and time formats: </p>

I'm not sure if this paragraph says what you want it to say. Maybe you meant something like, "which provides internal slots and property names for Duration instances, and which is also used to key Records of templates to format individual Duration components".

ryzokuken

comment created time in 4 days

issue commenttc39/ecma262

Symbols can't be used as WeakMap keys

Overall, I think Symbols as WeakMap keys would be a very useful base for being able reference objects from primitives (in the context of the Records and Tuples proposal), by indirecting through the WeakMap.

The implication chain goes like this:

  • A core benefit of Records and Tuples is that === does deep comparison
  • === is a reliable operation, so it's not something that Proxy or Symbols or operator overloading could trap
  • Records and Tuples need to be primitives, so that they can have === semantics which are not based on object identity
  • These primitives cannot be membrane-wrapped, so there's no way they could directly contain Objects, since then these objects would pierce through the membrane. Access to objects from Records and Tuples would need to be provided by some other object, access to which could be membrane-wrapped.
  • The references to Objects which are immediately referenced in Records and Tuples need to be through a primitive type, such as Symbol (or a new "box" type)
  • There would need to be some kind of mapping from some kind of primitive which has an identity (such as Symbol or "box") to objects, in order to support Records and Tuples logically referencing objects (without manually maintaining a parallel data structure)

Symbols as WeakMap keys seems simpler than adding a "box" type, even though we don't need to use these things as property keys.

Such a system would preserve our typical invariants protecting membranes/ocap systems, since object operations are used to access the WeakMap. While it would be ergonomically nice and composition-promoting to have a single built-in mapping from Symbols (or some other primitive) to objects, this wouldn't meet ocap goals, since it would constitute built-in shared state, providing a cross-compartment communication channel for multiple compartments sharing the same frozen Realm containing all of TC39's unmodified primordials.

The open questions I see are:

  • Can registered symbols be used as WeakMap keys? @ljharb has expressed that they should be (if we support this at all), and @erights has expressed that they shouldn't be. Personally, I think either option would be an acceptable choice:
    • Allowing registered symbols doesn't seem so bad, since registered Symbols are similar to Objects that are held alive for the lifetime of the Realm. Things like Symbol.iterator are similar to primordials like Object.prototype and Array.prototype, and registered Symbol.for() symbols are similar to properties of the global object. Just because these will stay alive doesn't mean we disallow them as WeakMap keys.
    • Prohibiting registered symbols doesn't seem so bad, since it's already readily observable whether a Symbol is registered, and it's not very useful to include these as WeakMap keys. Therefore, it's hard to see what practical or consistency problems the prohibition would create.

I hope we can work out a solution here among the available options.

  • We could support Symbols in WeakRefs and FinalizationRegistry, or not. I don't have any use case in mind, but it would seem consistent with adding them as WeakMap keys. I imagine we should support Symbols as WeakSet entries as well (I don't think this should be controversial if we agree on Symbols as WeakMap keys).

I plan to propose "Symbols as WeakMap keys" for Stage 1 at the June 2020 TC39 meeting. By going through the stage process, I hope we can develop consensus on answers to these questions little by little.

devsnek

comment created time in 4 days

issue commentFrankYFTang/proposal-intl-enumeration

More things that we might enumerate over

Or, on second thought: Maybe things like language/region enumeration should be part of Intl.DisplayNames, and the iteration functions on Intl is more about options supported across APIs.

littledan

comment created time in 4 days

issue commentFrankYFTang/proposal-intl-enumeration

More things that we might enumerate over

supportedLocalesOf takes a larger set of locales that you are asking for a subset of. I guess what I'm suggesting that we make an API which gives the supported locales of the universal set.

Yes, this is definitely inexact. I'd suggest that this API be broad in general, erring on the side of including more things (e.g., having the display name), and then we can let programmers use more fine-grained APIs if they want to test support for a particular API (e.g., supportedLocalesOf or resolvedOptions).

(Hmm, maybe this means we would actually want Temporal.TimeZone to have way to check support for timezones/iterate through all the actually supported ones...)

littledan

comment created time in 4 days

issue commenttc39/proposal-temporal

What about the default calendar?

I agree with all the points that @ptomato mentioned above, and his weighing of them. I want to mention a few more disadvantages of option 4, which I've mentioned in some calls but don't think I properly wrote down anywhere:

  • Determining the default calendar: My understanding is that many regions of the world have a default calendar which is really more of an individual preference. CLDR sometimes lists, for these regions, that the default calendar is ISO, and other times another calendar, but the ground truth is more subtle. If the default calendar is chosen based on the region, we may not meet user expectations; application-level logic would lead to better results. (I don't really know how close we'll get to users' real calendar preferences if we pass up the "right" default calendar through navigator.locales; maybe that would be enough?) Application-level calendar determination would be best implemented on top of a simpler, more predictable base.
  • Testing: Since most of the world uses an ISO calendar default, most testing would be executed in environments with an ISO calendar. This leads to the risk of code being shipped which works in most of the world and is broken when the "wrong" default calendar is selected by the environment.
  • Separation of concerns: Without the inheritance of the default calendar from the environment, Temporal would operate consistently the same across different contexts/environments, modulo ECMA-402's implementation-defined-ness of calendars. I'd prefer to expose the user agent's default calendar through a separate navigator.locales API or similar, and ask developers to thread it through if it makes sense. Often, there will be application-level preferences which would override it. Also, not all environments have a meaningful user-agent-level default (e.g., servers). (Yes, Intl has a pervasive concept of a default locale; my claim is, that was an unfortunate design and we shouldn't extend it more broadly.)

Across options 2, 3, 5 and 6, there is a common API design principle that, if we ask developers to explicitly invoke the "iso" calendar in one way or another, then that will lead to a decision point from them. I share @ptomato 's skepticism about what this would mean in practice--I think the meaning of this would remain confusing to many programmers, and wouldn't constitute a choice point in practice. However, this is just a hypothesis, which we might investigate by talking to more programmers, distributing sample implementations/documentation for API alternatives, etc.

Among options 2, 3, 5 and 6, I prefer 6--I think it has the lowest syntactic overhead in practice, and it still meets the goal of "providing an explicit choice point", if that's taken to be a goal. The alternate naming that @ptomato proposes in option 6 seems interesting to me--this alternative option 6 would still create a situation where, in the documentation listing, tab completion for methods, etc, you see an option where there's an explicit calendar parameter, so this may still lead developers to invoke the right calendar-specific APIs. Option 6 seems to me like, at worst, a very minor source of slight ugliness compared to Option 1.

Overall, I prefer option 1, but the only option I am very strongly concerned about is option 4.

sffc

comment created time in 4 days

push eventtc39/agendas

Daniel Ehrenberg

commit sha 7df61d671e7de18da6f1085eac5d67b024673ef3

Readding things accidentally deleted in #764

view details

push time in 4 days

issue openedFrankYFTang/proposal-intl-enumeration

More things that we might enumerate over

These are some things that I could imagine using in a picker

  • Languages
  • Regions

In general, if something is supported by Intl.DurationFormat, I wonder if you might want to be able to enumerate over supported values.

For example, this set includes scripts, but maybe enumerating over scripts is only useful in conjunction with data about which scripts may be meaningful for a given locale, which is a whole other project...

created time in 5 days

PR opened tc39/agendas

Decorators status update
+1 -2

0 comment

1 changed file

pr created time in 5 days

create barnchtc39/agendas

branch : littledan-patch-1

created branch time in 5 days

PR opened tc39/agendas

Add two agenda items
+2 -0

0 comment

1 changed file

pr created time in 5 days

create barnchtc39/agendas

branch : littledan-patch-1

created branch time in 5 days

Pull request review commentsyg/proposal-rm-builtin-subclassing

add examples

 Type I is used by user libraries, as well as by the web platform in WebIDL and D  Type II is supported if built-in methods create new instances of the subclass. For example, if `Array.prototype.map` or `Array.from` returns instances of subclasses of `Array`. Support for this is provided by delegating to `this.constructor[`@@species`]` inside built-in methods for the default @@species getter.

Should @@species be mentioned here? What is meant by it?

codehag

comment created time in 5 days

issue commentsyg/proposal-rm-builtin-subclassing

Semantics suggestion: Use SpeciesConstructor just for new.target

OK, sounds like this wouldn't be a big benefit; no need to focus on this idea.

littledan

comment created time in 5 days

push eventtc39/agendas

Sven Sauleau

commit sha 278042a7829bc8a11f79438d1e6444cbba99eab1

Add Module Attributes

view details

Sven Sauleau

commit sha 4aaa15f48b484a4972b61818b2a37042c6c436d5

Update 06.md

view details

push time in 5 days

more