Re: Pure win: Array.from and Array.of
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 http://wiki.ecmascript.org/doku.php?id=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. On 10.07.2011 9:35, Brendan Eich wrote: Thanks to @rwaldron for compiling these, and dherman (@littlecalculist) for being a twitter conversationalist who speaks in JS: https://gist.github.com/1074126 http://jsfiddle.net/rwaldron/5UjWy/ From a twitter conversation sparked by an IRC conversation where I reminded jcran...@mozilla.com mailto:jcran...@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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
On 10.07.2011 14:27, Mike Shaver wrote: On Sun, Jul 10, 2011 at 6:06 AM, Dmitry A. Soshnikov dmitry.soshni...@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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
On Sun, Jul 10, 2011 at 7:09 AM, Dmitry A. Soshnikov dmitry.soshni...@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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
On 10.07.2011 15:14, Mike Shaver wrote: On Sun, Jul 10, 2011 at 7:09 AM, Dmitry A. Soshnikov dmitry.soshni...@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. js [undefined,undefined,undefined,undefined].map(function(_,x)x*x) [0, 1, 4, 9] Is that not what you want? Mike ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Array generation (was: Pure win: Array.from and Array.of)
Le 10/07/2011 12:06, Dmitry A. Soshnikov a écrit : (...) 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 http://wiki.ecmascript.org/doku.php?id=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); What is Array(9).fill(function(){})? An array filled with 9 undefined? An array filled with 9 (no-op) functions? 9 undefined according to the implementation you provided. I think it should be 9 functions. Another syntax should be provided to generate values with a function. Maybe: Array.generate(count, fillerFunction/*throws a TypeError if not callable*/, thisArg) (call count times fillerFunction.bind(thisArg) and return value of i-th call is [[Put]] as i-th element of the array) Array.fill could be implemented as: Array.fill = function(c, v){ return Array.generate(c, (- v) ); }; (...) Also class-method Array.fill(count, filler) can be considered. Since .fill seems to be intended for initialization, I would tend to be in favor of an Array.fill method rather than Array.prototype.fill. But a Array.fill syntax would prevent from choosing the prototype. Maybe harmony:array_comprehensions could be enhanced to support array generation? Since I'm not familiar with the proposal, I won't try to play with the grammar, but it sounds like the right place to suggest initialization syntax. And it would solve the prototype issue in combination with the proto operator: myProto | [/*my syntax generating an array of 1000 elements*/] David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array generation
On 10.07.2011 15:54, David Bruant wrote: Le 10/07/2011 12:06, Dmitry A. Soshnikov a écrit : (...) 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 http://wiki.ecmascript.org/doku.php?id=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); What is Array(9).fill(function(){})? An array filled with 9 undefined? An array filled with 9 (no-op) functions? 9 undefined according to the implementation you provided. I think it should be 9 functions. It's a good question. Though, usually it's needed to initiate an array just with a simple value, so the case with a function (as a filler) was provided as just an addition. From this viewpoint, yes, perhaps it should 9 functions. Another syntax should be provided to generate values with a function. Maybe: Array.generate(count, fillerFunction/*throws a TypeError if not callable*/, thisArg) (call count times fillerFunction.bind(thisArg) and return value of i-th call is [[Put]] as i-th element of the array) Array.fill could be implemented as: Array.fill = function(c, v){ return Array.generate(c, (- v) ); }; Yes, it's common way, though, that's said, usually it's needed only to fill an array with e.g. Array.fill(1) So from this viewpoint (and regarding that example with squares), it's good to have also `Array.seq(from, to)` method (the name is taken from Erlang, I just frequently uses lists:seq(from, to) there): Array.seq(1, 5).map((x) - x * x); [1, 4, 9, 16, 25] (...) Also class-method Array.fill(count, filler) can be considered. Since .fill seems to be intended for initialization, I would tend to be in favor of an Array.fill method rather than Array.prototype.fill. But a Array.fill syntax would prevent from choosing the prototype. Maybe harmony:array_comprehensions could be enhanced to support array generation? Since I'm not familiar with the proposal, I won't try to play with the grammar, but it sounds like the right place to suggest initialization syntax. And it would solve the prototype issue in combination with the proto operator: myProto| [/*my syntax generating an array of 1000 elements*/] Yes, also have to consider it and think. Dmitry. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
The more I think about it, I still can't come up with any really exciting use casesnbsp;wherenbsp;Array.ofnbsp;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 lt;dmitry.soshni...@gmail.comgt; wrote: On 10.07.2011 20:36, Brendan Eich wrote: gt; On Jul 10, 2011, at 3:06 AM, Dmitry A. Soshnikov wrote: gt; gt;gt; Array.from is a good addition, I guess any good framework has it. gt;gt; gt;gt; Though, `Array.of` in contrast doesn't bring much of a sugar. Compare these two apples-to-apples: gt;gt; gt;gt; Array.of( things, that, aren't, currently, an, array ) gt;gt; gt;gt; vs. gt;gt; gt;gt; [things, that, aren't, currently, an, array] gt;gt; gt;gt; 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). gt; Note that JS's pattern for alternative constructors is String.fromCharCode, Array.from, etc. -- class methods. gt; 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`. gt; 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). gt; 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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 (http://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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 ;-). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
And I don't see it still. Maybe you can explain it in some detail then if you have understood it? Dmitry. On 10.07.2011 21:33, Rick Waldron wrote: _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 bren...@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 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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: using Private name objects for declarative property definition.
On Jul 9, 2011, at 7:22 PM, Brendan Eich wrote: On Jul 9, 2011, at 5:02 PM, Allen Wirfs-Brock wrote: ... 1) stratification - Proxy.isProxy is an example 2) It is impossible or inconvenient to add the classification interface to the appropriate instance interface. I think that was the reason for Array.isArray. We were more afraid of adding it to Array.prototype than to Array. That's too bad, since we added Function.prototype.isGenerator (which as I noted last time shows up on Function, of course!) without problem. It's Object.prototype that people can't extend, and then the warning about other built-ins is pre-ES5, out of lack of enumerable control, so for fear of breaking for-in loops. Adding a non-enumerable Array.prototype method seems doable to me, if the name is clear and not commonly used. We can probably still add Array.prototoype.isArray if that would help to establish the pattern. Document as being preferred over Array.isArray Well, if you were actually using Proxy to implement Array, you would probably also be providing the Array implementation. Not necessarily -- you might just want isArray to return true for your proxied fakes and the real deal. But yes, you would have to provide at least Array.isArray. With all the standard methods on Array.prototype generic, I believe you wouldn't have to replace all of Array. but if you want (new Array()) to create the fakes... However, arguably Array.isArray really should have been Array.prototype.isArray. We treated as a case 2 from above. May we really didn't need to, but that's water over dam. I don't think we should use it as precedent for more greenfield situations. First thought: Crock sold us on reformed Number.is{NaN,Finite} along with new Numer.isInteger. We can do both and correct course for the long run, perhaps: Array.isArray and Array.prototype.isArray. But first we should settle the data property vs. method issue. yes. I wonder if isArray and isInteger are different kinds of categorizations (class based vs value based) that perhaps should have distinct naming conventions. But f the method implementation is simply going to be return true or return false why do yo need to call it at all? The general case is an optional method, a notification hook call-out or some such. You're right that for object detection the method call seems a waste. We could have made Function isGenerator a non-writable, non-configurable, and non-enumerable boolean-valued data property. But, then it would be an instance property, which burns storage (the shape or hidden class sharing is not the issue, the true or false value slot is); or else an accessor on Function.prototype, which is about as costly as a method in implementations. Users testing it would not have to write (), your point. That wins. But otherwise it's a wash. Why not a non-writable,non-enumerable non-configurable data property on Function.prototype. Smalltalk code guidelines would general say (but I'll use JS syntax here instead of Smalltalk): obj.isFoo//ok obj.constructor.isFoo(obj) //less ok, unless there is a good reason Foo.isFoo(obj) //even less good In the first two you are only statically coupled to obj in the third you are statically coupled to both obj and Foo. Right, and as you say there may be a reason for that (reasons 1 and 3; not sure about 2). and I should have included: obj.constructor === Foo //very bad Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 ;) - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 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. 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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 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. 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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
module exports
Hi Dave: According to the module grammar, the following is valid: 691module car { function startCar() {} module engine { function start() {} } export {start:startCar} from engine; } It seems like there would be issues with exporting module elements after the module has been defined. Also, what is the behavior of aliasing over existing Identifiers? Would the compiler fail or would behavior be the 'last' Identifier wins?___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 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. 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. 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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
On 10.07.2011 23:25, Juan Ignacio Dopazo wrote: On Sun, Jul 10, 2011 at 2:35 PM, Dmitry A. Soshnikov dmitry.soshni...@gmail.com mailto:dmitry.soshni...@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: http://yuilibrary.com/forum/viewtopic.php?f=18t=7978 http://yuilibrary.com/forum/viewtopic.php?f=18t=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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array generation
So from this viewpoint (and regarding that example with squares), it's good to have also `Array.seq(from, to)` method (the name is taken from Erlang, I just frequently uses lists:seq(from, to) there): bikeshedArray.range seems like an intuitive name as well./bikeshed Array.seq(1, 5).map((x) - x * x); [1, 4, 9, 16, 25] This pattern (integer range immediately followed by map) is so common that many Schemes have a more general function that fuses the two traversals, sometimes called build-list or list-tabulate: Array.build(n, f) ~~~ [f(0), ..., f(n-1)] Another common and useful fusion of two traversals that's in many Schemes is map-filter or filter-map: a.filterMap(f) ~~~ [res for [i,x] of items(a) let (res = f(x, i)) if (res !== void 0)] I rather arbitrarily chose to accept both null and undefined here as way to say no element -- a reasonable alternative would be to accept *only* undefined as no element. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. Dave On Jul 10, 2011, at 10:33 AM, Rick Waldron wrote: _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 bren...@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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Pure win: Array.from and Array.of
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 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. 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. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Extending standard library of arrays
Here I put some extensions for arrays standard library (separated from this thread: https://mail.mozilla.org/pipermail/es-discuss/2011-July/015856.html where Array.of and Array.from were considered). We can consider also the following (as a first step): *- 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)* // or Array.range(from, to) Array.seq(1, 5); // [1, 2, 3, 4, 5] *- Array.build(n, fn)* Array.build(5, function(index) index + 1); // [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.fromArrays([a, b, c], [1, 2, 3]);* // {a: 1, b: 2, c: 3} *- Array.prototype.unique* [1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5] Thus, all names of methods can be discussed. Dmitry. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Extending standard library of arrays
In addition, here's Erlang's one, which has rich lists library -- http://www.erlang.org/doc/man/lists.html Some/most methods are already implemented in JS of course (though, by different names), but we can take missing, but needed (and thus implemented in many JS libs) methods. Dmitry. On 11.07.2011 0:46, Dmitry A. Soshnikov wrote: Here I put some extensions for arrays standard library (separated from this thread: https://mail.mozilla.org/pipermail/es-discuss/2011-July/015856.html where Array.of and Array.from were considered). We can consider also the following (as a first step): *- 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)* // or Array.range(from, to) Array.seq(1, 5); // [1, 2, 3, 4, 5] *- Array.build(n, fn)* Array.build(5, function(index) index + 1); // [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.fromArrays([a, b, c], [1, 2, 3]);* // {a: 1, b: 2, c: 3} *- Array.prototype.unique* [1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5] Thus, all names of methods can be discussed. Dmitry. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array generation
David, I like the way you paint your bike sheds. Array.range() (or similarly functional but differently named) is definitely another one of those oft-rerolled solutions. Rick On Sun, Jul 10, 2011 at 4:23 PM, David Herman dher...@mozilla.com wrote: So from this viewpoint (and regarding that example with squares), it's good to have also `Array.seq(from, to)` method (the name is taken from Erlang, I just frequently uses lists:seq(from, to) there): bikeshedArray.range seems like an intuitive name as well./bikeshed Array.seq(1, 5).map((x) - x * x); [1, 4, 9, 16, 25] This pattern (integer range immediately followed by map) is so common that many Schemes have a more general function that fuses the two traversals, sometimes called build-list or list-tabulate: Array.build(n, f) ~~~ [f(0), ..., f(n-1)] Another common and useful fusion of two traversals that's in many Schemes is map-filter or filter-map: a.filterMap(f) ~~~ [res for [i,x] of items(a) let (res = f(x, i)) if (res !== void 0)] I rather arbitrarily chose to accept both null and undefined here as way to say no element -- a reasonable alternative would be to accept *only* undefined as no element. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Design principles for extending ES object abstractions
I'm not sure what Array.prototype methods would or wouldn't work on instances of SubArray. All of them. They are all generic. We're speaking too broadly here. It depends on what we want to work how. For example, .map can't magically know how to produce a SubArray as its result if that's how SubArray wants it to work. But what I'm actually more concerned about is the behavior of .length. Does the | semantics make .length work automagically the way it does for ordinary Array instances? However, subarray instances have all the internal state and methods that make them true arrays so even if some of the inherited Array methods weren't generic they would still work. Including .length (which isn't a method, but YKWIM)? Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array generation
On 10 July 2011 22:23, David Herman dher...@mozilla.com wrote: Another common and useful fusion of two traversals that's in many Schemes is map-filter or filter-map: a.filterMap(f) ~~~ [res for [i,x] of items(a) let (res = f(x, i)) if (res !== void 0)] I rather arbitrarily chose to accept both null and undefined here as way to say no element -- a reasonable alternative would be to accept *only* undefined as no element. The way I think of it is that in analogy to NaN being the Numbers that represent no number, null is the Object that represents no object, in other words a reasonable value to store to tell just that. The undefined value is by analogy the value that represents no value, so is the only value that should be a no element. But that might be just my way of thinking about and distinguishing the not-a-something special cases. -- David liorean Andersson ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array generation
Agreed. I think that's a pretty common way people think about null vs undefined, and it's consistent with the language's behavior. Dave On Jul 10, 2011, at 3:09 PM, liorean wrote: On 10 July 2011 22:23, David Herman dher...@mozilla.com wrote: Another common and useful fusion of two traversals that's in many Schemes is map-filter or filter-map: a.filterMap(f) ~~~ [res for [i,x] of items(a) let (res = f(x, i)) if (res !== void 0)] I rather arbitrarily chose to accept both null and undefined here as way to say no element -- a reasonable alternative would be to accept *only* undefined as no element. The way I think of it is that in analogy to NaN being the Numbers that represent no number, null is the Object that represents no object, in other words a reasonable value to store to tell just that. The undefined value is by analogy the value that represents no value, so is the only value that should be a no element. But that might be just my way of thinking about and distinguishing the not-a-something special cases. -- David liorean Andersson ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Extending standard library of arrays
Le 10/07/2011 22:46, Dmitry A. Soshnikov a écrit : Here I put some extensions for arrays standard library (separated from this thread: https://mail.mozilla.org/pipermail/es-discuss/2011-July/015856.html where Array.of and Array.from were considered). We can consider also the following (as a first step): *- 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)* // or Array.range(from, to) Array.seq(1, 5); // [1, 2, 3, 4, 5] *- Array.build(n, fn)* Array.build(5, function(index) index + 1); // [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.fromArrays([a, b, c], [1, 2, 3]);* // {a: 1, b: 2, c: 3} *- Array.prototype.unique* [1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5] Thus, all names of methods can be discussed. I like a lot all of these ideas, but I can't help thinking that they do not seem to be aligned with the initial ECMAScript array design which is that arrays are ECMAScript objects (which is very different from what we'd understand of array in C or lists in Erlang as you cite them). The question I ask for each of your Array.prototype ideas is how does it apply to non-dense arrays?. Creating a List or a DenseArray (or both?) type sounds to better capture your intentions (especially since you provided a link to Erlang list methods). It could inherit everything from Array.prototype for free. Actually, this could be implemented with proxies :-) Since we're suggesting array additions, I would be interested in trying to address one issue of forEach, map, every, some and filter. They all have a well-defined algorithm. Consequently, if the callback function has side-effects, these are deterministic. This, however, prevent efficient (parallelized, for instance) implementation. This is unfortunate since in a lot of cases, people don't do side-effect and would certainly trade the side-effect determinism guarantee for performance. Could it be considered to add non-deterministic versions of these functions? They would be defined like Array.prototype.sort is, in terms of guarantees (like the callback function will be called at most once on which array element for 'every' and 'some' for instance) rather than with an algorithm. I have no strong opinion on how to name them. Maybe adding an N (for Non-deterministic) at the end of the equivalent method (Array.prototype.forEachN, Array.prototype.mapN, etc.)? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Extending standard library of arrays
As a sidenote, but with regard to forEach, can someone point me to some documentation that explains why the generic form of forEach doesn't work with objects (the use case has sufficient history) Rick -- Sent from my Palm Pre On Jul 10, 2011 6:42 PM, David Bruant lt;david.bru...@labri.frgt; wrote: Le 10/07/2011 22:46, Dmitry A. Soshnikov a écritnbsp;: Here I put some extensions for arrays standard library (separated from this thread: https://mail.mozilla.org/pipermail/es-discuss/2011-July/015856.html where Array.of and Array.from were considered). We can consider also the following (as a first step): - 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) // or Array.range(from, to) Array.seq(1, 5); // [1, 2, 3, 4, 5] - Array.build(n, fn) Array.build(5, function(index) index + 1); // [1, 2, 3, 4, 5]nbsp; - Array.min(array), Array.max(array) (can be implemented with Math.max/min and apply though) Array.min = (array) -gt; 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.fromArrays([a, b, c], [1, 2, 3]); // {a: 1, b: 2, c: 3} - Array.prototype.unique [1, 3, 2, 5, 5, 3].unique(); // [1, 3, 2, 5] Thus, all names of methods can be discussed. I like a lot all of these ideas, but I can't help thinking that they do not seem to be aligned with the initial ECMAScript array design which is that arrays are ECMAScript objects (which is very different from what we'd understand of array in C or lists in Erlang as you cite them). The question I ask for each of your Array.prototype ideas is how does it apply to non-dense arrays?. Creating a List or a DenseArray (or both?) type sounds to better capture your intentions (especially since you provided a link to Erlang list methods). It could inherit everything from Array.prototype for free. Actually, this could be implemented with proxies :-) Since we're suggesting array additions, I would be interested in trying to address one issue of forEach, map, every, some and filter. They all have a well-defined algorithm. Consequently, if the callback function has side-effects, these are deterministic. This, however, prevent efficient (parallelized, for instance) implementation. This is unfortunate since in a lot of cases, people don't do side-effect and would certainly trade the side-effect determinism guarantee for performance. Could it be considered to add non-deterministic versions of these functions? They would be defined like Array.prototype.sort is, in terms of guarantees (like the callback function will be called at most once on which array element for 'every' and 'some' for instance) rather than with an algorithm. I have no strong opinion on how to name them. Maybe adding an N (for Non-deterministic) at the end of the equivalent method (Array.prototype.forEachN, Array.prototype.mapN, etc.)? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Design principles for extending ES object abstractions
On Jul 10, 2011, at 3:02 PM, David Herman wrote: I'm not sure what Array.prototype methods would or wouldn't work on instances of SubArray. All of them. They are all generic. We're speaking too broadly here. It depends on what we want to work how. For example, .map can't magically know how to produce a SubArray as its result if that's how SubArray wants it to work. But what I'm actually more concerned about is the behavior of .length. Does the | semantics make .length work automagically the way it does for ordinary Array instances? Of course, since the thing on the right of | is a newly minted Array which has its own length. There's no issue here -- are you thinking of the other case (which I showed), Object.create([])? That's where length doesn't inherit. However, subarray instances have all the internal state and methods that make them true arrays so even if some of the inherited Array methods weren't generic they would still work. Including .length (which isn't a method, but YKWIM)? The | operator sets [[Prototype]] in the newborn-because-literally-expressions right operand, to the value of the left operand. So (proto | [1,2,3]) is an Array instance, no mystery or inheritance of Arrayness required. The trick as your SubArray example showed is not to lose the Array.prototype heritage -- proto ought to have Array.prototype on its proto-chain. 'length' is own in each Array instance, maintained by [[Put]] in ES1-3, [[DefineOwnProperty]] in ES5. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Design principles for extending ES object abstractions
On Jul 10, 2011, at 3:54 PM, Brendan Eich wrote: On Jul 10, 2011, at 3:02 PM, David Herman wrote: I'm not sure what Array.prototype methods would or wouldn't work on instances of SubArray. All of them. They are all generic. We're speaking too broadly here. It depends on what we want to work how. For example, .map can't magically know how to produce a SubArray as its result if that's how SubArray wants it to work. This is the real concern, I believe. The Array methods (all generic in that they take array-like |this| -- at least one is Array-specific in argument handling: concat) that return a new array always make an instance of Array. Alex Russell brought up the idea of extending these array-producing methods to call a user-defined constructor. We discussed doing it by reflecting on this.constructor, but that is not a compatible change: people today call Array.prototype.slice.call(arguments) intending to get an Array instance whose elements come from the arguments object. It would be wrong to change this code to return a new Object, but that's what reflecting on this.constructor would do, because: js function f(){return arguments.constructor} js f() function Object() {[native code]} So we have two choices: 1. Duplicate the array methods with new twins mutated to reflect on this.constructor -- this is ugly and bloaty, even if we can segregate the methods so as to avoid mangling the twins' names. 2. Add a new protocol, perhaps enabled by setting a well-known private name object (i.e., a unique public name), denoted it kResultConstructor, so that the methods can detect something like this[kResultConstructor]. (2) adds a bit of runtime cost to the methods, which are not super-optimized in many way in today's engines. Not sure that hurts it much, compared to (1). Do modules help us make a better, less bloaty form of (1)? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array generation
range.__doc__ 'range([start,] stop[, step]) - range object\n\nReturns a virtual sequence of numbers from start to stop by step.' [i for i in range(10)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [i for i in range(10, 20)] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] [i for i in range(10, 20, 2)] [10, 12, 14, 16, 18] It seems to me we want * range(end), range(start, end), range(start, end, step) as in Python 3, a generator. function range(...args) { const start = (args.length == 1) ? 0 : Number.toInteger(args[0]); const end = Number.toInteger((args.length 1) ? args[1] : args[0]); const step = (args.length 2) ? Number.toInteger(args[2]) : 1; if (Number.isNaN(start) || Number.isNaN(end) || Number.isNaN(step)) { throw new TypeError(...); } for (let i = start; i != end; i += step) { yield i; } } * a way to take an iterator I and exhaust it to build an array: [x for x of I] is the comprehension form (note the paren-free for-of head). A functional form per Allen's principle would be helpful some of the time: Array.fromIterator or Array.exhaust? * a standard array element-key-only-and-as-integral-index (*not* string) and elements-only iterators: for i of indexes(array), for v of elements(array). See http://wiki.ecmascript.org/doku.php?id=harmony:iterators for more on for-of. /be On Jul 10, 2011, at 1:52 PM, Rick Waldron wrote: David, I like the way you paint your bike sheds. Array.range() (or similarly functional but differently named) is definitely another one of those oft-rerolled solutions. Rick On Sun, Jul 10, 2011 at 4:23 PM, David Herman dher...@mozilla.com wrote: So from this viewpoint (and regarding that example with squares), it's good to have also `Array.seq(from, to)` method (the name is taken from Erlang, I just frequently uses lists:seq(from, to) there): bikeshedArray.range seems like an intuitive name as well./bikeshed Array.seq(1, 5).map((x) - x * x); [1, 4, 9, 16, 25] This pattern (integer range immediately followed by map) is so common that many Schemes have a more general function that fuses the two traversals, sometimes called build-list or list-tabulate: Array.build(n, f) ~~~ [f(0), ..., f(n-1)] Another common and useful fusion of two traversals that's in many Schemes is map-filter or filter-map: a.filterMap(f) ~~~ [res for [i,x] of items(a) let (res = f(x, i)) if (res !== void 0)] I rather arbitrarily chose to accept both null and undefined here as way to say no element -- a reasonable alternative would be to accept *only* undefined as no element. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: using Private name objects for declarative property definition.
On Jul 10, 2011, at 10:54 AM, Allen Wirfs-Brock wrote: However, arguably Array.isArray really should have been Array.prototype.isArray. We treated as a case 2 from above. May we really didn't need to, but that's water over dam. I don't think we should use it as precedent for more greenfield situations. First thought: Crock sold us on reformed Number.is{NaN,Finite} along with new Numer.isInteger. We can do both and correct course for the long run, perhaps: Array.isArray and Array.prototype.isArray. But first we should settle the data property vs. method issue. yes. I wonder if isArray and isInteger are different kinds of categorizations (class based vs value based) that perhaps should have distinct naming conventions. The isFoo predicate convention is used variously in other languages. Kind of like foop in Lisps. I would not tax name length just to distinguish these cases, or others (ontology fanatics will soon be splitting sub-cases of value-based). But f the method implementation is simply going to be return true or return false why do yo need to call it at all? The general case is an optional method, a notification hook call-out or some such. You're right that for object detection the method call seems a waste. We could have made Function isGenerator a non-writable, non-configurable, and non-enumerable boolean-valued data property. But, then it would be an instance property, which burns storage (the shape or hidden class sharing is not the issue, the true or false value slot is); or else an accessor on Function.prototype, which is about as costly as a method in implementations. Users testing it would not have to write (), your point. That wins. But otherwise it's a wash. Why not a non-writable,non-enumerable non-configurable data property on Function.prototype. We're talking about isGenerator, right? There is no Generator constructor, no shadowing opportunity. Function can create a generator if yield occurs in the body string. Here's a reason to prefer a method, at least one method per feature: you can then object-detect the method without having to autoconf-style try/catch a generator in eval or Function. Just if (Function.prototype.isGenerator) or (shorter, works as noted) if (Function.isGenerator) to guard code (perhaps a script injection) that depends on generator support. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: module exports
According to the module grammar, the following is valid: 691module car { function startCar() {} module engine { function start() {} } export {start:startCar} from engine; } It seems like there would be issues with exporting module elements after the module has been defined. I don't see any conflicts with the code you wrote, but it does contain a linking error, because the car module doesn't have access to the unexported start function. Maybe you intended: module car { export function startCar() { } module engine { export function start() { } } export { start: startCar } from engine; } In this case, you have a conflict, because the car module is attempting to create two different exports with the same name. This is an early error. Also, what is the behavior of aliasing over existing Identifiers? Would the compiler fail or would behavior be the 'last' Identifier wins? Early error. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss