Pure win: Array.from and Array.of

# Brendan Eich (14 years ago)

Thanks to @rwaldron for compiling these, and dherman (@littlecalculist) for being a twitter conversationalist who speaks in JS:

gist.github.com/1074126, jsfiddle.net/rwaldron/5UjWy

From a twitter conversation sparked by an IRC conversation where I reminded jcranmer at mozilla.com that ES5 Function.prototype.bind can be used to spread arguments into a 'new' expression.

Standardizing these would save reinventing them, and the built-ins could be optimized quite a bit.

# Dmitry A. Soshnikov (14 years ago)

Array.from is a good addition, I guess any good framework has it.

Though, Array.of in contrast doesn't bring much of a sugar. Compare these two apples-to-apples:

Array.of( "things", "that", "aren't", "currently", "an", "array" )

vs.

["things", "that", "aren't", "currently", "an", "array"]

what's the goal in first case to write this useless "Array.of" prefix and exactly the same to manually enumerate the items? In fact, the second one is more suggared than the first one (the first one is: "added useless prefix Array.of and brackets around items are replaced with call parens").

Another thing to consider is Array.prototype.fill method which we discussed before.

The problem:

Array(4).map(function(x) x * x); // [NaN, NaN, NaN, NaN]

(by the way, this mistaken example is still mentioned in this document strawman:shorter_function_syntax, in the "Alternate Syntax Proposals" section, though, is fixed in the main section with let randomArray = NonHoleyArray(10).map(#{Math.random()}); when was mentioned before).

The solution:

// fill with a simple value

Array(4).fill(true); // [true, true, true, true]

// fill with a function in needed context of this

let object = {data: 4}; Array(3).fill(-> if this.data > 3 { 'accepted' } else {'declined' },

object);

Implementation is quite simple also, though, can be optimized in built-ins:

Array.prototype.fill || Object.defineProperty(Array.prototype, "fill", { valu: function arrayFill(filler) { for (var k = 0; k < this.length; k++) { this[k] = typeof filler == "function" ? filler.call(thisArg || this, this[k], k, this) : value; } return this; }, configurable: true, writable: true });

Also class-method Array.fill(count, filler) can be considered.

Dmitry.

# Mike Shaver (14 years ago)

On Sun, Jul 10, 2011 at 6:06 AM, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com> wrote:

The problem:

Array(4).map(function(x) x * x); // [NaN, NaN, NaN, NaN]

I think it actually produces just [ , , , , ], because map skips holes. (If you see the NaN behaviour in FF, please file a bug.)

If I hadn't made map skip holes, then the fill pattern would be simple enough:

Array(4).map(function (_,x) x * x);

Mike

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 14:27, Mike Shaver wrote:

On Sun, Jul 10, 2011 at 6:06 AM, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com> wrote:

The problem:

Array(4).map(function(x) x * x); // [NaN, NaN, NaN, NaN] I think it actually produces just [ , , , , ], because map skips holes. (If you see the NaN behaviour in FF, please file a bug.)

Sorry, did I wrote NaN? A "hole" of course (i.e. "nothing"), which is by [[Get]] is displayed as undefined in Firebug, or just as just ,,,, with toString. Anyway, the issue is in its behavior.

If I hadn't made map skip holes, then the fill pattern would be simple enough:

Array(4).map(function (_,x) x * x);

It's in particular case, you try to multiply indices, which in current implementation of map anyway gives unfortunately nothing.

Dmitry.

# Mike Shaver (14 years ago)

On Sun, Jul 10, 2011 at 7:09 AM, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com> wrote:

If I hadn't made map skip holes, then the fill pattern would be simple enough:

Array(4).map(function (_,x) x * x);

It's in particular case, you try to multiply indices, which in current implementation of map anyway gives unfortunately nothing.

Yes, as I said it would work if map had been specified not to skip holes:

js> [undefined,undefined,undefined,undefined].map(function(_,x)x*x) [0, 1, 4, 9]

Is that not what you want?

Mike

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 15:14, Mike Shaver wrote:

On Sun, Jul 10, 2011 at 7:09 AM, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com> wrote:

If I hadn't made map skip holes, then the fill pattern would be simple enough:

Array(4).map(function (_,x) x * x);

It's in particular case, you try to multiply indices, which in current implementation of map anyway gives unfortunately nothing. Yes, as I said it would work if map had been specified not to skip holes:

Oh, would -- I missed it. Sure, but if it had, I wouldn't mention it at all ;)

But map correctly skips holes, as it should -- to support sparse arrays. The issue is not in map, so that's why I mention fill.

Dmitry.

# Brendan Eich (14 years ago)

On Jul 10, 2011, at 3:06 AM, Dmitry A. Soshnikov wrote:

Array.from is a good addition, I guess any good framework has it.

Though, Array.of in contrast doesn't bring much of a sugar. Compare these two apples-to-apples:

Array.of( "things", "that", "aren't", "currently", "an", "array" )

vs.

["things", "that", "aren't", "currently", "an", "array"]

what's the goal in first case to write this useless "Array.of" prefix and exactly the same to manually enumerate the items? In fact, the second one is more suggared than the first one (the first one is: "added useless prefix Array.of and brackets around items are replaced with call parens").

Note that JS's pattern for alternative constructors is String.fromCharCode, Array.from, etc. -- "class methods".

So the goal of Array.of is to provide a constructor that, unlike Array, does not have that insane special case for Array(42), which presets length (and hints to implementations to preallocate) but leaves holes in [0, length).

I agree that an Array.prototype.fill or similar method is a good addition too.

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 20:36, Brendan Eich wrote:

On Jul 10, 2011, at 3:06 AM, Dmitry A. Soshnikov wrote:

Array.from is a good addition, I guess any good framework has it.

Though, Array.of in contrast doesn't bring much of a sugar. Compare these two apples-to-apples:

Array.of( "things", "that", "aren't", "currently", "an", "array" )

vs.

["things", "that", "aren't", "currently", "an", "array"]

what's the goal in first case to write this useless "Array.of" prefix and exactly the same to manually enumerate the items? In fact, the second one is more suggared than the first one (the first one is: "added useless prefix Array.of and brackets around items are replaced with call parens"). Note that JS's pattern for alternative constructors is String.fromCharCode, Array.from, etc. -- "class methods".

Yes, that's OK with Array.from. That's said, many libs have such a util. Some langs, e.g. Ruby just expose such a possibility as instance method. That is, an object there can just call its inherited method to_a to convert self to array value. Though, Array.from(...) seems better for JS for the same reason as Object.defineProperty is placed on Object instead of the Object.prototype.

So the goal of Array.of is to provide a constructor that, unlike Array, does not have that insane special case for Array(42), which presets length (and hints to implementations to preallocate) but leaves holes in [0, length).

I still don't see how it will help in manual enumeration of the same items which may be directly passed to brackets of array initialiser. We enumerate (by hands) items here, right? -- Array.of(1, 2, 3). And we enumerate items here (by hands also) -- [1, 2, 3]. The difference is that the second case syntactically more elegant and sugared and also doesn't require non-needed function activation with allocating call-stack frame, etc. Still Array.of seems just useless for me. Correct me if I'm wrong. But I'm all in for the Array.from.

Dmitry.

# Brendan Eich (14 years ago)

On Jul 10, 2011, at 9:59 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 20:36, Brendan Eich wrote:

So the goal of Array.of is to provide a constructor that, unlike Array, does not have that insane special case for Array(42), which presets length (and hints to implementations to preallocate) but leaves holes in [0, length).

I still don't see how it will help in manual enumeration of the same items which may be directly passed to brackets of array initialiser. We enumerate (by hands) items here, right? -- Array.of(1, 2, 3). And we enumerate items here (by hands also) -- [1, 2, 3]. The difference is that the second case syntactically more elegant and sugared and also doesn't require non-needed function activation with allocating call-stack frame, etc.

That's all true, but beside the point. The use-case is when you can't write a literal, because you are passing a function-that-constructs as a funarg, and the eventual caller may pass only one number arg, or several args. In that case, Array will not do the right thing in the one-number-arg case.

That's the reason for Array.of.

# Rick Waldron (14 years ago)

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Array.from() still rules.

Rick

-- Sent from my Palm Pre On Jul 10, 2011 12:59 PM, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com> wrote:

On 10.07.2011 20:36, Brendan Eich wrote:

On Jul 10, 2011, at 3:06 AM, Dmitry A. Soshnikov wrote:

Array.from is a good addition, I guess any good framework has it.

Though, Array.of in contrast doesn't bring much of a sugar. Compare these two apples-to-apples:

Array.of( "things", "that", "aren't", "currently", "an", "array" )

vs.

["things", "that", "aren't", "currently", "an", "array"]

what's the goal in first case to write this useless "Array.of" prefix and exactly the same to manually enumerate the items? In fact, the second one is more suggared than the first one (the first one is: "added useless prefix Array.of and brackets around items are replaced with call parens").

Note that JS's pattern for alternative constructors is String.fromCharCode, Array.from, etc. -- "class methods".

Yes, that's OK with Array.from. That's said, many libs have such a

util. Some langs, e.g. Ruby just expose such a possibility as instance

method. That is, an object there can just call its inherited method

to_a to convert self to array value. Though, Array.from(...) seems

better for JS for the same reason as Object.defineProperty is placed

on Object instead of the Object.prototype.

So the goal of Array.of is to provide a constructor that, unlike Array, does not have that insane special case for Array(42), which presets length (and hints to implementations to preallocate) but leaves holes in [0, length).

I still don't see how it will help in manual enumeration of the same

items which may be directly passed to brackets of array initialiser. We

enumerate (by hands) items here, right? -- Array.of(1, 2, 3). And we

enumerate items here (by hands also) -- [1, 2, 3]. The difference is

that the second case syntactically more elegant and sugared and also

doesn't require non-needed function activation with allocating

call-stack frame, etc. Still Array.of seems just useless for me.

Correct me if I'm wrong. But I'm all in for the Array.from.

Dmitry.

# Brendan Eich (14 years ago)

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

# Allen Wirfs-Brock (14 years ago)

On Jul 10, 2011, at 10:23 AM, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

Yes, if you actually need to pass Array.of as a function argument. Of course if we have block lambdas you could just say:

 hof({|a|[a]})

instead of hof(Array.of)

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 21:18, Brendan Eich wrote:

On Jul 10, 2011, at 9:59 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 20:36, Brendan Eich wrote:

So the goal of Array.of is to provide a constructor that, unlike Array, does not have that insane special case for Array(42), which presets length (and hints to implementations to preallocate) but leaves holes in [0, length). I still don't see how it will help in manual enumeration of the same items which may be directly passed to brackets of array initialiser. We enumerate (by hands) items here, right? -- Array.of(1, 2, 3). And we enumerate items here (by hands also) -- [1, 2, 3]. The difference is that the second case syntactically more elegant and sugared and also doesn't require non-needed function activation with allocating call-stack frame, etc. That's all true, but beside the point. The use-case is when you can't write a literal, because you are passing a function-that-constructs as a funarg, and the eventual caller may pass only one number arg, or several args. In that case, Array will not do the right thing in the one-number-arg case.

You mean Function.prototype.construct (dmitrysoshnikov.com/notes/note-1-ecmascript-bound-functions/#constructor-with-various-number-of-arguments)? In this case spread operator will help and some additional thing for this is not required.

That's the reason for Array.of.

Could you please show an example? From what I understand from your words it's sort of:

function Foo(a, b) { ... }

var object = (function (ConstructorFunction, a, b) { return new ConstructorFunction /* here Array.of should help some how to pass a and b - how? */ })(Foo, 10, 20);

Dmitry.

# Rick Waldron (14 years ago)

that is the compelling use-case I was looking for.

Rick

-- Sent from my Palm Pre On Jul 10, 2011 1:23 PM, Brendan Eich <brendan at mozilla.com> wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 21:32, Allen Wirfs-Brock wrote:

On Jul 10, 2011, at 10:23 AM, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

Yes, if you actually need to pass Array.of as a function argument. Of course if we have block lambdas you could just say:

 hof({|a|[a]})

instead of hof(Array.of)

Can you show a real use-case of it please?

Dmitry.

# Brendan Eich (14 years ago)

On Jul 10, 2011, at 10:32 AM, Allen Wirfs-Brock wrote:

On Jul 10, 2011, at 10:23 AM, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

Yes, if you actually need to pass Array.of as a function argument. Of course if we have block lambdas you could just say:

 hof({|a|[a]})

instead of hof(Array.of)

You know I <3 block-lambdas ;-).

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 21:23, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

You mean when Array itself is passed as an argument?

var o = (function (ArrayConstructor, ...rest) { return ArrayConstructor(...rest); })(Array, 10, 20, 30);

Or I'm still missing something?

Dmitry.

# Dmitry A. Soshnikov (14 years ago)

And I don't see it still. Maybe you can explain it in some detail then if you have understood it?

Dmitry.

# Allen Wirfs-Brock (14 years ago)

On Jul 10, 2011, at 10:32 AM, Allen Wirfs-Brock wrote:

Yes, if you actually need to pass Array.of as a function argument. Of course if we have block lambdas you could just say:

 hof({|a|[a]})

instead of hof(Array.of)

actually the above aren't equivalent. The block lambda form would have to be:

 hof({|...a|[...a]})

so it would loose the length way by 6 characters.

# John-David Dalton (14 years ago)

I dig Array.from, and have manually made sugar for that in my projects. Array.of is something I have also wanted though I had been struggling with a name for it. Until now if I wanted to avoid setting the array length I would do something like ns.Array.from([23]), but Array.of is nice too ;)

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 22:26, John-David Dalton wrote:

I dig Array.from, and have manually made sugar for that in my projects. Array.of is something I have also wanted though I had been struggling with a name for it.

It's interesting -- can you show where and how?

Until now if I wanted to avoid setting the array length I would do something like ns.Array.from([23]),

What. Is. That. ?

Isn't just [23] is enough?

Guys, I understand we need Array.from as a good addition. Note -- it's just the addition to be able use array methods. We though can do it and without it via call and apply since most of array methods are generic.

but Array.of is nice too ;)

