Skip to content

Commit

Permalink
Editorial: Factor out SortIndexedProperties
Browse files Browse the repository at this point in the history
  • Loading branch information
jmdyck committed Mar 9, 2022
1 parent 3728999 commit 87cb50b
Showing 1 changed file with 74 additions and 70 deletions.
144 changes: 74 additions & 70 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -37635,76 +37635,8 @@ <h1>Array.prototype.sort ( _comparefn_ )</h1>
1. Let _ySmaller_ be ! IsLessThan(_yString_, _xString_, *true*).
1. If _ySmaller_ is *true*, return *1*<sub>𝔽</sub>.
1. Return *+0*<sub>𝔽</sub>.
1. Let _items_ be a new empty List.
1. Let _k_ be 0.
1. Repeat, while _k_ &lt; _len_,
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Let _kPresent_ be ? HasProperty(_obj_, _Pk_).
1. If _kPresent_ is *true*, then
1. Let _kValue_ be ? Get(_obj_, _Pk_).
1. Append _kValue_ to _items_.
1. Set _k_ to _k_ + 1.
1. Let _itemCount_ be the number of elements in _items_.
1. [id="step-array-sort"] Sort _items_ using an implementation-defined sequence of calls to _SortCompare_. If any such call returns an abrupt completion, stop before performing any further calls to _SortCompare_ or steps in this algorithm and return that Completion Record.
1. Let _j_ be 0.
1. Repeat, while _j_ &lt; _itemCount_,
1. Perform ? Set(_obj_, ! ToString(𝔽(_j_)), _items_[_j_], *true*).
1. Set _j_ to _j_ + 1.
1. Repeat, while _j_ &lt; _len_,
1. Perform ? DeletePropertyOrThrow(_obj_, ! ToString(𝔽(_j_))).
1. Set _j_ to _j_ + 1.
1. Return _obj_.
1. Return ? SortIndexedProperties(_obj_, _len_, _SortCompare_).
</emu-alg>
<p>The <em>sort order</em> is the ordering of _items_ after completion of step <emu-xref href="#step-array-sort"></emu-xref> of the algorithm above. The result of the `sort` function is then determined as follows:</p>
<p>The sort order is implementation-defined if any of the following conditions is true:</p>
<ul>
<li>
If _comparefn_ is not *undefined* and is not a consistent comparator for the elements of _items_.
</li>
<li>
If _comparefn_ is *undefined* and _SortCompare_ does not act as a consistent comparator.
</li>
<li>
If _comparefn_ is *undefined* and all applications of ToString, to any specific value passed as an argument to _SortCompare_, do not produce the same result.
</li>
</ul>
<p>Unless the sort order is specified above to be implementation-defined, _items_ must satisfy all of the following conditions after executing step <emu-xref href="#step-array-sort"></emu-xref> of the algorithm above:</p>
<ul>
<li>
There must be some mathematical permutation &pi; of the non-negative integers less than _itemCount_, such that for every non-negative integer _j_ less than _itemCount_, the element <emu-eqn>old[_j_]</emu-eqn> is exactly the same as <emu-eqn>new[&pi;(_j_)]</emu-eqn>.
</li>
<li>
Then for all non-negative integers _j_ and _k_, each less than _itemCount_, if <emu-eqn>_SortCompare_(old[_j_], old[_k_]) &lt; 0</emu-eqn>, then <emu-eqn>&pi;(_j_) &lt; &pi;(_k_)</emu-eqn>.
</li>
</ul>
<p>Here the notation <emu-eqn>old[_j_]</emu-eqn> is used to refer to <emu-eqn>_items_[_j_]</emu-eqn> before step <emu-xref href="#step-array-sort"></emu-xref> is executed, and the notation <emu-eqn>new[_j_]</emu-eqn> to refer to <emu-eqn>_items_[_j_]</emu-eqn> after step <emu-xref href="#step-array-sort"></emu-xref> has been executed.</p>
<p>An abstract closure or function _comparator_ is a <dfn id="consistent-comparator">consistent comparator</dfn> for a set of values _S_ if all of the requirements below are met for all values _a_, _b_, and _c_ (possibly the same value) in the set _S_: The notation <emu-eqn>_a_ &lt;<sub>C</sub> _b_</emu-eqn> means <emu-eqn>_comparator_(_a_, _b_) &lt; 0</emu-eqn>; <emu-eqn>_a_ =<sub>C</sub> _b_</emu-eqn> means <emu-eqn>_comparator_(_a_, _b_) = 0</emu-eqn> (of either sign); and <emu-eqn>_a_ &gt;<sub>C</sub> _b_</emu-eqn> means <emu-eqn>_comparator_(_a_, _b_) &gt; 0</emu-eqn>.</p>
<ul>
<li>
Calling _comparator_(_a_, _b_) always returns the same value _v_ when given a specific pair of values _a_ and _b_ as its two arguments. Furthermore, Type(_v_) is Number, and _v_ is not *NaN*. Note that this implies that exactly one of _a_ &lt;<sub>C</sub> _b_, _a_ =<sub>C</sub> _b_, and _a_ &gt;<sub>C</sub> _b_ will be true for a given pair of _a_ and _b_.
</li>
<li>
Calling _comparator_(_a_, _b_) does not modify _obj_ or any object on _obj_'s prototype chain.
</li>
<li>
_a_ =<sub>C</sub> _a_ (reflexivity)
</li>
<li>
If _a_ =<sub>C</sub> _b_, then _b_ =<sub>C</sub> _a_ (symmetry)
</li>
<li>
If _a_ =<sub>C</sub> _b_ and _b_ =<sub>C</sub> _c_, then _a_ =<sub>C</sub> _c_ (transitivity of =<sub>C</sub>)
</li>
<li>
If _a_ &lt;<sub>C</sub> _b_ and _b_ &lt;<sub>C</sub> _c_, then _a_ &lt;<sub>C</sub> _c_ (transitivity of &lt;<sub>C</sub>)
</li>
<li>
If _a_ &gt;<sub>C</sub> _b_ and _b_ &gt;<sub>C</sub> _c_, then _a_ &gt;<sub>C</sub> _c_ (transitivity of &gt;<sub>C</sub>)
</li>
</ul>
<emu-note>
<p>The above conditions are necessary and sufficient to ensure that _comparator_ divides the set _S_ into equivalence classes and that these equivalence classes are totally ordered.</p>
</emu-note>
<emu-note>
<p>Because non-existent property values always compare greater than *undefined* property values, and *undefined* always compares greater than any other value, *undefined* property values always sort to the end of the result, followed by non-existent property values.</p>
</emu-note>
Expand All @@ -37714,6 +37646,77 @@ <h1>Array.prototype.sort ( _comparefn_ )</h1>
<emu-note>
<p>The `sort` function is intentionally generic; it does not require that its *this* value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.</p>
</emu-note>

