Mutable array methods

# Maël Nison (13 years ago)

I'm just wondering why there is no mutable function with Javascript arrays.

For exemple, if I want to remove every entry matching 42 from an array, I will have to write something like :

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; array = array.filter( function ( x ) { return x === 42; } );

Why is it necessary to make a copy ? Why can't we just write something like this ?

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; array.mfilter( function ( x ) { return x === 42; } ); // mutable filter

The alternative is to use a for loop with splice, but some optimisations won't be available (removing multiple elements at the time ) :

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; for ( var t = array.length; -- t; ) if ( array[ t ] === 42 )

array.splice( t, 1 );

Same for map :

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; array.mmap( function ( ) { return 42; } ); // mutable map

The alternative would be to use the forEach method using three arguments :

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; array.forEach( function ( x, i, a ) { a[ i ] = 42; } );

Is there a reason for these missing functions ?

Thanks,

# David Bruant (13 years ago)

Le 08/03/2012 13:02, Maël Nison a écrit :

Hi,

I'm just wondering why there is no mutable function with Javascript arrays.

For exemple, if I want to remove every entry matching 42 from an array, I will have to write something like :

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; array = array.filter( function ( x ) { return x === 42; } );

Why is it necessary to make a copy ? Why can't we just write something like this ?

var array = [ 0, 1, 42, 3, 4, 5, 42, 42, 42 ]; array.mfilter( function ( x ) { return x === 42; } ); // mutable filter

(...)

Is there a reason for these missing functions ?

None besides history. It's still possible to add these functions to Array.prototype yourslef, though.

# Maël Nison (13 years ago)

Shouldn't native versions be more efficients ?

# David Bruant (13 years ago)

Le 08/03/2012 18:02, Maël Nison a écrit :

Shouldn't native versions be more efficients ?

I heard V8 is on the path of self-hosting (writing standard functions in JavaScript itself) as much as it can (can anyone confirm?).

It seems that in some cases, there is actually no benefit in writing in C++ and a JavaScript-based solution can be 60% faster [1] [2]. This example is DOM, but I wouldn't be surprised if it was true for some ECMAScript functions.

Also, specifically, I would intuit that performance should not be that different for mutation methods while it does change for methods that create a new array since the engine can pre-allocate of correct size right away (control that we don't have in JavaScript).

Regardless, performance had changed so quickly over tha last years that I'm not sure any guess on performance is really accurate for long.

David

[1] twitter.com/#!/jdalton/status/165618550868946944 [2] twitter.com/#!/jdalton/status/165914543418126336

# Brendan Eich (13 years ago)

Maël Nison wrote:

Shouldn't native versions be more efficients ?

No, as David wrote.

Also, it doesn't matter until it matters. There has been little (none to my knowledge until your post) evolutionary pressure or demand for mutating extras. Let's see a popular library or three first, then pave that cowpath.

# Rick Waldron (13 years ago)

On Thu, Mar 8, 2012 at 12:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Le 08/03/2012 18:02, Maël Nison a écrit :

Shouldn't native versions be more efficients ?

I heard V8 is on the path of self-hosting (writing standard functions in JavaScript itself) as much as it can (can anyone confirm?).

Confirmed.

code.google.com/p/v8/source/browse/trunk/src/array.js

# Maël Nison (13 years ago)

I'm 'upping' this discussion for two reasons :

  • I didn't send any response before ! I didn't know that some parts of V8 were self-hosted, so I'm glad to have learn that. Thanks. : )

  • I've just read this article [1] on the web, and it reminds me this discussion. The author is explaining a valid use case of mutable functions (preventing useless garbage collection). It's true that in real time application, garbage collection consume a lot of processing time (factories or persistent objects are not uncommon [2] [3] [4]).

What do you think about this ?

[1] www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript

[2] arcanis/spark.js/blob/master/lib/factory.js [3] zz85/sparks.js/blob/master/Sparks.js#L847 [4] mrdoob/three.js/blob/master/src/core/Matrix4.js#L1038

# David Bruant (13 years ago)

Le 19/03/2012 21:10, Maël Nison a écrit :

Hi,

I'm 'upping' this discussion for two reasons :

  • I didn't send any response before ! I didn't know that some parts of V8 were self-hosted, so I'm glad to have learn that. Thanks. : )

  • I've just read this article [1] on the web, and it reminds me this discussion. The author is explaining a valid use case of mutable functions (preventing useless garbage collection). It's true that in real time application, garbage collection consume a lot of processing time (factories or persistent objects are not uncommon [2] [3] [4]).

What do you think about this ?

My opinion hasn't changed. You can still add these methods yourself to Array.prototype. You are even encouraged to do that and remove methods abusively creating new arrays if it helps promote array reusability in your own code.

Regarding garbage collection, I diverged a thread at some point to start about garbage collection [1]. Allen had really interesting points about how garbage collection works or could work. Modern web browsers are getting there.

"Garbage collection consumes a lot of processing time" because people use it a lot by creating and not reusing. The problem does not come from the collector, but from those who generate the garbage. Very much like for actual garbage ;-)