Can maybe you show me a real useful example of Arra.of?

Dmitry.

# Brendan Eich (14 years ago)

On Jul 10, 2011, at 10:40 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 21:23, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

You mean when Array itself is passed as an argument?

var o = (function (ArrayConstructor, ...rest) { return ArrayConstructor(...rest); })(Array, 10, 20, 30);

Yes. Now consider the case where you leave out the 20 and 30.

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 22:44, Brendan Eich wrote:

On Jul 10, 2011, at 10:40 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 21:23, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

You mean when Array itself is passed as an argument?

var o = (function (ArrayConstructor, ...rest) { return ArrayConstructor(...rest); })(Array, 10, 20, 30);

Yes. Now consider the case where you leave out the 20 and 30.

return ArrayConstructor(rest[0]) ?

May I ask to show nevertheless how you want to apply here Array.of?

P.S.:

If this is a wish-list of extending standard array lib, we can consider also the following:

  • Array.prototype.remove(value, all)

[1, 2, 3, 2].remove(2); // [1, 3, 2] [1, 2, 3, 2].remove(2, true); // [1, 3]

(seems this function is required more than Array.of, because at least I saw it implemented in all frameworks and used it myself).

  • Array.prototype.subtract(array)

[1, 2, 3, 4].subtract([2, 4]); // [1, 3]

  • Array.seq(from, to)