<emu-clause id="sec-sortindexedproperties" type="abstract operation">
<h1>
SortIndexedProperties (
_obj_: an Object,
_len_: a non-negative integer,
_SortCompare_: an Abstract Closure with two parameters,
): either a normal completion containing an Object or an abrupt completion
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Let _items_ be a new empty List.
1. Let _k_ be 0.
1. Repeat, while _k_ &lt; _len_,
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Let _kPresent_ be ? HasProperty(_obj_, _Pk_).
1. If _kPresent_ is *true*, then
1. Let _kValue_ be ? Get(_obj_, _Pk_).
1. Append _kValue_ to _items_.
1. Set _k_ to _k_ + 1.
1. Let _itemCount_ be the number of elements in _items_.
1. [id="step-array-sort"] Sort _items_ using an implementation-defined sequence of calls to _SortCompare_. If any such call returns an abrupt completion, stop before performing any further calls to _SortCompare_ or steps in this algorithm and return that Completion Record.
1. Let _j_ be 0.
1. Repeat, while _j_ &lt; _itemCount_,
1. Perform ? Set(_obj_, ! ToString(𝔽(_j_)), _items_[_j_], *true*).
1. Set _j_ to _j_ + 1.
1. Repeat, while _j_ &lt; _len_,
1. Perform ? DeletePropertyOrThrow(_obj_, ! ToString(𝔽(_j_))).
1. Set _j_ to _j_ + 1.
1. Return _obj_.
</emu-alg>
<p>The <dfn id="sort-order">sort order</dfn> is the ordering of _items_ after completion of step <emu-xref href="#step-array-sort"></emu-xref> of the algorithm above. The sort order is implementation-defined if _SortCompare_ is not a consistent comparator for the elements of _items_. When SortIndexedProperties is invoked by <emu-xref href="#sec-array.prototype.sort">Array.prototype.sort</emu-xref>, the sort order is also implementation-defined if _comparefn_ is *undefined*, and all applications of ToString, to any specific value passed as an argument to _SortCompare_, do not produce the same result.</p>
<p>Unless the sort order is specified to be implementation-defined, it must satisfy all of the following conditions:</p>
<ul>
<li>
There must be some mathematical permutation &pi; of the non-negative integers less than _itemCount_, such that for every non-negative integer _j_ less than _itemCount_, the element <emu-eqn>old[_j_]</emu-eqn> is exactly the same as <emu-eqn>new[&pi;(_j_)]</emu-eqn>.
</li>
<li>
Then for all non-negative integers _j_ and _k_, each less than _itemCount_, if <emu-eqn>_SortCompare_(old[_j_], old[_k_]) &lt; 0</emu-eqn>, then <emu-eqn>&pi;(_j_) &lt; &pi;(_k_)</emu-eqn>.
</li>
</ul>
<p>Here the notation <emu-eqn>old[_j_]</emu-eqn> is used to refer to <emu-eqn>_items_[_j_]</emu-eqn> before step <emu-xref href="#step-array-sort"></emu-xref> is executed, and the notation <emu-eqn>new[_j_]</emu-eqn> to refer to <emu-eqn>_items_[_j_]</emu-eqn> after step <emu-xref href="#step-array-sort"></emu-xref> has been executed.</p>
<p>An abstract closure or function _comparator_ is a <dfn id="consistent-comparator">consistent comparator</dfn> for a set of values _S_ if all of the requirements below are met for all values _a_, _b_, and _c_ (possibly the same value) in the set _S_: The notation <emu-eqn>_a_ &lt;<sub>C</sub> _b_</emu-eqn> means <emu-eqn>_comparator_(_a_, _b_) &lt; 0</emu-eqn>; <emu-eqn>_a_ =<sub>C</sub> _b_</emu-eqn> means <emu-eqn>_comparator_(_a_, _b_) = 0</emu-eqn> (of either sign); and <emu-eqn>_a_ &gt;<sub>C</sub> _b_</emu-eqn> means <emu-eqn>_comparator_(_a_, _b_) &gt; 0</emu-eqn>.</p>
<ul>
<li>
Calling _comparator_(_a_, _b_) always returns the same value _v_ when given a specific pair of values _a_ and _b_ as its two arguments. Furthermore, Type(_v_) is Number, and _v_ is not *NaN*. Note that this implies that exactly one of _a_ &lt;<sub>C</sub> _b_, _a_ =<sub>C</sub> _b_, and _a_ &gt;<sub>C</sub> _b_ will be true for a given pair of _a_ and _b_.
</li>
<li>
Calling _comparator_(_a_, _b_) does not modify _obj_ or any object on _obj_'s prototype chain.
</li>
<li>
_a_ =<sub>C</sub> _a_ (reflexivity)
</li>
<li>
If _a_ =<sub>C</sub> _b_, then _b_ =<sub>C</sub> _a_ (symmetry)
</li>
<li>
If _a_ =<sub>C</sub> _b_ and _b_ =<sub>C</sub> _c_, then _a_ =<sub>C</sub> _c_ (transitivity of =<sub>C</sub>)
</li>
<li>
If _a_ &lt;<sub>C</sub> _b_ and _b_ &lt;<sub>C</sub> _c_, then _a_ &lt;<sub>C</sub> _c_ (transitivity of &lt;<sub>C</sub>)
</li>
<li>
If _a_ &gt;<sub>C</sub> _b_ and _b_ &gt;<sub>C</sub> _c_, then _a_ &gt;<sub>C</sub> _c_ (transitivity of &gt;<sub>C</sub>)
</li>
</ul>
<emu-note>
<p>The above conditions are necessary and sufficient to ensure that _comparator_ divides the set _S_ into equivalence classes and that these equivalence classes are totally ordered.</p>
</emu-note>
</emu-clause>
</emu-clause>

