# Replace \`.toSorted\`, \`.toSpliced\`, \`.toReversed\` with \`.clone\`

**URL:** <https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025>\
**Category:** 🦋 Proposals\
**Created:** [April 23, 2024, 2:57pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025 "2024-04-23T14:57:09Z")\
**Posts on this page:** 16\
**Page:** 2

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [April 26, 2024, 5:01am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/22 "2024-04-26T05:01:20Z")

</div>

Ok, but they’re already shipped and in the spec - they will never be removed. Your opinion is noted but doesn’t change that fact.

---

<div class="post-metadata">

**Author:** ![Alexander](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/alexander/32/2127_2.png) [@Alexander](https://es.discourse.group/u/Alexander)\
**Post date:** [April 26, 2024, 5:47am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/23 "2024-04-26T05:47:21Z")

</div>

I'm agree with you, we don't need to delete them. We can deprecate them. No one developer will use those methods if are deprecated.

We should try to solve this fast...

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [April 26, 2024, 6:07am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/24 "2024-04-26T06:07:10Z")

</div>

The names are common in other languages.

> <https://github.com/tc39/proposal-change-array-by-copy/issues/10#issuecomment-820224125>
>
> See https://github.com/tc39/proposal-record-tuple/issues/121, but we might want …to discuss naming before commiting to this.

Kotlin has  
`list.sort()` (mutating) [docs](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort.html)  
`list.sorted()` (non-mutating) [docs](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sorted.html)

Java has  
`Arrays.sort(array)` (mutating) [docs](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/Arrays.html#sort(java.lang.Object%5B%5D))  
`stream.sorted()` (non-mutating) [docs](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/stream/Stream.html#sorted())

Python has  
`array.sort()` (mutating) [docs](https://docs.python.org/3/library/stdtypes.html#list.sort)  
`sorted(array)` (non-mutating) [docs](https://docs.python.org/3/library/functions.html#sorted)

Swift has  
`collection.sort()` (mutating) [docs](https://developer.apple.com/documentation/swift/array/1688499-sort)  
`collection.sorted()` (non-mutating) [docs](https://developer.apple.com/documentation/swift/array/2296815-sorted)

---

<div class="post-metadata">

**Author:** ![Alexander](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/alexander/32/2127_2.png) [@Alexander](https://es.discourse.group/u/Alexander)\
**Post date:** [April 26, 2024, 7:07am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/25 "2024-04-26T07:07:16Z")

</div>

So many languages has the `.first()`, `.last()`, `.isEmpty()` and the usefull `.clear()` for their arrays, but JS does not. It does not means anything

Js is a universal language used in all browsers and all devices, we can't just copy and paste other bad languages designs (personal perspective, I did argument on this post)

We need to think about what is better to write and understand, avoid stun developers with a lot of redundant methods and give them exactly what they need, this is related with the scalability of all JS projects

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [April 26, 2024, 3:13pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/26 "2024-04-26T15:13:12Z")

</div>

We don't deprecate things in the language, and your faith that developers will follow guidance is endearing, but empirically largely false.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [April 29, 2024, 11:48am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/27 "2024-04-29T11:48:14Z")

</div>

> [@Alexander](#):
>
> The unique difference between the old and new methods are that those last ones makes a copy of the array to avoid mutate the original one. Where the `.toSorted()` name explains that? It does not.

There's a long-standing convention that `.toFoobar()` methods returns some representation of the object without modifying it. Such as `.toString()`, `.toUpperCase()`, `.toURL()`, etc.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 3, 2024, 6:53pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/28 "2024-05-03T18:53:25Z")

</div>

Could you link to that? I thought lookup was amortized O(1). And monomorphic inline caches reduce that even further to a simple (and easily predicted) conditional jump.

There might be at most about 100 or so externally visible function object types _in the entire spec today_, with the largest objects (`Date`, `Array`, and %TypedArray% prototypes) having less than 20 properties in total. Assuming the growth factor is chosen correctly (normally 0.8), you won't run into the non-linear performance problems in hash tables with any remotely modern form of open addressing until you have _thousands_ of entries _on a single object_.

So I'm highly skeptical of that.

---

<div class="post-metadata">

**Author:** ![Josh-Cena](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/josh-cena/32/1408_2.png) [@Josh-Cena](https://es.discourse.group/u/Josh-Cena)\
**Post date:** [May 3, 2024, 8:08pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/29 "2024-05-03T20:08:44Z")

</div>

IIRC: it was when change-array-by-copy tried to add \>10 methods all at once. I was surprised at first too. But now I can't remember what I saw it (either an issue, meeting notes, or in another repo when they brought this up as an argument for "no more array methods")

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [May 3, 2024, 10:33pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/30 "2024-05-03T22:33:41Z")

</div>

> [@Josh-Cena](#):
>
> "no more array methods")

The no-more-array-methods leaning is mostly driven by how often these end up breaking existing websites. It was something like 1 in 3 of most recently added array methods caused websites issues. `Array.prototype.group` was moved to `{Map,Object}.groupBy` for this reason. Static methods tend to cause fewer issues.

---

<div class="post-metadata">

**Author:** ![nickmccurdy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/nickmccurdy/32/2327_2.png) [@nickmccurdy](https://es.discourse.group/u/nickmccurdy)\
**Post date:** [December 18, 2024, 11:56am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/31 "2024-12-18T11:56:37Z")

</div>

Rather than a deprecation warning (which AFAIK is not going to happen in the ECMAScript standard), couldn't userland code just use something like `clone` or `structuredClone` with a linter that bans `to*` methods?

---

<div class="post-metadata">

**Author:** ![sgmonda](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/sgmonda/32/2337_2.png) [@sgmonda](https://es.discourse.group/u/sgmonda)\
**Post date:** [January 6, 2025, 8:50am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/32 "2025-01-06T08:50:54Z")

</div>

Mutating original arrays was a bad design. It could make sense in the beginning just to make the language more similar to Java, but it makes no sense to consider adding more mutating stuff to arrays in the future.

What I expect is that new array methods in the future have a name starting with `to` without having a mutating counterpart. We’ll add a `Array.prototype.toWhatever()` without having a `Array.prototype.whatever()` mutating version.

So, in my humble opinion, if we had to add a `@deprecated` it would have to be to `.reverse()`, `.sort()`, etc. 😄

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 7, 2025, 4:38am UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/33 "2025-05-07T04:38:29Z")

</div>

> [@sgmonda](#):
>
> Mutating original arrays was a bad design. It could make sense in the beginning just to make the language more similar to Java, but it makes no sense to consider adding more mutating stuff to arrays in the future.

There are a few remaining holes in `Array`'s mutable APIs I want to see filled, though, all for performance reasons:

- Bulk pushing and unshifting into arrays
- Array set with both a start and end index (as well as a typed array equivalent)
- Array length reservation (spec-wise, a no-op, but engines should be taking it as a hint)

Mutation is king in perf-sensitive stuff. Sometimes, it is truly faster to create new objects, but it's rare. Once you start needing to meet effective performance targets of 100k+ ops per second on even mobile for non-trivial operations like [path template evaluation](https://github.com/dead-claudia/mithril.js/blob/8bfbe6b314ba13112b1e125a702292e50b307e35/src/std/path-query.js) ([here's the tests, to show how it'd be called in practice](https://github.com/dead-claudia/mithril.js/blob/8bfbe6b314ba13112b1e125a702292e50b307e35/tests/std/p.js)) or physics calculations, you lose access to most nice things like immutability.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [May 7, 2025, 11:18pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/34 "2025-05-07T23:18:28Z")

</div>

> [@claudiameadows](#):
>
> a few remaining holes in `Array`'s mutable APIs I want to see filled:
> 
> - Bulk pushing and unshifting into arrays
> - Array set with both a start and end index

`splice()` does that already, no?

> [@claudiameadows](#):
>
> - (as well as a typed array equivalent)

For typed arrays, you can use [`.set()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set), possibly in combination with [`.subarray()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray) if you want to copy only a part of an array (since you mentioned an end index).

---

<div class="post-metadata">

**Author:** ![jschoi](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jschoi/32/917_2.png) [@jschoi](https://es.discourse.group/u/jschoi)\
**Post date:** [May 8, 2025, 3:19pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/35 "2025-05-08T15:19:36Z")

</div>

For what it’s worth, there are very, very, very early talks about maybe adding standard Queue and Stack, which would probably support things like bulk shifting and pushing. [Quoting one engine implementor](https://matrixlogs.bakkot.com/TC39_Delegates/2024-10-09#L535):

> take a personal pet peeve: we don't have some pretty basic data structures, like Queue, and people are using arrays to poorly emulate. how does something like that weigh against 'make iterators even more helpful'

> there are crimes being done in the engine to support the expected algorithmic complexity of queue vs stack vs random-access arrays

> yes, you can use [arrays] as such, but we'd also like have data structures fit for purpose

(Don’t expect any concrete proposals for these new data structures for a while. This is very early discussion.)

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 8, 2025, 7:02pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/36 "2025-05-08T19:02:30Z")

</div>

I still would need them for arrays anyways. I'm not pushing these to something I'm popping or unshifting from afterwards. I'm pushing them to something I'm then iterating and sometimes indexing. Stacks and queues don't work for that.

Really, what I truly would prefer is a `FixedArray` abstraction with the same methods as typed arrays. But that seems to not be possible currently.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 8, 2025, 8:16pm UTC](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025/37 "2025-05-08T20:16:34Z")

</div>

> [@bergus](#):
>
> `splice()` does that already, no?

I mean in the sense of typed array `.set(array, offset)`.

> [@bergus](#):
>
> For typed arrays, you can use [`.set()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set), possibly in combination with [`.subarray()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray) if you want to copy only a part of an array (since you mentioned an end index).

I know. I just would prefer to not be doing that when processing hundreds of thousands of buffers a second. I've also seen measurable perf increases in some cases by going _back_ to Node's native buffer set APIs, especially in filesystem reading. (Their network ingress implementation is dog slow, being stuck in single digit megabits per core. Bun's is not, and it's much more limited by the underlying JS engine.)

In fact, this overhead directly causes JS apps to require larger read/write buffers than C apps to maintain equivalent performance. For a server to process 5 Gbps, it needs to process 4096-byte buffers at a little over 150k per second, but 65536-byte buffers at a little over 20k per second. For a simple copying pipe, you're doing 1 write and 1 read per process. For compression and decompression, that's 2 reads and 2 writes, meaning you're doing as much as 600k subarrays per second with 4096-byte buffers, but only about 80k subarrays per second with 65536-byte buffers.

On modern high-end processors, memmove/memcpy and memset can be scheduled at near petabit speeds on a single core, bandwidth permitting. To take Zen 3 and 4 as an example: `rep movsb` (memcpy) and `rep stosb` (memset) on Zen 4 can copy 16 bytes per cycle, or a full 4096-byte page in as little as 256 cycles (≈ 50-80 ns/op, or 384-640 Tbps). Conversely, a single load from L1 cache normally has a 4-5 cycle latency on most high-end cores, and L2 (where most JS property reads would come from) hangs around 14-16 cycles of latency. That means you can only do about 15-18 dependent L2 accesses or about 51-64 dependent L1 accesses in the same amount of time. Creating a temporary subarray might actually hit half of the dependent L2 access count abovr in JIT code if not successfully elided (and I've not seen JS engines do that even in simpler cases like with object literals returned from inlined functions and sent to other inline functions). And for promise creation and scheduling, you're blowing past all of it.

The overhead is non-negligible in high-performance servers and other perf-sensitive scenarios. And while WebAssembly is useful for avoiding this with stuff like audio, it isn't really an option for networking, especially video, because you'd be copying to/from buffers anyways.

[Previous page](https://es.discourse.group/t/replace-tosorted-tospliced-toreversed-with-clone/2025.md?page=1)