Array.seq(1, 5); // [1, 2, 3, 4, 5]

  • Array.min(array), Array.max(array) (can be implemented with Math.max/min and apply though)

Array.min = (array) -> Math.min.apply(Math, array)

  • Array.prototype.split(n)

["a", "b", "c", "d", "e"].split(3) // [["a", "b", "c"], ["d", "e", "f"]]

Perhaps even to build objects from lists of keys and values (this function is usually called as zip):

  • Object.fromLists(["a", "b", "c"], [1, 2, 3]); // {a: 1, b: 2, c: 3}

Dmitry.

# Dmitry A. Soshnikov (14 years ago)

And by the way, an efficient Array.prototype.unique also would be nice to have, since in JS in general it's hard to implement it's efficiently (in lower level at least it will iterate faster).

[1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5]

Dmitry.

# Juan Ignacio Dopazo (14 years ago)

On Sun, Jul 10, 2011 at 2:35 PM, Dmitry A. Soshnikov < dmitry.soshnikov at gmail.com> wrote:

** On 10.07.2011 21:32, Allen Wirfs-Brock wrote:

On Jul 10, 2011, at 10:23 AM, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

Yes, if you actually need to pass Array.of as a function argument. Of course if we have block lambdas you could just say:

  hof({|a|[a]})