<emu-clause id="sec-array.prototype.splice">
Expand Down Expand Up @@ -39011,7 +39014,7 @@ <h1>%TypedArray%.prototype.some ( _callbackfn_ [ , _thisArg_ ] )</h1>
<h1>%TypedArray%.prototype.sort ( _comparefn_ )</h1>
<p>%TypedArray%`.prototype.sort` is a distinct function that, except as described below, implements the same requirements as those of `Array.prototype.sort` as defined in <emu-xref href="#sec-array.prototype.sort"></emu-xref>. The implementation of the %TypedArray%`.prototype.sort` specification may be optimized with the knowledge that the *this* value is an object that has a fixed length and whose <emu-xref href="#integer-index">integer-indexed</emu-xref> properties are not sparse.</p>
<p>This function is not generic. The *this* value must be an object with a [[TypedArrayName]] internal slot.</p>
<p>Upon entry, the following steps are performed to initialize evaluation of the `sort` function. These steps are used instead of steps <emu-xref href="#step-array-sort-comparefn"></emu-xref>–<emu-xref href="#step-array-sort-len"></emu-xref> in <emu-xref href="#sec-array.prototype.sort"></emu-xref>:</p>
<p>The following steps are performed:</p>
<emu-alg>
1. If _comparefn_ is not *undefined* and IsCallable(_comparefn_) is *false*, throw a *TypeError* exception.
1. Let _obj_ be the *this* value.
Expand All @@ -39034,6 +39037,7 @@ <h1>%TypedArray%.prototype.sort ( _comparefn_ )</h1>
1. If _x_ is *-0*<sub>𝔽</sub> and _y_ is *+0*<sub>𝔽</sub>, return *-1*<sub>𝔽</sub>.
1. If _x_ is *+0*<sub>𝔽</sub> and _y_ is *-0*<sub>𝔽</sub>, return *1*<sub>𝔽</sub>.
1. Return *+0*<sub>𝔽</sub>.
1. Return ? SortIndexedProperties(_obj_, _len_, _SortCompare_).
</emu-alg>
<emu-note>
<p>Because *NaN* always compares greater than any other value, *NaN* property values always sort to the end of the result when _comparefn_ is not provided.</p>
Expand Down

0 comments on commit 87cb50b

Please sign in to comment.