Garbage collection gives the false impression to programmers that they can stop worrying about memory. But this is a... false impression. You can have leaks in JavaScript code as well. And if it's easy to not reuse the memory you've already allocated, you obviously pay it somewhere else. It's somewhat depressing that someone has to write a blog post to say "reuse things that are already allocated".

David

[1] esdiscuss/2011-November/018782

# Allen Wirfs-Brock (13 years ago)

On Mar 19, 2012, at 2:36 PM, David Bruant wrote:

Le 19/03/2012 21:10, Maël Nison a écrit :

Hi,

I'm 'upping' this discussion for two reasons :

  • I didn't send any response before ! I didn't know that some parts of V8 were self-hosted, so I'm glad to have learn that. Thanks. : )

  • I've just read this article [1] on the web, and it reminds me this discussion. The author is explaining a valid use case of mutable functions (preventing useless garbage collection). It's true that in real time application, garbage collection consume a lot of processing time (factories or persistent objects are not uncommon [2] [3] [4]).

What do you think about this ? My opinion hasn't changed. You can still add these methods yourself to Array.prototype. You are even encouraged to do that and remove methods abusively creating new arrays if it helps promote array reusability in your own code.

Implicit in the original post is the assumption that removing (or adding) elements to an existing object is more efficient (in all performance dimensions) than creating a new object with the desired elements. That isn't always the case...

# David Bruant (13 years ago)

Le 19/03/2012 23:12, Allen Wirfs-Brock a écrit :

On Mar 19, 2012, at 2:36 PM, David Bruant wrote:

Le 19/03/2012 21:10, Maël Nison a écrit :

Hi,

I'm 'upping' this discussion for two reasons :

  • I didn't send any response before ! I didn't know that some parts of V8 were self-hosted, so I'm glad to have learn that. Thanks. : )

  • I've just read this article [1] on the web, and it reminds me this discussion. The author is explaining a valid use case of mutable functions (preventing useless garbage collection). It's true that in real time application, garbage collection consume a lot of processing time (factories or persistent objects are not uncommon [2] [3] [4]).

What do you think about this ? My opinion hasn't changed. You can still add these methods yourself to Array.prototype. You are even encouraged to do that and remove methods abusively creating new arrays if it helps promote array reusability in your own code. Implicit in the original post is the assumption that removing (or adding) elements to an existing object is more efficient (in all performance dimensions) than creating a new object with the desired elements. That isn't always the case...

Indeed. The wipe function may have terrible performances if there are a lot of properties (especially the for-in + hasOwnProperty that could have been replaced by an Object.keys). Probably worse than a bump allocator and an implicit free of the nursery of a generational garbage collector.