instead of hof(Array.of)

Can you show a real use-case of it please?

Dmitry.

A real use-case for this functions: yuilibrary.com/forum/viewtopic.php?f=18&t=7978 YUI uses get/set methods for dealing with attributes and has a declarative form for them that looks like this:

Y.SomeClass = Y.Base.create('someClass', Y.Superclass, [Y.Mixin], proto, { ATTRS: { someAttr: { value: [] } } });

Using [] as a default value can lead to bugs because the class will hold a reference to a unique array in all instances. Using a constructor function one can be sure each instance will have a fresh array.

Y.SomeClass = Y.Base.create('someClass', Y.Superclass, [Y.Mixin], proto, { ATTRS: { someAttr: { valueFn: Array } } });

Here valueFn calls the provided function to create the default value each time. In this case it would create a new array. Array creation functions would help create more complex patters and avoid bugs with unexpected parametes (tough now I think Array.bind(null, 0) maybe could work...

Juan

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 23:09, Dmitry A. Soshnikov wrote:

And by the way, an efficient Array.prototype.unique also would be nice to have, since in JS in general it's hard to implement it's efficiently (in lower level at least it will iterate faster).

[1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5]

Dmitry.

On 10.07.2011 23:02, Dmitry A. Soshnikov wrote:

On 10.07.2011 22:44, Brendan Eich wrote:

On Jul 10, 2011, at 10:40 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 21:23, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

You mean when Array itself is passed as an argument?

var o = (function (ArrayConstructor, ...rest) { return ArrayConstructor(...rest); })(Array, 10, 20, 30);

Yes. Now consider the case where you leave out the 20 and 30.

return ArrayConstructor(rest[0]) ?

Ah, goddammit, sorry, I got it. Completely forgot about this case, even if myself just showed it before in Array(42).map example, thanks for mentioning. It will of course create array with length 10 and with holes (some implementations, in particular V8 even pre-allocate these holes).

So Array.of is just exactly and only for this use-case.

Dmitry.

# Dmitry A. Soshnikov (14 years ago)

On 10.07.2011 23:25, Juan Ignacio Dopazo wrote:

On Sun, Jul 10, 2011 at 2:35 PM, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com <mailto:dmitry.soshnikov at gmail.com>> wrote:

On 10.07.2011 21:32, Allen Wirfs-Brock wrote:
On Jul 10, 2011, at 10:23 AM, Brendan Eich wrote:
On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:
The more I think about it, I still can't come up with any
really exciting use cases where Array.of
<http://Array.of/> would outshine anything that already exists.
I say strike it from the wishlist.
Higher-order programming with Array as constructing-function
bites back for the single-number-argument case. That's where
Array.of helps.
Yes, if you actually need to pass Array.of as a function
argument.  Of course if we have block lambdas you could just say:

     hof({|a|[a]})
instead of
     hof(Array.of)
Can you show a real use-case of it please?

Dmitry.

A real use-case for this functions: yuilibrary.com/forum/viewtopic.php?f=18&t=7978, yuilibrary.com/forum/viewtopic.php?f=18&t=7978 YUI uses get/set methods for dealing with attributes and has a declarative form for them that looks like this:

Y.SomeClass = Y.Base.create('someClass', Y.Superclass, [Y.Mixin], proto, { ATTRS: { someAttr: { value: [] } } });

Using [] as a default value can lead to bugs because the class will hold a reference to a unique array in all instances. Using a constructor function one can be sure each instance will have a fresh array.

Y.SomeClass = Y.Base.create('someClass', Y.Superclass, [Y.Mixin], proto, { ATTRS: { someAttr: { valueFn: Array } } });

Here valueFn calls the provided function to create the default value each time. In this case it would create a new array. Array creation functions would help create more complex patters and avoid bugs with unexpected parametes (tough now I think Array.bind(null, 0) maybe could work...

I see. Though, the case with Array.bind(null, 0) seems is particular for YUI.

Anyway, from what I can say now Array.of is a "fixed" version of Array which doesn't have a special case of Array(length), but always considers it as Array(items...). Don't know how rare/often this case is. Sometimes it's needed vice-versa to create Array(length). I also think we should consider other proposals of arrays library which I mentioned in previous letter.

Dmitry.

# David Herman (14 years ago)

I mentioned two benefits I can see to Array.of over []-literals here:

https://twitter.com/#!/littlecalculist/status/89854372405723136
  1. With Array.of you know you aren't going to accidentally create holes, and

  2. if you're passing it to a higher-order function you know you aren't going to trip over the single-uint32-arg special case.

That said, the "readability" story you and I tweeted about is not so compelling given that, in the first-order usage pattern an array-literal is strictly more readable. So a longer name like Array.fromElements or something might be okay.

# Brendan Eich (14 years ago)

On Jul 10, 2011, at 12:02 PM, Dmitry A. Soshnikov wrote:

On 10.07.2011 22:44, Brendan Eich wrote:

On Jul 10, 2011, at 10:40 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 21:23, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

You mean when Array itself is passed as an argument?

var o = (function (ArrayConstructor, ...rest) { return ArrayConstructor(...rest); })(Array, 10, 20, 30);

Yes. Now consider the case where you leave out the 20 and 30.

return ArrayConstructor(rest[0]) ?

The called function taking ArrayConstructor cannot assume it was passed only one trailing parameter captured by ...rest!

May I ask to show nevertheless how you want to apply here Array.of?

You would pass Array.of instead of Array, of course.

P.S.:

If this is a wish-list of extending standard array lib, we can consider also the following:

A postscript is no place for more wish list items. See the subject: and start a new thread.

# Dmitry A. Soshnikov (14 years ago)

On 11.07.2011 0:35, Brendan Eich wrote:

On Jul 10, 2011, at 12:02 PM, Dmitry A. Soshnikov wrote:

On 10.07.2011 22:44, Brendan Eich wrote:

On Jul 10, 2011, at 10:40 AM, Dmitry A. Soshnikov wrote:

On 10.07.2011 21:23, Brendan Eich wrote:

On Jul 10, 2011, at 10:18 AM, Rick Waldron wrote:

The more I think about it, I still can't come up with any really exciting use cases where Array.of Array.of would outshine anything that already exists. I say strike it from the wishlist.

Higher-order programming with Array as constructing-function bites back for the single-number-argument case. That's where Array.of helps.

You mean when Array itself is passed as an argument?

var o = (function (ArrayConstructor, ...rest) { return ArrayConstructor(...rest); })(Array, 10, 20, 30);

Yes. Now consider the case where you leave out the 20 and 30.

return ArrayConstructor(rest[0]) ?

The called function taking ArrayConstructor cannot assume it was passed only one trailing parameter captured by ...rest!

May I ask to show nevertheless how you want to apply here Array.of?

You would pass Array.of instead of Array, of course.

Yes, I've already realized it. Array.of is just a "fixed" version of Array. Though, I'm still thinking how rare/often these cases are.

P.S.:

If this is a wish-list of extending standard array lib, we can consider also the following:

A postscript is no place for more wish list items. See the subject: and start a new thread.

Yes, OK, it will be better.

Dmitry.

# Allen Wirfs-Brock (14 years ago)

On Jul 10, 2011, at 12:09 PM, Dmitry A. Soshnikov wrote:

And by the way, an efficient Array.prototype.unique also would be nice to have, since in JS in general it's hard to implement it's efficiently (in lower level at least it will iterate faster).

[1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5]

Before considering adding too many things to Array.prototype we perhaps should start considering the protocol of a real collection hierarchy that goes beyond just arrays.

# Dmitry A. Soshnikov (14 years ago)

On 11.07.2011 20:01, Allen Wirfs-Brock wrote:

On Jul 10, 2011, at 12:09 PM, Dmitry A. Soshnikov wrote:

And by the way, an efficient Array.prototype.unique also would be nice to have, since in JS in general it's hard to implement it's efficiently (in lower level at least it will iterate faster).

[1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5] Before considering adding too many things to Array.prototype

I wouldn't call such standard methods which are present in standard libraries of many languages as "too many things".

we perhaps should start considering the protocol of a real collection hierarchy that goes beyond just arrays.

Yes, and this is of course true.

Dmitry.

# Andrea Giammarchi (14 years ago)

glad somebody said that!

Also I would pollute performance oriented methods rather than "whatever framework sugar" anybody could easily add where unique() and remove(all) may be part of these cases while fill() could be superfluous.

Andrea

# Alex Russell (14 years ago)

On Jul 26, 2011, at 7:10 AM, Andrea Giammarchi wrote:

glad somebody said that!

Also I would pollute performance oriented methods rather than "whatever framework sugar" anybody could easily add where unique() and remove(all) may be part of these cases while fill() could be superfluous.

I feel like i have to stick up for "framework sugar". This stuff is getting sent around the network at dizzying expense in latency, bytes, and collision potential/workarounds. Framework sugar is only dismissible in a world where you can actually extend the prototypes, and that means being in control of the entire app today. Few (if any) frameworks can do this right now, and without something like SOE, it's not clear to me that the dynamics are set to change. That leaves us in a place where it's up to the language to add the sugar we all would like to see, else nobody (credibly) can. So lets either stop calling it "sugar" when libraries do it or start acknowledging that sugar isn't a cheap import.

On Mon, Jul 11, 2011 at 6:01 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

On Jul 10, 2011, at 12:09 PM, Dmitry A. Soshnikov wrote:

And by the way, an efficient Array.prototype.unique also would be nice to have, since in JS in general it's hard to implement it's efficiently (in lower level at least it will iterate faster).

[1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5]

Before considering adding too many things to Array.prototype we perhaps should start considering the protocol of a real collection hierarchy that goes beyond just arrays.

Allen


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# Andrea Giammarchi (14 years ago)

Alex I think whatever method we have natively won't be enough for this or that case, plus once a method is implemented native his signature becomes legacy developers may like or not.

With Object.defineProperty we could pollute Array.prototype avoiding the most annoying and idiotic thing developers have been historically complained about ( and "I really don't know why" ): the for/in loop

Same is for Object.prototype so ... we already have the power to add the sugar we may or may not need ( I am not saying anybody should do this ) but what is missing is some kick ass performances method and not the whole Prototype/Dojo framework in core, imo.

In few words, it won't surprise me if at some point some library/framework will go out with such code:

Object.defineProperty(Array.prototype, "remove", { enumerable: false, writable: false, configurable: false, value: function (value, all) { var i = 0; do { i = this.indexOf(value, i); if (-1 < i) { this.splice(i, 1); all = all && true; } else { all = false; } } while(all); } });

Then we gonna have problems with live collections, the fact is missing the index to start with the removing operation or who knows what other edge/adhoc case ... and this is just for an extra remove so, why bother with all possible frameworks sugar?

It makes sense if we have real usages in numbers rather than the fact that "if it's there it surely means developers need it", don't you agree?

Don't get me wrong, the more we have the more powerful/fast the language looks like but I am not sure we really need all these shortcuts.

Andrea

P.S. about non Array specific stuff, I am looking at typed Array big time ... there I would never complain about a Vec3Array with a multiply(Vec3) native method for sure!