Javascript Language feature Idea
Since Array inherits from Object, it can have any key, including the key "-1". So something like list[-1] would break compatibility as users can now already assign values to the index -1.
If you want a short way to access the last element, it should probably be a function in the Array prototype. Something like list.last().
, Sander
2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>:
Since Array inherits from Object, it can have any key, including the key "-1". So something like list[-1] would break compatibility as users can now already assign values to the index -1. If you want a short way to access the last element, it should probably be a function in the Array prototype. Something like list.last(). Regards, Sander 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > In other programming languages such as python, you can specify the last > element of a list with "list[-1]" but in javascript you have to do > "list[list.length-1]". Is there maybe a way to make this feature in > javascript? > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160122/dbf5909c/attachment.html>
Don't forget that Array#slice() can accept negative indexes. E.g.:
['a', 'b', 'c', 'd'].slice(-1) [ 'd' ]
Which is nearly as terse as any Array.prototype addition would be, and I think it's at least expressive enough to alleviate the need for one.
Don't forget that Array#slice() can accept negative indexes. E.g.: > ['a', 'b', 'c', 'd'].slice(-1) [ 'd' ] Which is nearly as terse as any Array.prototype addition would be, and I think it's at least expressive enough to alleviate the need for one. On Fri, Jan 22, 2016 at 12:59 PM, Sander Deryckere <sanderd17 at gmail.com> wrote: > Since Array inherits from Object, it can have any key, including the key > "-1". So something like list[-1] would break compatibility as users can now > already assign values to the index -1. > > If you want a short way to access the last element, it should probably be > a function in the Array prototype. Something like list.last(). > > Regards, > Sander > > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > >> In other programming languages such as python, you can specify the last >> element of a list with "list[-1]" but in javascript you have to do >> "list[list.length-1]". Is there maybe a way to make this feature in >> javascript? >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -- Jeremy Martin 661.312.3853 http://devsmash.com @jmar777 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160122/d99e7f11/attachment.html>
On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> wrote:
In other programming languages such as python, you can specify the last element of a list with "list[-1]" but in javascript you have to do "list[list.length-1]". Is there maybe a way to make this feature in javascript?
This could be a good addition, although slice
may work as well. This has
been discussed previously as well in the last 4-5 years. In addition with
non-enumerable properties you can just monkey-patch Array.prototype
with
the peek
or last
method. I guess approach when some library forces some
method to widely used, can be a good candidate for adding it to the spec
(this how it was with Function.prototype.bind
, e.g., although today
monkey-patching is a bad practice of course).
In addition, you can monkey-patch just -1
, and other indexes, e.g. a gist
from 5 years old, when a similar topic was proposed here:
gist.github.com/DmitrySoshnikov/984921
Dmitry
On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> wrote: > In other programming languages such as python, you can specify the last > element of a list with "list[-1]" but in javascript you have to do > "list[list.length-1]". Is there maybe a way to make this feature in > javascript? > > This could be a good addition, although `slice` may work as well. This has been discussed previously as well in the last 4-5 years. In addition with non-enumerable properties you can just monkey-patch `Array.prototype` with the `peek` or `last` method. I guess approach when some library forces some method to widely used, can be a good candidate for adding it to the spec (this how it was with `Function.prototype.bind`, e.g., although today monkey-patching is a bad practice of course). In addition, you can monkey-patch just `-1`, and other indexes, e.g. a gist from 5 years old, when a similar topic was proposed here: https://gist.github.com/DmitrySoshnikov/984921 Dmitry -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160122/587534fb/attachment-0001.html>
Personally I prefer a well known symbol for marking you are grabbing from
the end of the list rather than this wrapping behavior like D (
dlang.org/spec/arrays.html#array-length ). That said I think
.last
is more reasonable than changing prototypes.
Personally I prefer a well known symbol for marking you are grabbing from the end of the list rather than this wrapping behavior like D ( https://dlang.org/spec/arrays.html#array-length ). That said I think `.last` is more reasonable than changing prototypes. On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov < dmitry.soshnikov at gmail.com> wrote: > On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> wrote: > >> In other programming languages such as python, you can specify the last >> element of a list with "list[-1]" but in javascript you have to do >> "list[list.length-1]". Is there maybe a way to make this feature in >> javascript? >> >> > This could be a good addition, although `slice` may work as well. This has > been discussed previously as well in the last 4-5 years. In addition with > non-enumerable properties you can just monkey-patch `Array.prototype` with > the `peek` or `last` method. I guess approach when some library forces some > method to widely used, can be a good candidate for adding it to the spec > (this how it was with `Function.prototype.bind`, e.g., although today > monkey-patching is a bad practice of course). > > In addition, you can monkey-patch just `-1`, and other indexes, e.g. a > gist from 5 years old, when a similar topic was proposed here: > https://gist.github.com/DmitrySoshnikov/984921 > > Dmitry > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160122/b5680ff0/attachment.html>
More cool stuff:
const arr = [1, 2, 3];
// Easy push
arr[] = 4; // => arr[arr.length];
// Easy s(p)lice
arr[begin, end];,
arr[begin,]; // => arr[begin, arr.length - 1];
arr[begin, end] = [1, 2, 3];
A terrible example (terrible because this should be done with WebGL shaders):
const image = [ /* Umbagajillion of RGBA pixels */ ];
function manipulate(rgba) {
rgba[0] += 10;
rgba[1] += 10;
rgba[2] += 10;
}
for (let i = 0; i < image.length / 4; i++) {
const begin = i * 4;
const end = begin + 4;
/*
In case easy s(p)lice doesn't actually Array.p.slice
and just creates a limited view of the array
without breaking reference
(image[begin, end] === image[begin, end])
*/
manipulate(image[begin, end]);
/*
In case easy s(p)lice does Array.p.slice
and creates a new array
(image[begin, end] !== image[begin, end])
*/
const pixel = image[begin, end];
manipulate(pixel);
image[begin, end] = pixel;
}
Edit: Fixed the typo @kdex pointed out. Thanks!
More cool stuff: ```javascript const arr = [1, 2, 3]; // Easy push arr[] = 4; // => arr[arr.length]; // Easy s(p)lice arr[begin, end];, arr[begin,]; // => arr[begin, arr.length]; arr[begin, end] = [1, 2, 3]; ``` A terrible example (terrible because this should be done with WebGL shaders): ```javascript const image = [ /* Umbagajillion of RGBA pixels */ ]; function manipulate(rgba) { rgba[0] += 10; rgba[1] += 10; rgba[2] += 10; } for (let i = 0; i < image.length / 4; i++) { const begin = i * 4; const end = begin + 4; /* In case easy s(p)lice doesn't actually Array.p.slice and just creates a limited view of the array without breaking reference (image[begin, end] === image[begin, end]) */ manipulate(image[begin, end]); /* In case easy s(p)lice does Array.p.slice and creates a new array (image[begin, end] !== image[begin, end]) */ const pixel = image[begin, end]; manipulate(pixel); image[begin, end] = pixel; } ``` -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160122/4d2904b0/attachment.html>
I really adore the slicing syntax. Just as a quick fix, though,
arr[begin,]; // => arr[begin, arr.length];
should obviously return arr[begin, arr.length - 1]
.
Honestly, I'm not too sure if the "easy push" syntax is particularly self- explanatory. There might be better alternatives.
I really adore the slicing syntax. Just as a quick fix, though, > arr[begin,]; // => arr[begin, arr.length]; should obviously return `arr[begin, arr.length - 1]`. Honestly, I'm not too sure if the "easy push" syntax is particularly self- explanatory. There might be better alternatives. On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > More cool stuff: > ```javascript > const arr = [1, 2, 3]; > > // Easy push > arr[] = 4; // => arr[arr.length]; > > // Easy s(p)lice > arr[begin, end];, > arr[begin,]; // => arr[begin, arr.length]; > arr[begin, end] = [1, 2, 3]; > ``` > > A terrible example (terrible because this should be done with WebGL > shaders): > ```javascript > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > function manipulate(rgba) { > rgba[0] += 10; > rgba[1] += 10; > rgba[2] += 10; > } > > for (let i = 0; i < image.length / 4; i++) { > const begin = i * 4; > const end = begin + 4; > > /* > In case easy s(p)lice doesn't actually Array.p.slice > and just creates a limited view of the array > without breaking reference > (image[begin, end] === image[begin, end]) > */ > manipulate(image[begin, end]); > > /* > In case easy s(p)lice does Array.p.slice > and creates a new array > (image[begin, end] !== image[begin, end]) > */ > const pixel = image[begin, end]; > manipulate(pixel); > image[begin, end] = pixel; > } > ```
Standardizing unused array keys breaks compatibility about as much as extending the prototype does, really. Users can already mangle with both.
The problems are a little more subtle, and yes, it would severely break backwards compatibility. Consider this example (accessing an element based on a computed index):
let a = [1, 2, 3];
let occurrence = a.indexOf(4);
a[occurrence];
Currently, this should result in undefined
. After your proposal, you could
introduce a potential bug into every program that accesses arrays using an
index computed with Array.prototype.indexOf
, since it would now return 3
.
Standardizing unused array keys breaks compatibility about as much as extending the prototype does, really. Users can already mangle with both. The problems are a little more subtle, and yes, it would severely break backwards compatibility. Consider this example (accessing an element based on a computed index): ```js let a = [1, 2, 3]; let occurrence = a.indexOf(4); a[occurrence]; ``` Currently, this should result in `undefined`. After your proposal, you could introduce a potential bug into every program that accesses arrays using an index computed with `Array.prototype.indexOf`, since it would now return `3`. On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote: > Since Array inherits from Object, it can have any key, including the key > "-1". So something like list[-1] would break compatibility as users can now > already assign values to the index -1. > > If you want a short way to access the last element, it should probably be a > function in the Array prototype. Something like list.last(). > > Regards, > Sander > > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > > In other programming languages such as python, you can specify the last > > element of a list with "list[-1]" but in javascript you have to do > > "list[list.length-1]". Is there maybe a way to make this feature in > > javascript? > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss
Interesting! More pedestrian, it would be nice to finally have a version of splice that doesn't create a new other Array as a side effect.
Interesting! More pedestrian, it would be nice to finally have a version of splice that doesn't create a new other Array as a side effect. > On Jan 22, 2016, at 13:00, kdex <kdex at kdex.de> wrote: > > I really adore the slicing syntax. Just as a quick fix, though, >> arr[begin,]; // => arr[begin, arr.length]; > should obviously return `arr[begin, arr.length - 1]`. > > Honestly, I'm not too sure if the "easy push" syntax is particularly self- > explanatory. There might be better alternatives. > >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: >> More cool stuff: >> ```javascript >> const arr = [1, 2, 3]; >> >> // Easy push >> arr[] = 4; // => arr[arr.length]; >> >> // Easy s(p)lice >> arr[begin, end];, >> arr[begin,]; // => arr[begin, arr.length]; >> arr[begin, end] = [1, 2, 3]; >> ``` >> >> A terrible example (terrible because this should be done with WebGL >> shaders): >> ```javascript >> const image = [ /* Umbagajillion of RGBA pixels */ ]; >> >> function manipulate(rgba) { >> rgba[0] += 10; >> rgba[1] += 10; >> rgba[2] += 10; >> } >> >> for (let i = 0; i < image.length / 4; i++) { >> const begin = i * 4; >> const end = begin + 4; >> >> /* >> In case easy s(p)lice doesn't actually Array.p.slice >> and just creates a limited view of the array >> without breaking reference >> (image[begin, end] === image[begin, end]) >> */ >> manipulate(image[begin, end]); >> >> /* >> In case easy s(p)lice does Array.p.slice >> and creates a new array >> (image[begin, end] !== image[begin, end]) >> */ >> const pixel = image[begin, end]; >> manipulate(pixel); >> image[begin, end] = pixel; >> } >> ``` > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
The "easy push" syntax exists in PHP so it will be familiar to at least some people. The slicey thing was also being discussed for PHP. I don't know if it landed or got dropped.
The "easy push" syntax exists in PHP so it will be familiar to at least some people. The slicey thing was also being discussed for PHP. I don't know if it landed or got dropped. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160123/c33c18c7/attachment.html>
Using a well-known symbol to access an array's last element is probably wiser than a typical method or property:
let a = [0, 1, 2, 3]; console.log( a[Symbol.last] === 3 /* true */ );
There're obviously instances where authors have extended Array prototypes with "last" methods or properties, but we can't guarantee they'd all work the same. For instance, assume there are some implementations that skip undefined values:
var a = [0, 1, 2, undefined, undefined]; Array.prototype.last = function(){ return this[this.length - 1]; }; /** One that skips undefined values */ Array.prototype.last = function(){ var offset = 1; while(offset < this.length && undefined === this[this.length - offset]) ++offset; return this[this.length - offset]; }
These discrepancies are subtle, but have the potential to break backwards compatibility.
Using a well-known symbol eliminates the potential for conflict. Furthermore, it also offers an opportunity to complement any iterable object's ability to synthesise array-like behaviour. For instance, it enables iterables to also return the last object in their list of values:
let pruebas = { data: ["Probando", "la", "mierda", "esta", undefined],
Symbol.iterator{ /* Stuff with .data / }, Symbol.last{ /* Stuff to skip undefined values or whatever */ let offset = 1; let data = this.data; while( offset < data.length && undefined === data[data.length - offset] ) ++offset; return data[data.length - offset]; } }
Using a well-known symbol to access an array's last element is probably wiser than a typical method or property: let a = [0, 1, 2, 3]; console.log( a[Symbol.last] === 3 /* true */ ); There're obviously instances where authors have extended Array prototypes with "last" methods or properties, but we can't guarantee they'd all work the same. For instance, assume there are some implementations that skip undefined values: var a = [0, 1, 2, undefined, undefined]; Array.prototype.last = function(){ return this[this.length - 1]; }; /** One that skips undefined values */ Array.prototype.last = function(){ var offset = 1; while(offset < this.length && undefined === this[this.length - offset]) ++offset; return this[this.length - offset]; } These discrepancies are subtle, but have the potential to break backwards compatibility. Using a well-known symbol eliminates the potential for conflict. Furthermore, it also offers an opportunity to complement any iterable object's ability to synthesise array-like behaviour. For instance, it enables iterables to also return the last object in their list of values: let pruebas = { data: ["Probando", "la", "mierda", "esta", undefined], [Symbol.iterator](){ /* Stuff with .data */ }, [Symbol.last](){ /** Stuff to skip undefined values or whatever */ let offset = 1; let data = this.data; while( offset < data.length && undefined === data[data.length - offset] ) ++offset; return data[data.length - offset]; } } On 23 January 2016 at 08:36, <es-discuss-request at mozilla.org> wrote: > Send es-discuss mailing list submissions to > es-discuss at mozilla.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.mozilla.org/listinfo/es-discuss > or, via email, send a message with subject or body 'help' to > es-discuss-request at mozilla.org > > You can reach the person managing the list at > es-discuss-owner at mozilla.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of es-discuss digest..." > > Today's Topics: > > 1. Re: Javascript Language feature Idea (Bradley Meck) > 2. Re: Re: Javascript Language feature Idea (Alican ?ubuk?uo?lu) > 3. Re: Javascript Language feature Idea (kdex) > 4. Re: Javascript Language feature Idea (kdex) > 5. Re: Javascript Language feature Idea (Benoit Marchant) > > > ---------- Forwarded message ---------- > From: Bradley Meck <bradley.meck at gmail.com> > To: Dmitry Soshnikov <dmitry.soshnikov at gmail.com> > Cc: es-discuss <es-discuss at mozilla.org> > Date: Fri, 22 Jan 2016 13:51:54 -0600 > Subject: Re: Javascript Language feature Idea > Personally I prefer a well known symbol for marking you are grabbing from > the end of the list rather than this wrapping behavior like D ( > https://dlang.org/spec/arrays.html#array-length ). That said I think > `.last` is more reasonable than changing prototypes. > > On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov < > dmitry.soshnikov at gmail.com> wrote: > >> On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> wrote: >> >>> In other programming languages such as python, you can specify the last >>> element of a list with "list[-1]" but in javascript you have to do >>> "list[list.length-1]". Is there maybe a way to make this feature in >>> javascript? >>> >>> >> This could be a good addition, although `slice` may work as well. This >> has been discussed previously as well in the last 4-5 years. In addition >> with non-enumerable properties you can just monkey-patch `Array.prototype` >> with the `peek` or `last` method. I guess approach when some library forces >> some method to widely used, can be a good candidate for adding it to the >> spec (this how it was with `Function.prototype.bind`, e.g., although today >> monkey-patching is a bad practice of course). >> >> In addition, you can monkey-patch just `-1`, and other indexes, e.g. a >> gist from 5 years old, when a similar topic was proposed here: >> https://gist.github.com/DmitrySoshnikov/984921 >> >> Dmitry >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > > ---------- Forwarded message ---------- > From: "Alican Çubukçuoğlu" <alicancubukcuoglu at gmail.com> > To: es-discuss at mozilla.org > Cc: > Date: Fri, 22 Jan 2016 22:32:42 +0200 > Subject: Re: Re: Javascript Language feature Idea > More cool stuff: > ```javascript > const arr = [1, 2, 3]; > > // Easy push > arr[] = 4; // => arr[arr.length]; > > // Easy s(p)lice > arr[begin, end];, > arr[begin,]; // => arr[begin, arr.length]; > arr[begin, end] = [1, 2, 3]; > ``` > > A terrible example (terrible because this should be done with WebGL > shaders): > ```javascript > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > function manipulate(rgba) { > rgba[0] += 10; > rgba[1] += 10; > rgba[2] += 10; > } > > for (let i = 0; i < image.length / 4; i++) { > const begin = i * 4; > const end = begin + 4; > > /* > In case easy s(p)lice doesn't actually Array.p.slice > and just creates a limited view of the array > without breaking reference > (image[begin, end] === image[begin, end]) > */ > manipulate(image[begin, end]); > > /* > In case easy s(p)lice does Array.p.slice > and creates a new array > (image[begin, end] !== image[begin, end]) > */ > const pixel = image[begin, end]; > manipulate(pixel); > image[begin, end] = pixel; > } > ``` > > > ---------- Forwarded message ---------- > From: kdex <kdex at kdex.de> > To: es-discuss at mozilla.org > Cc: > Date: Fri, 22 Jan 2016 22:00:01 +0100 > Subject: Re: Javascript Language feature Idea > I really adore the slicing syntax. Just as a quick fix, though, > > arr[begin,]; // => arr[begin, arr.length]; > should obviously return `arr[begin, arr.length - 1]`. > > Honestly, I'm not too sure if the "easy push" syntax is particularly self- > explanatory. There might be better alternatives. > > On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > > More cool stuff: > > ```javascript > > const arr = [1, 2, 3]; > > > > // Easy push > > arr[] = 4; // => arr[arr.length]; > > > > // Easy s(p)lice > > arr[begin, end];, > > arr[begin,]; // => arr[begin, arr.length]; > > arr[begin, end] = [1, 2, 3]; > > ``` > > > > A terrible example (terrible because this should be done with WebGL > > shaders): > > ```javascript > > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > > > function manipulate(rgba) { > > rgba[0] += 10; > > rgba[1] += 10; > > rgba[2] += 10; > > } > > > > for (let i = 0; i < image.length / 4; i++) { > > const begin = i * 4; > > const end = begin + 4; > > > > /* > > In case easy s(p)lice doesn't actually Array.p.slice > > and just creates a limited view of the array > > without breaking reference > > (image[begin, end] === image[begin, end]) > > */ > > manipulate(image[begin, end]); > > > > /* > > In case easy s(p)lice does Array.p.slice > > and creates a new array > > (image[begin, end] !== image[begin, end]) > > */ > > const pixel = image[begin, end]; > > manipulate(pixel); > > image[begin, end] = pixel; > > } > > ``` > > > > > > ---------- Forwarded message ---------- > From: kdex <kdex at kdex.de> > To: es-discuss at mozilla.org > Cc: > Date: Fri, 22 Jan 2016 22:14:20 +0100 > Subject: Re: Javascript Language feature Idea > Standardizing unused array keys breaks compatibility about as much as > extending the prototype does, really. Users can already mangle with both. > > The problems are a little more subtle, and yes, it would severely break > backwards compatibility. Consider this example (accessing an element based > on > a computed index): > > ```js > let a = [1, 2, 3]; > let occurrence = a.indexOf(4); > a[occurrence]; > ``` > > Currently, this should result in `undefined`. After your proposal, you > could > introduce a potential bug into every program that accesses arrays using an > index computed with `Array.prototype.indexOf`, since it would now return > `3`. > > On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote: > > Since Array inherits from Object, it can have any key, including the key > > "-1". So something like list[-1] would break compatibility as users can > now > > already assign values to the index -1. > > > > If you want a short way to access the last element, it should probably > be a > > function in the Array prototype. Something like list.last(). > > > > Regards, > > Sander > > > > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > > > In other programming languages such as python, you can specify the last > > > element of a list with "list[-1]" but in javascript you have to do > > > "list[list.length-1]". Is there maybe a way to make this feature in > > > javascript? > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > ---------- Forwarded message ---------- > From: Benoit Marchant <marchant at mac.com> > To: kdex <kdex at kdex.de> > Cc: es-discuss at mozilla.org > Date: Fri, 22 Jan 2016 13:35:55 -0800 > Subject: Re: Javascript Language feature Idea > Interesting! More pedestrian, it would be nice to finally have a version > of splice that doesn't create a new other Array as a side effect. > > > On Jan 22, 2016, at 13:00, kdex <kdex at kdex.de> wrote: > > > > I really adore the slicing syntax. Just as a quick fix, though, > >> arr[begin,]; // => arr[begin, arr.length]; > > should obviously return `arr[begin, arr.length - 1]`. > > > > Honestly, I'm not too sure if the "easy push" syntax is particularly > self- > > explanatory. There might be better alternatives. > > > >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > >> More cool stuff: > >> ```javascript > >> const arr = [1, 2, 3]; > >> > >> // Easy push > >> arr[] = 4; // => arr[arr.length]; > >> > >> // Easy s(p)lice > >> arr[begin, end];, > >> arr[begin,]; // => arr[begin, arr.length]; > >> arr[begin, end] = [1, 2, 3]; > >> ``` > >> > >> A terrible example (terrible because this should be done with WebGL > >> shaders): > >> ```javascript > >> const image = [ /* Umbagajillion of RGBA pixels */ ]; > >> > >> function manipulate(rgba) { > >> rgba[0] += 10; > >> rgba[1] += 10; > >> rgba[2] += 10; > >> } > >> > >> for (let i = 0; i < image.length / 4; i++) { > >> const begin = i * 4; > >> const end = begin + 4; > >> > >> /* > >> In case easy s(p)lice doesn't actually Array.p.slice > >> and just creates a limited view of the array > >> without breaking reference > >> (image[begin, end] === image[begin, end]) > >> */ > >> manipulate(image[begin, end]); > >> > >> /* > >> In case easy s(p)lice does Array.p.slice > >> and creates a new array > >> (image[begin, end] !== image[begin, end]) > >> */ > >> const pixel = image[begin, end]; > >> manipulate(pixel); > >> image[begin, end] = pixel; > >> } > >> ``` > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160123/d6033eb0/attachment-0001.html>
While John's solution doesn't run into conflicts with downward compatibility, it still wouldn't solve the problem of getting the n-th last element of an array. To solve this, it'd probably be a good idea to extend the prototype and specify a parameter, defaulting to 1.
Array.prototype.last
doesn't show up a terrible lot on search engines,
either, so we might actually be lucky here. Other than that, I also found two
more threads[1][2] on the EcmaScript discussion archives that propose it.
They might be worth a read.
[1] esdiscuss.org/topic/array-prototype-last [2] esdiscuss.org/topic/proposal
While John's solution doesn't run into conflicts with downward compatibility, it still wouldn't solve the problem of getting the n-th last element of an array. To solve this, it'd probably be a good idea to extend the prototype and specify a parameter, defaulting to 1. `Array.prototype.last` doesn't show up a terrible lot on search engines, either, so we might actually be lucky here. Other than that, I also found two more threads[1][2] on the EcmaScript discussion archives that propose it. They might be worth a read. [1] https://esdiscuss.org/topic/array-prototype-last [2] https://esdiscuss.org/topic/proposal-array-prototype-last On Samstag, 23. Januar 2016 15:44:19 CET John Gardner wrote: > Using a well-known symbol to access an array's last element is probably > wiser than a typical method or property: > > let a = [0, 1, 2, 3]; > console.log( > a[Symbol.last] === 3 > /* true */ > ); > > There're obviously instances where authors have extended Array prototypes > with "last" methods or properties, but we can't guarantee they'd all work > the same. For instance, assume there are some implementations that skip > undefined values: > > var a = [0, 1, 2, undefined, undefined]; > Array.prototype.last = function(){ > return this[this.length - 1]; > }; > /** One that skips undefined values */ > Array.prototype.last = function(){ > var offset = 1; > while(offset < this.length && undefined === this[this.length - offset]) > ++offset; > return this[this.length - offset]; > } > > These discrepancies are subtle, but have the potential to break backwards > compatibility. > > Using a well-known symbol eliminates the potential for conflict. > Furthermore, it also offers an opportunity to complement any iterable > object's ability to synthesise array-like behaviour. For instance, it > enables iterables to also return the last object in their list of values: > > let pruebas = { > data: ["Probando", "la", "mierda", "esta", undefined], > > [Symbol.iterator](){ > /* Stuff with .data */ > }, > [Symbol.last](){ > /** Stuff to skip undefined values or whatever */ > let offset = 1; > let data = this.data; > while( > offset < data.length && > undefined === data[data.length - offset] > ) > ++offset; > return data[data.length - offset]; > } > } > > On 23 January 2016 at 08:36, <es-discuss-request at mozilla.org> wrote: > > Send es-discuss mailing list submissions to > > > > es-discuss at mozilla.org > > > > To subscribe or unsubscribe via the World Wide Web, visit > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > or, via email, send a message with subject or body 'help' to > > > > es-discuss-request at mozilla.org > > > > You can reach the person managing the list at > > > > es-discuss-owner at mozilla.org > > > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of es-discuss digest..." > > > > Today's Topics: > > 1. Re: Javascript Language feature Idea (Bradley Meck) > > 2. Re: Re: Javascript Language feature Idea (Alican ?ubuk?uo?lu) > > 3. Re: Javascript Language feature Idea (kdex) > > 4. Re: Javascript Language feature Idea (kdex) > > 5. Re: Javascript Language feature Idea (Benoit Marchant) > > > > ---------- Forwarded message ---------- > > From: Bradley Meck <bradley.meck at gmail.com> > > To: Dmitry Soshnikov <dmitry.soshnikov at gmail.com> > > Cc: es-discuss <es-discuss at mozilla.org> > > Date: Fri, 22 Jan 2016 13:51:54 -0600 > > Subject: Re: Javascript Language feature Idea > > Personally I prefer a well known symbol for marking you are grabbing from > > the end of the list rather than this wrapping behavior like D ( > > https://dlang.org/spec/arrays.html#array-length ). That said I think > > `.last` is more reasonable than changing prototypes. > > > > On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov < > > > > dmitry.soshnikov at gmail.com> wrote: > >> On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> wrote: > >>> In other programming languages such as python, you can specify the last > >>> element of a list with "list[-1]" but in javascript you have to do > >>> "list[list.length-1]". Is there maybe a way to make this feature in > >>> javascript? > >> > >> This could be a good addition, although `slice` may work as well. This > >> has been discussed previously as well in the last 4-5 years. In addition > >> with non-enumerable properties you can just monkey-patch > >> `Array.prototype` > >> with the `peek` or `last` method. I guess approach when some library > >> forces > >> some method to widely used, can be a good candidate for adding it to the > >> spec (this how it was with `Function.prototype.bind`, e.g., although > >> today > >> monkey-patching is a bad practice of course). > >> > >> In addition, you can monkey-patch just `-1`, and other indexes, e.g. a > >> gist from 5 years old, when a similar topic was proposed here: > >> https://gist.github.com/DmitrySoshnikov/984921 > >> > >> Dmitry > >> > >> _______________________________________________ > >> es-discuss mailing list > >> es-discuss at mozilla.org > >> https://mail.mozilla.org/listinfo/es-discuss > > > > ---------- Forwarded message ---------- > > From: "Alican Çubukçuoğlu" <alicancubukcuoglu at gmail.com> > > To: es-discuss at mozilla.org > > Cc: > > Date: Fri, 22 Jan 2016 22:32:42 +0200 > > Subject: Re: Re: Javascript Language feature Idea > > More cool stuff: > > ```javascript > > const arr = [1, 2, 3]; > > > > // Easy push > > arr[] = 4; // => arr[arr.length]; > > > > // Easy s(p)lice > > arr[begin, end];, > > arr[begin,]; // => arr[begin, arr.length]; > > arr[begin, end] = [1, 2, 3]; > > ``` > > > > A terrible example (terrible because this should be done with WebGL > > shaders): > > ```javascript > > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > > > function manipulate(rgba) { > > > > rgba[0] += 10; > > rgba[1] += 10; > > rgba[2] += 10; > > > > } > > > > for (let i = 0; i < image.length / 4; i++) { > > > > const begin = i * 4; > > const end = begin + 4; > > > > /* > > > > In case easy s(p)lice doesn't actually Array.p.slice > > and just creates a limited view of the array > > without breaking reference > > (image[begin, end] === image[begin, end]) > > > > */ > > manipulate(image[begin, end]); > > > > /* > > > > In case easy s(p)lice does Array.p.slice > > and creates a new array > > (image[begin, end] !== image[begin, end]) > > > > */ > > const pixel = image[begin, end]; > > manipulate(pixel); > > image[begin, end] = pixel; > > > > } > > ``` > > > > > > ---------- Forwarded message ---------- > > From: kdex <kdex at kdex.de> > > To: es-discuss at mozilla.org > > Cc: > > Date: Fri, 22 Jan 2016 22:00:01 +0100 > > Subject: Re: Javascript Language feature Idea > > I really adore the slicing syntax. Just as a quick fix, though, > > > > > arr[begin,]; // => arr[begin, arr.length]; > > > > should obviously return `arr[begin, arr.length - 1]`. > > > > Honestly, I'm not too sure if the "easy push" syntax is particularly self- > > explanatory. There might be better alternatives. > > > > On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > > > More cool stuff: > > > ```javascript > > > const arr = [1, 2, 3]; > > > > > > // Easy push > > > arr[] = 4; // => arr[arr.length]; > > > > > > // Easy s(p)lice > > > arr[begin, end];, > > > arr[begin,]; // => arr[begin, arr.length]; > > > arr[begin, end] = [1, 2, 3]; > > > ``` > > > > > > A terrible example (terrible because this should be done with WebGL > > > shaders): > > > ```javascript > > > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > > > > > function manipulate(rgba) { > > > > > > rgba[0] += 10; > > > rgba[1] += 10; > > > rgba[2] += 10; > > > > > > } > > > > > > for (let i = 0; i < image.length / 4; i++) { > > > > > > const begin = i * 4; > > > const end = begin + 4; > > > > > > /* > > > > > > In case easy s(p)lice doesn't actually Array.p.slice > > > and just creates a limited view of the array > > > without breaking reference > > > (image[begin, end] === image[begin, end]) > > > > > > */ > > > manipulate(image[begin, end]); > > > > > > /* > > > > > > In case easy s(p)lice does Array.p.slice > > > and creates a new array > > > (image[begin, end] !== image[begin, end]) > > > > > > */ > > > const pixel = image[begin, end]; > > > manipulate(pixel); > > > image[begin, end] = pixel; > > > > > > } > > > ``` > > > > ---------- Forwarded message ---------- > > From: kdex <kdex at kdex.de> > > To: es-discuss at mozilla.org > > Cc: > > Date: Fri, 22 Jan 2016 22:14:20 +0100 > > Subject: Re: Javascript Language feature Idea > > Standardizing unused array keys breaks compatibility about as much as > > extending the prototype does, really. Users can already mangle with both. > > > > The problems are a little more subtle, and yes, it would severely break > > backwards compatibility. Consider this example (accessing an element based > > on > > a computed index): > > > > ```js > > let a = [1, 2, 3]; > > let occurrence = a.indexOf(4); > > a[occurrence]; > > ``` > > > > Currently, this should result in `undefined`. After your proposal, you > > could > > introduce a potential bug into every program that accesses arrays using an > > index computed with `Array.prototype.indexOf`, since it would now return > > `3`. > > > > On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote: > > > Since Array inherits from Object, it can have any key, including the key > > > "-1". So something like list[-1] would break compatibility as users can > > > > now > > > > > already assign values to the index -1. > > > > > > If you want a short way to access the last element, it should probably > > > > be a > > > > > function in the Array prototype. Something like list.last(). > > > > > > Regards, > > > Sander > > > > > > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > > > > In other programming languages such as python, you can specify the > > > > last > > > > element of a list with "list[-1]" but in javascript you have to do > > > > "list[list.length-1]". Is there maybe a way to make this feature in > > > > javascript? > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > ---------- Forwarded message ---------- > > From: Benoit Marchant <marchant at mac.com> > > To: kdex <kdex at kdex.de> > > Cc: es-discuss at mozilla.org > > Date: Fri, 22 Jan 2016 13:35:55 -0800 > > Subject: Re: Javascript Language feature Idea > > Interesting! More pedestrian, it would be nice to finally have a version > > of splice that doesn't create a new other Array as a side effect. > > > > > On Jan 22, 2016, at 13:00, kdex <kdex at kdex.de> wrote: > > > > > > I really adore the slicing syntax. Just as a quick fix, though, > > > > > >> arr[begin,]; // => arr[begin, arr.length]; > > > > > > should obviously return `arr[begin, arr.length - 1]`. > > > > > > Honestly, I'm not too sure if the "easy push" syntax is particularly > > > > self- > > > > > explanatory. There might be better alternatives. > > > > > >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > > >> More cool stuff: > > >> ```javascript > > >> const arr = [1, 2, 3]; > > >> > > >> // Easy push > > >> arr[] = 4; // => arr[arr.length]; > > >> > > >> // Easy s(p)lice > > >> arr[begin, end];, > > >> arr[begin,]; // => arr[begin, arr.length]; > > >> arr[begin, end] = [1, 2, 3]; > > >> ``` > > >> > > >> A terrible example (terrible because this should be done with WebGL > > >> shaders): > > >> ```javascript > > >> const image = [ /* Umbagajillion of RGBA pixels */ ]; > > >> > > >> function manipulate(rgba) { > > >> > > >> rgba[0] += 10; > > >> rgba[1] += 10; > > >> rgba[2] += 10; > > >> > > >> } > > >> > > >> for (let i = 0; i < image.length / 4; i++) { > > >> > > >> const begin = i * 4; > > >> const end = begin + 4; > > >> > > >> /* > > >> > > >> In case easy s(p)lice doesn't actually Array.p.slice > > >> and just creates a limited view of the array > > >> without breaking reference > > >> (image[begin, end] === image[begin, end]) > > >> > > >> */ > > >> manipulate(image[begin, end]); > > >> > > >> /* > > >> > > >> In case easy s(p)lice does Array.p.slice > > >> and creates a new array > > >> (image[begin, end] !== image[begin, end]) > > >> > > >> */ > > >> const pixel = image[begin, end]; > > >> manipulate(pixel); > > >> image[begin, end] = pixel; > > >> > > >> } > > >> ``` > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org > > > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss
Is this what you're thinking?
Array.prototype.nth = function (n){ if(n < 0){ return this[this.length -n]; } else { return this[n]; } }
Thomas Foster
@thomasfoster96 Ph: +61477808008 thomasfoster.co
Is this what you're thinking? Array.prototype.nth = function (n){ if(n < 0){ return this[this.length -n]; } else { return this[n]; } } Thomas Foster @thomasfoster96 Ph: +61477808008 http://thomasfoster.co/ > On 23 Jan 2016, at 4:40 PM, kdex <kdex at kdex.de> wrote: > > While John's solution doesn't run into conflicts with downward compatibility, > it still wouldn't solve the problem of getting the n-th last element of an > array. To solve this, it'd probably be a good idea to extend the prototype and > specify a parameter, defaulting to 1. > > `Array.prototype.last` doesn't show up a terrible lot on search engines, > either, so we might actually be lucky here. Other than that, I also found two > more threads[1][2] on the EcmaScript discussion archives that propose it. > > They might be worth a read. > > [1] https://esdiscuss.org/topic/array-prototype-last > [2] https://esdiscuss.org/topic/proposal-array-prototype-last > >> On Samstag, 23. Januar 2016 15:44:19 CET John Gardner wrote: >> Using a well-known symbol to access an array's last element is probably >> wiser than a typical method or property: >> >> let a = [0, 1, 2, 3]; >> console.log( >> a[Symbol.last] === 3 >> /* true */ >> ); >> >> There're obviously instances where authors have extended Array prototypes >> with "last" methods or properties, but we can't guarantee they'd all work >> the same. For instance, assume there are some implementations that skip >> undefined values: >> >> var a = [0, 1, 2, undefined, undefined]; >> Array.prototype.last = function(){ >> return this[this.length - 1]; >> }; >> /** One that skips undefined values */ >> Array.prototype.last = function(){ >> var offset = 1; >> while(offset < this.length && undefined === this[this.length - offset]) >> ++offset; >> return this[this.length - offset]; >> } >> >> These discrepancies are subtle, but have the potential to break backwards >> compatibility. >> >> Using a well-known symbol eliminates the potential for conflict. >> Furthermore, it also offers an opportunity to complement any iterable >> object's ability to synthesise array-like behaviour. For instance, it >> enables iterables to also return the last object in their list of values: >> >> let pruebas = { >> data: ["Probando", "la", "mierda", "esta", undefined], >> >> [Symbol.iterator](){ >> /* Stuff with .data */ >> }, >> [Symbol.last](){ >> /** Stuff to skip undefined values or whatever */ >> let offset = 1; >> let data = this.data; >> while( >> offset < data.length && >> undefined === data[data.length - offset] >> ) >> ++offset; >> return data[data.length - offset]; >> } >> } >> >> O
I think Symbol.last seems like the best option so far, without breaking things.
I think Symbol.last seems like the best option so far, without breaking things. On Fri, Jan 22, 2016 at 8:44 PM, John Gardner <gardnerjohng at gmail.com> wrote: > Using a well-known symbol to access an array's last element is probably > wiser than a typical method or property: > > let a = [0, 1, 2, 3]; > console.log( > a[Symbol.last] === 3 > /* true */ > ); > > There're obviously instances where authors have extended Array prototypes > with "last" methods or properties, but we can't guarantee they'd all work > the same. For instance, assume there are some implementations that skip > undefined values: > > var a = [0, 1, 2, undefined, undefined]; > Array.prototype.last = function(){ > return this[this.length - 1]; > }; > /** One that skips undefined values */ > Array.prototype.last = function(){ > var offset = 1; > while(offset < this.length && undefined === this[this.length - offset]) > ++offset; > return this[this.length - offset]; > } > > These discrepancies are subtle, but have the potential to break backwards > compatibility. > > Using a well-known symbol eliminates the potential for conflict. > Furthermore, it also offers an opportunity to complement any iterable > object's ability to synthesise array-like behaviour. For instance, it > enables iterables to also return the last object in their list of values: > > let pruebas = { > data: ["Probando", "la", "mierda", "esta", undefined], > > [Symbol.iterator](){ > /* Stuff with .data */ > }, > [Symbol.last](){ > /** Stuff to skip undefined values or whatever */ > let offset = 1; > let data = this.data; > while( > offset < data.length && > undefined === data[data.length - offset] > ) > ++offset; > return data[data.length - offset]; > } > } > > > On 23 January 2016 at 08:36, <es-discuss-request at mozilla.org> wrote: >> >> Send es-discuss mailing list submissions to >> es-discuss at mozilla.org >> >> To subscribe or unsubscribe via the World Wide Web, visit >> https://mail.mozilla.org/listinfo/es-discuss >> or, via email, send a message with subject or body 'help' to >> es-discuss-request at mozilla.org >> >> You can reach the person managing the list at >> es-discuss-owner at mozilla.org >> >> When replying, please edit your Subject line so it is more specific >> than "Re: Contents of es-discuss digest..." >> >> Today's Topics: >> >> 1. Re: Javascript Language feature Idea (Bradley Meck) >> 2. Re: Re: Javascript Language feature Idea (Alican ?ubuk?uo?lu) >> 3. Re: Javascript Language feature Idea (kdex) >> 4. Re: Javascript Language feature Idea (kdex) >> 5. Re: Javascript Language feature Idea (Benoit Marchant) >> >> >> ---------- Forwarded message ---------- >> From: Bradley Meck <bradley.meck at gmail.com> >> To: Dmitry Soshnikov <dmitry.soshnikov at gmail.com> >> Cc: es-discuss <es-discuss at mozilla.org> >> Date: Fri, 22 Jan 2016 13:51:54 -0600 >> Subject: Re: Javascript Language feature Idea >> Personally I prefer a well known symbol for marking you are grabbing from >> the end of the list rather than this wrapping behavior like D ( >> https://dlang.org/spec/arrays.html#array-length ). That said I think `.last` >> is more reasonable than changing prototypes. >> >> On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov >> <dmitry.soshnikov at gmail.com> wrote: >>> >>> On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> wrote: >>>> >>>> In other programming languages such as python, you can specify the last >>>> element of a list with "list[-1]" but in javascript you have to do >>>> "list[list.length-1]". Is there maybe a way to make this feature in >>>> javascript? >>>> >>> >>> This could be a good addition, although `slice` may work as well. This >>> has been discussed previously as well in the last 4-5 years. In addition >>> with non-enumerable properties you can just monkey-patch `Array.prototype` >>> with the `peek` or `last` method. I guess approach when some library forces >>> some method to widely used, can be a good candidate for adding it to the >>> spec (this how it was with `Function.prototype.bind`, e.g., although today >>> monkey-patching is a bad practice of course). >>> >>> In addition, you can monkey-patch just `-1`, and other indexes, e.g. a >>> gist from 5 years old, when a similar topic was proposed here: >>> https://gist.github.com/DmitrySoshnikov/984921 >>> >>> Dmitry >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >> >> >> ---------- Forwarded message ---------- >> From: "Alican Çubukçuoğlu" <alicancubukcuoglu at gmail.com> >> To: es-discuss at mozilla.org >> Cc: >> Date: Fri, 22 Jan 2016 22:32:42 +0200 >> Subject: Re: Re: Javascript Language feature Idea >> More cool stuff: >> ```javascript >> const arr = [1, 2, 3]; >> >> // Easy push >> arr[] = 4; // => arr[arr.length]; >> >> // Easy s(p)lice >> arr[begin, end];, >> arr[begin,]; // => arr[begin, arr.length]; >> arr[begin, end] = [1, 2, 3]; >> ``` >> >> A terrible example (terrible because this should be done with WebGL >> shaders): >> ```javascript >> const image = [ /* Umbagajillion of RGBA pixels */ ]; >> >> function manipulate(rgba) { >> rgba[0] += 10; >> rgba[1] += 10; >> rgba[2] += 10; >> } >> >> for (let i = 0; i < image.length / 4; i++) { >> const begin = i * 4; >> const end = begin + 4; >> >> /* >> In case easy s(p)lice doesn't actually Array.p.slice >> and just creates a limited view of the array >> without breaking reference >> (image[begin, end] === image[begin, end]) >> */ >> manipulate(image[begin, end]); >> >> /* >> In case easy s(p)lice does Array.p.slice >> and creates a new array >> (image[begin, end] !== image[begin, end]) >> */ >> const pixel = image[begin, end]; >> manipulate(pixel); >> image[begin, end] = pixel; >> } >> ``` >> >> >> ---------- Forwarded message ---------- >> From: kdex <kdex at kdex.de> >> To: es-discuss at mozilla.org >> Cc: >> Date: Fri, 22 Jan 2016 22:00:01 +0100 >> Subject: Re: Javascript Language feature Idea >> I really adore the slicing syntax. Just as a quick fix, though, >> > arr[begin,]; // => arr[begin, arr.length]; >> should obviously return `arr[begin, arr.length - 1]`. >> >> Honestly, I'm not too sure if the "easy push" syntax is particularly self- >> explanatory. There might be better alternatives. >> >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: >> > More cool stuff: >> > ```javascript >> > const arr = [1, 2, 3]; >> > >> > // Easy push >> > arr[] = 4; // => arr[arr.length]; >> > >> > // Easy s(p)lice >> > arr[begin, end];, >> > arr[begin,]; // => arr[begin, arr.length]; >> > arr[begin, end] = [1, 2, 3]; >> > ``` >> > >> > A terrible example (terrible because this should be done with WebGL >> > shaders): >> > ```javascript >> > const image = [ /* Umbagajillion of RGBA pixels */ ]; >> > >> > function manipulate(rgba) { >> > rgba[0] += 10; >> > rgba[1] += 10; >> > rgba[2] += 10; >> > } >> > >> > for (let i = 0; i < image.length / 4; i++) { >> > const begin = i * 4; >> > const end = begin + 4; >> > >> > /* >> > In case easy s(p)lice doesn't actually Array.p.slice >> > and just creates a limited view of the array >> > without breaking reference >> > (image[begin, end] === image[begin, end]) >> > */ >> > manipulate(image[begin, end]); >> > >> > /* >> > In case easy s(p)lice does Array.p.slice >> > and creates a new array >> > (image[begin, end] !== image[begin, end]) >> > */ >> > const pixel = image[begin, end]; >> > manipulate(pixel); >> > image[begin, end] = pixel; >> > } >> > ``` >> >> >> >> >> >> ---------- Forwarded message ---------- >> From: kdex <kdex at kdex.de> >> To: es-discuss at mozilla.org >> Cc: >> Date: Fri, 22 Jan 2016 22:14:20 +0100 >> Subject: Re: Javascript Language feature Idea >> Standardizing unused array keys breaks compatibility about as much as >> extending the prototype does, really. Users can already mangle with both. >> >> The problems are a little more subtle, and yes, it would severely break >> backwards compatibility. Consider this example (accessing an element based >> on >> a computed index): >> >> ```js >> let a = [1, 2, 3]; >> let occurrence = a.indexOf(4); >> a[occurrence]; >> ``` >> >> Currently, this should result in `undefined`. After your proposal, you >> could >> introduce a potential bug into every program that accesses arrays using an >> index computed with `Array.prototype.indexOf`, since it would now return >> `3`. >> >> On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote: >> > Since Array inherits from Object, it can have any key, including the key >> > "-1". So something like list[-1] would break compatibility as users can >> > now >> > already assign values to the index -1. >> > >> > If you want a short way to access the last element, it should probably >> > be a >> > function in the Array prototype. Something like list.last(). >> > >> > Regards, >> > Sander >> > >> > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: >> > > In other programming languages such as python, you can specify the >> > > last >> > > element of a list with "list[-1]" but in javascript you have to do >> > > "list[list.length-1]". Is there maybe a way to make this feature in >> > > javascript? >> > > >> > > _______________________________________________ >> > > es-discuss mailing list >> > > es-discuss at mozilla.org >> > > https://mail.mozilla.org/listinfo/es-discuss >> >> >> >> >> >> ---------- Forwarded message ---------- >> From: Benoit Marchant <marchant at mac.com> >> To: kdex <kdex at kdex.de> >> Cc: es-discuss at mozilla.org >> Date: Fri, 22 Jan 2016 13:35:55 -0800 >> Subject: Re: Javascript Language feature Idea >> Interesting! More pedestrian, it would be nice to finally have a version >> of splice that doesn't create a new other Array as a side effect. >> >> > On Jan 22, 2016, at 13:00, kdex <kdex at kdex.de> wrote: >> > >> > I really adore the slicing syntax. Just as a quick fix, though, >> >> arr[begin,]; // => arr[begin, arr.length]; >> > should obviously return `arr[begin, arr.length - 1]`. >> > >> > Honestly, I'm not too sure if the "easy push" syntax is particularly >> > self- >> > explanatory. There might be better alternatives. >> > >> >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: >> >> More cool stuff: >> >> ```javascript >> >> const arr = [1, 2, 3]; >> >> >> >> // Easy push >> >> arr[] = 4; // => arr[arr.length]; >> >> >> >> // Easy s(p)lice >> >> arr[begin, end];, >> >> arr[begin,]; // => arr[begin, arr.length]; >> >> arr[begin, end] = [1, 2, 3]; >> >> ``` >> >> >> >> A terrible example (terrible because this should be done with WebGL >> >> shaders): >> >> ```javascript >> >> const image = [ /* Umbagajillion of RGBA pixels */ ]; >> >> >> >> function manipulate(rgba) { >> >> rgba[0] += 10; >> >> rgba[1] += 10; >> >> rgba[2] += 10; >> >> } >> >> >> >> for (let i = 0; i < image.length / 4; i++) { >> >> const begin = i * 4; >> >> const end = begin + 4; >> >> >> >> /* >> >> In case easy s(p)lice doesn't actually Array.p.slice >> >> and just creates a limited view of the array >> >> without breaking reference >> >> (image[begin, end] === image[begin, end]) >> >> */ >> >> manipulate(image[begin, end]); >> >> >> >> /* >> >> In case easy s(p)lice does Array.p.slice >> >> and creates a new array >> >> (image[begin, end] !== image[begin, end]) >> >> */ >> >> const pixel = image[begin, end]; >> >> manipulate(pixel); >> >> image[begin, end] = pixel; >> >> } >> >> ``` >> > >> > >> > _______________________________________________ >> > es-discuss mailing list >> > es-discuss at mozilla.org >> > https://mail.mozilla.org/listinfo/es-discuss >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
Thomas is right. "last" should unambiguously mean last. If authors want to ascertain the second-last, or third-last, a different method is probably preferable. "nth" sounds great, and could work from the end of the array if passed a negative value.
This would circumvent the issues raised by overriding the -1 property a.l.a Python.
Thomas is right. "last" should unambiguously mean ***last**.* If authors want to ascertain the second-last, or third-last, a different method is probably preferable. "nth" sounds great, and could work from the end of the array if passed a negative value. This would circumvent the issues raised by overriding the -1 property a.l.a Python. On 23 January 2016 at 17:04, <es-discuss-request at mozilla.org> wrote: > Send es-discuss mailing list submissions to > es-discuss at mozilla.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.mozilla.org/listinfo/es-discuss > or, via email, send a message with subject or body 'help' to > es-discuss-request at mozilla.org > > You can reach the person managing the list at > es-discuss-owner at mozilla.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of es-discuss digest..." > > Today's Topics: > > 1. Re: JavaScript Language feature Idea (kdex) > 2. Re: JavaScript Language feature Idea (Thomas) > 3. Re: JavaScript Language feature Idea (/#!/JoePea) > > > ---------- Forwarded message ---------- > From: kdex <kdex at kdex.de> > To: es-discuss at mozilla.org > Cc: > Date: Sat, 23 Jan 2016 06:40:28 +0100 > Subject: Re: JavaScript Language feature Idea > While John's solution doesn't run into conflicts with downward > compatibility, > it still wouldn't solve the problem of getting the n-th last element of an > array. To solve this, it'd probably be a good idea to extend the prototype > and > specify a parameter, defaulting to 1. > > `Array.prototype.last` doesn't show up a terrible lot on search engines, > either, so we might actually be lucky here. Other than that, I also found > two > more threads[1][2] on the EcmaScript discussion archives that propose it. > > They might be worth a read. > > [1] https://esdiscuss.org/topic/array-prototype-last > [2] https://esdiscuss.org/topic/proposal-array-prototype-last > > On Samstag, 23. Januar 2016 15:44:19 CET John Gardner wrote: > > Using a well-known symbol to access an array's last element is probably > > wiser than a typical method or property: > > > > let a = [0, 1, 2, 3]; > > console.log( > > a[Symbol.last] === 3 > > /* true */ > > ); > > > > There're obviously instances where authors have extended Array prototypes > > with "last" methods or properties, but we can't guarantee they'd all work > > the same. For instance, assume there are some implementations that skip > > undefined values: > > > > var a = [0, 1, 2, undefined, undefined]; > > Array.prototype.last = function(){ > > return this[this.length - 1]; > > }; > > /** One that skips undefined values */ > > Array.prototype.last = function(){ > > var offset = 1; > > while(offset < this.length && undefined === this[this.length - offset]) > > ++offset; > > return this[this.length - offset]; > > } > > > > These discrepancies are subtle, but have the potential to break backwards > > compatibility. > > > > Using a well-known symbol eliminates the potential for conflict. > > Furthermore, it also offers an opportunity to complement any iterable > > object's ability to synthesise array-like behaviour. For instance, it > > enables iterables to also return the last object in their list of values: > > > > let pruebas = { > > data: ["Probando", "la", "mierda", "esta", undefined], > > > > [Symbol.iterator](){ > > /* Stuff with .data */ > > }, > > [Symbol.last](){ > > /** Stuff to skip undefined values or whatever */ > > let offset = 1; > > let data = this.data; > > while( > > offset < data.length && > > undefined === data[data.length - offset] > > ) > > ++offset; > > return data[data.length - offset]; > > } > > } > > > > On 23 January 2016 at 08:36, <es-discuss-request at mozilla.org> wrote: > > > Send es-discuss mailing list submissions to > > > > > > es-discuss at mozilla.org > > > > > > To subscribe or unsubscribe via the World Wide Web, visit > > > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > or, via email, send a message with subject or body 'help' to > > > > > > es-discuss-request at mozilla.org > > > > > > You can reach the person managing the list at > > > > > > es-discuss-owner at mozilla.org > > > > > > When replying, please edit your Subject line so it is more specific > > > than "Re: Contents of es-discuss digest..." > > > > > > Today's Topics: > > > 1. Re: Javascript Language feature Idea (Bradley Meck) > > > 2. Re: Re: Javascript Language feature Idea (Alican ?ubuk?uo?lu) > > > 3. Re: Javascript Language feature Idea (kdex) > > > 4. Re: Javascript Language feature Idea (kdex) > > > 5. Re: Javascript Language feature Idea (Benoit Marchant) > > > > > > ---------- Forwarded message ---------- > > > From: Bradley Meck <bradley.meck at gmail.com> > > > To: Dmitry Soshnikov <dmitry.soshnikov at gmail.com> > > > Cc: es-discuss <es-discuss at mozilla.org> > > > Date: Fri, 22 Jan 2016 13:51:54 -0600 > > > Subject: Re: Javascript Language feature Idea > > > Personally I prefer a well known symbol for marking you are grabbing > from > > > the end of the list rather than this wrapping behavior like D ( > > > https://dlang.org/spec/arrays.html#array-length ). That said I think > > > `.last` is more reasonable than changing prototypes. > > > > > > On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov < > > > > > > dmitry.soshnikov at gmail.com> wrote: > > >> On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> > wrote: > > >>> In other programming languages such as python, you can specify the > last > > >>> element of a list with "list[-1]" but in javascript you have to do > > >>> "list[list.length-1]". Is there maybe a way to make this feature in > > >>> javascript? > > >> > > >> This could be a good addition, although `slice` may work as well. This > > >> has been discussed previously as well in the last 4-5 years. In > addition > > >> with non-enumerable properties you can just monkey-patch > > >> `Array.prototype` > > >> with the `peek` or `last` method. I guess approach when some library > > >> forces > > >> some method to widely used, can be a good candidate for adding it to > the > > >> spec (this how it was with `Function.prototype.bind`, e.g., although > > >> today > > >> monkey-patching is a bad practice of course). > > >> > > >> In addition, you can monkey-patch just `-1`, and other indexes, e.g. a > > >> gist from 5 years old, when a similar topic was proposed here: > > >> https://gist.github.com/DmitrySoshnikov/984921 > > >> > > >> Dmitry > > >> > > >> _______________________________________________ > > >> es-discuss mailing list > > >> es-discuss at mozilla.org > > >> https://mail.mozilla.org/listinfo/es-discuss > > > > > > ---------- Forwarded message ---------- > > > From: "Alican Çubukçuoğlu" <alicancubukcuoglu at gmail.com> > > > To: es-discuss at mozilla.org > > > Cc: > > > Date: Fri, 22 Jan 2016 22:32:42 +0200 > > > Subject: Re: Re: Javascript Language feature Idea > > > More cool stuff: > > > ```javascript > > > const arr = [1, 2, 3]; > > > > > > // Easy push > > > arr[] = 4; // => arr[arr.length]; > > > > > > // Easy s(p)lice > > > arr[begin, end];, > > > arr[begin,]; // => arr[begin, arr.length]; > > > arr[begin, end] = [1, 2, 3]; > > > ``` > > > > > > A terrible example (terrible because this should be done with WebGL > > > shaders): > > > ```javascript > > > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > > > > > function manipulate(rgba) { > > > > > > rgba[0] += 10; > > > rgba[1] += 10; > > > rgba[2] += 10; > > > > > > } > > > > > > for (let i = 0; i < image.length / 4; i++) { > > > > > > const begin = i * 4; > > > const end = begin + 4; > > > > > > /* > > > > > > In case easy s(p)lice doesn't actually Array.p.slice > > > and just creates a limited view of the array > > > without breaking reference > > > (image[begin, end] === image[begin, end]) > > > > > > */ > > > manipulate(image[begin, end]); > > > > > > /* > > > > > > In case easy s(p)lice does Array.p.slice > > > and creates a new array > > > (image[begin, end] !== image[begin, end]) > > > > > > */ > > > const pixel = image[begin, end]; > > > manipulate(pixel); > > > image[begin, end] = pixel; > > > > > > } > > > ``` > > > > > > > > > ---------- Forwarded message ---------- > > > From: kdex <kdex at kdex.de> > > > To: es-discuss at mozilla.org > > > Cc: > > > Date: Fri, 22 Jan 2016 22:00:01 +0100 > > > Subject: Re: Javascript Language feature Idea > > > I really adore the slicing syntax. Just as a quick fix, though, > > > > > > > arr[begin,]; // => arr[begin, arr.length]; > > > > > > should obviously return `arr[begin, arr.length - 1]`. > > > > > > Honestly, I'm not too sure if the "easy push" syntax is particularly > self- > > > explanatory. There might be better alternatives. > > > > > > On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > > > > More cool stuff: > > > > ```javascript > > > > const arr = [1, 2, 3]; > > > > > > > > // Easy push > > > > arr[] = 4; // => arr[arr.length]; > > > > > > > > // Easy s(p)lice > > > > arr[begin, end];, > > > > arr[begin,]; // => arr[begin, arr.length]; > > > > arr[begin, end] = [1, 2, 3]; > > > > ``` > > > > > > > > A terrible example (terrible because this should be done with WebGL > > > > shaders): > > > > ```javascript > > > > const image = [ /* Umbagajillion of RGBA pixels */ ]; > > > > > > > > function manipulate(rgba) { > > > > > > > > rgba[0] += 10; > > > > rgba[1] += 10; > > > > rgba[2] += 10; > > > > > > > > } > > > > > > > > for (let i = 0; i < image.length / 4; i++) { > > > > > > > > const begin = i * 4; > > > > const end = begin + 4; > > > > > > > > /* > > > > > > > > In case easy s(p)lice doesn't actually Array.p.slice > > > > and just creates a limited view of the array > > > > without breaking reference > > > > (image[begin, end] === image[begin, end]) > > > > > > > > */ > > > > manipulate(image[begin, end]); > > > > > > > > /* > > > > > > > > In case easy s(p)lice does Array.p.slice > > > > and creates a new array > > > > (image[begin, end] !== image[begin, end]) > > > > > > > > */ > > > > const pixel = image[begin, end]; > > > > manipulate(pixel); > > > > image[begin, end] = pixel; > > > > > > > > } > > > > ``` > > > > > > ---------- Forwarded message ---------- > > > From: kdex <kdex at kdex.de> > > > To: es-discuss at mozilla.org > > > Cc: > > > Date: Fri, 22 Jan 2016 22:14:20 +0100 > > > Subject: Re: Javascript Language feature Idea > > > Standardizing unused array keys breaks compatibility about as much as > > > extending the prototype does, really. Users can already mangle with > both. > > > > > > The problems are a little more subtle, and yes, it would severely break > > > backwards compatibility. Consider this example (accessing an element > based > > > on > > > a computed index): > > > > > > ```js > > > let a = [1, 2, 3]; > > > let occurrence = a.indexOf(4); > > > a[occurrence]; > > > ``` > > > > > > Currently, this should result in `undefined`. After your proposal, you > > > could > > > introduce a potential bug into every program that accesses arrays > using an > > > index computed with `Array.prototype.indexOf`, since it would now > return > > > `3`. > > > > > > On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote: > > > > Since Array inherits from Object, it can have any key, including the > key > > > > "-1". So something like list[-1] would break compatibility as users > can > > > > > > now > > > > > > > already assign values to the index -1. > > > > > > > > If you want a short way to access the last element, it should > probably > > > > > > be a > > > > > > > function in the Array prototype. Something like list.last(). > > > > > > > > Regards, > > > > Sander > > > > > > > > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > > > > > In other programming languages such as python, you can specify the > > > > > last > > > > > element of a list with "list[-1]" but in javascript you have to do > > > > > "list[list.length-1]". Is there maybe a way to make this feature in > > > > > javascript? > > > > > > > > > > _______________________________________________ > > > > > es-discuss mailing list > > > > > es-discuss at mozilla.org > > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > ---------- Forwarded message ---------- > > > From: Benoit Marchant <marchant at mac.com> > > > To: kdex <kdex at kdex.de> > > > Cc: es-discuss at mozilla.org > > > Date: Fri, 22 Jan 2016 13:35:55 -0800 > > > Subject: Re: Javascript Language feature Idea > > > Interesting! More pedestrian, it would be nice to finally have a > version > > > of splice that doesn't create a new other Array as a side effect. > > > > > > > On Jan 22, 2016, at 13:00, kdex <kdex at kdex.de> wrote: > > > > > > > > I really adore the slicing syntax. Just as a quick fix, though, > > > > > > > >> arr[begin,]; // => arr[begin, arr.length]; > > > > > > > > should obviously return `arr[begin, arr.length - 1]`. > > > > > > > > Honestly, I'm not too sure if the "easy push" syntax is particularly > > > > > > self- > > > > > > > explanatory. There might be better alternatives. > > > > > > > >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > > > >> More cool stuff: > > > >> ```javascript > > > >> const arr = [1, 2, 3]; > > > >> > > > >> // Easy push > > > >> arr[] = 4; // => arr[arr.length]; > > > >> > > > >> // Easy s(p)lice > > > >> arr[begin, end];, > > > >> arr[begin,]; // => arr[begin, arr.length]; > > > >> arr[begin, end] = [1, 2, 3]; > > > >> ``` > > > >> > > > >> A terrible example (terrible because this should be done with WebGL > > > >> shaders): > > > >> ```javascript > > > >> const image = [ /* Umbagajillion of RGBA pixels */ ]; > > > >> > > > >> function manipulate(rgba) { > > > >> > > > >> rgba[0] += 10; > > > >> rgba[1] += 10; > > > >> rgba[2] += 10; > > > >> > > > >> } > > > >> > > > >> for (let i = 0; i < image.length / 4; i++) { > > > >> > > > >> const begin = i * 4; > > > >> const end = begin + 4; > > > >> > > > >> /* > > > >> > > > >> In case easy s(p)lice doesn't actually Array.p.slice > > > >> and just creates a limited view of the array > > > >> without breaking reference > > > >> (image[begin, end] === image[begin, end]) > > > >> > > > >> */ > > > >> manipulate(image[begin, end]); > > > >> > > > >> /* > > > >> > > > >> In case easy s(p)lice does Array.p.slice > > > >> and creates a new array > > > >> (image[begin, end] !== image[begin, end]) > > > >> > > > >> */ > > > >> const pixel = image[begin, end]; > > > >> manipulate(pixel); > > > >> image[begin, end] = pixel; > > > >> > > > >> } > > > >> ``` > > > > > > > > _______________________________________________ > > > > es-discuss mailing list > > > > es-discuss at mozilla.org > > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org > > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > ---------- Forwarded message ---------- > From: Thomas <thomasjamesfoster at bigpond.com> > To: kdex <kdex at kdex.de> > Cc: es-discuss at mozilla.org > Date: Sat, 23 Jan 2016 16:51:21 +1100 > Subject: Re: JavaScript Language feature Idea > Is this what you're thinking? > > Array.prototype.nth = function (n){ > if(n < 0){ > return this[this.length -n]; > } else { > return this[n]; > } > } > > Thomas Foster > > @thomasfoster96 > Ph: +61477808008 > http://thomasfoster.co/ > > > On 23 Jan 2016, at 4:40 PM, kdex <kdex at kdex.de> wrote: > > > > While John's solution doesn't run into conflicts with downward > compatibility, > > it still wouldn't solve the problem of getting the n-th last element of > an > > array. To solve this, it'd probably be a good idea to extend the > prototype and > > specify a parameter, defaulting to 1. > > > > `Array.prototype.last` doesn't show up a terrible lot on search engines, > > either, so we might actually be lucky here. Other than that, I also > found two > > more threads[1][2] on the EcmaScript discussion archives that propose it. > > > > They might be worth a read. > > > > [1] https://esdiscuss.org/topic/array-prototype-last > > [2] https://esdiscuss.org/topic/proposal-array-prototype-last > > > >> On Samstag, 23. Januar 2016 15:44:19 CET John Gardner wrote: > >> Using a well-known symbol to access an array's last element is probably > >> wiser than a typical method or property: > >> > >> let a = [0, 1, 2, 3]; > >> console.log( > >> a[Symbol.last] === 3 > >> /* true */ > >> ); > >> > >> There're obviously instances where authors have extended Array > prototypes > >> with "last" methods or properties, but we can't guarantee they'd all > work > >> the same. For instance, assume there are some implementations that skip > >> undefined values: > >> > >> var a = [0, 1, 2, undefined, undefined]; > >> Array.prototype.last = function(){ > >> return this[this.length - 1]; > >> }; > >> /** One that skips undefined values */ > >> Array.prototype.last = function(){ > >> var offset = 1; > >> while(offset < this.length && undefined === this[this.length - offset]) > >> ++offset; > >> return this[this.length - offset]; > >> } > >> > >> These discrepancies are subtle, but have the potential to break > backwards > >> compatibility. > >> > >> Using a well-known symbol eliminates the potential for conflict. > >> Furthermore, it also offers an opportunity to complement any iterable > >> object's ability to synthesise array-like behaviour. For instance, it > >> enables iterables to also return the last object in their list of > values: > >> > >> let pruebas = { > >> data: ["Probando", "la", "mierda", "esta", undefined], > >> > >> [Symbol.iterator](){ > >> /* Stuff with .data */ > >> }, > >> [Symbol.last](){ > >> /** Stuff to skip undefined values or whatever */ > >> let offset = 1; > >> let data = this.data; > >> while( > >> offset < data.length && > >> undefined === data[data.length - offset] > >> ) > >> ++offset; > >> return data[data.length - offset]; > >> } > >> } > >> > >> O > > > > ---------- Forwarded message ---------- > From: "/#!/JoePea" <joe at trusktr.io> > To: John Gardner <gardnerjohng at gmail.com> > Cc: es-discuss <es-discuss at mozilla.org> > Date: Fri, 22 Jan 2016 22:04:14 -0800 > Subject: Re: JavaScript Language feature Idea > I think Symbol.last seems like the best option so far, without breaking > things. > > On Fri, Jan 22, 2016 at 8:44 PM, John Gardner <gardnerjohng at gmail.com> > wrote: > > Using a well-known symbol to access an array's last element is probably > > wiser than a typical method or property: > > > > let a = [0, 1, 2, 3]; > > console.log( > > a[Symbol.last] === 3 > > /* true */ > > ); > > > > There're obviously instances where authors have extended Array prototypes > > with "last" methods or properties, but we can't guarantee they'd all work > > the same. For instance, assume there are some implementations that skip > > undefined values: > > > > var a = [0, 1, 2, undefined, undefined]; > > Array.prototype.last = function(){ > > return this[this.length - 1]; > > }; > > /** One that skips undefined values */ > > Array.prototype.last = function(){ > > var offset = 1; > > while(offset < this.length && undefined === this[this.length - offset]) > > ++offset; > > return this[this.length - offset]; > > } > > > > These discrepancies are subtle, but have the potential to break backwards > > compatibility. > > > > Using a well-known symbol eliminates the potential for conflict. > > Furthermore, it also offers an opportunity to complement any iterable > > object's ability to synthesise array-like behaviour. For instance, it > > enables iterables to also return the last object in their list of values: > > > > let pruebas = { > > data: ["Probando", "la", "mierda", "esta", undefined], > > > > [Symbol.iterator](){ > > /* Stuff with .data */ > > }, > > [Symbol.last](){ > > /** Stuff to skip undefined values or whatever */ > > let offset = 1; > > let data = this.data; > > while( > > offset < data.length && > > undefined === data[data.length - offset] > > ) > > ++offset; > > return data[data.length - offset]; > > } > > } > > > > > > On 23 January 2016 at 08:36, <es-discuss-request at mozilla.org> wrote: > >> > >> Send es-discuss mailing list submissions to > >> es-discuss at mozilla.org > >> > >> To subscribe or unsubscribe via the World Wide Web, visit > >> https://mail.mozilla.org/listinfo/es-discuss > >> or, via email, send a message with subject or body 'help' to > >> es-discuss-request at mozilla.org > >> > >> You can reach the person managing the list at > >> es-discuss-owner at mozilla.org > >> > >> When replying, please edit your Subject line so it is more specific > >> than "Re: Contents of es-discuss digest..." > >> > >> Today's Topics: > >> > >> 1. Re: Javascript Language feature Idea (Bradley Meck) > >> 2. Re: Re: Javascript Language feature Idea (Alican ?ubuk?uo?lu) > >> 3. Re: Javascript Language feature Idea (kdex) > >> 4. Re: Javascript Language feature Idea (kdex) > >> 5. Re: Javascript Language feature Idea (Benoit Marchant) > >> > >> > >> ---------- Forwarded message ---------- > >> From: Bradley Meck <bradley.meck at gmail.com> > >> To: Dmitry Soshnikov <dmitry.soshnikov at gmail.com> > >> Cc: es-discuss <es-discuss at mozilla.org> > >> Date: Fri, 22 Jan 2016 13:51:54 -0600 > >> Subject: Re: Javascript Language feature Idea > >> Personally I prefer a well known symbol for marking you are grabbing > from > >> the end of the list rather than this wrapping behavior like D ( > >> https://dlang.org/spec/arrays.html#array-length ). That said I think > `.last` > >> is more reasonable than changing prototypes. > >> > >> On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov > >> <dmitry.soshnikov at gmail.com> wrote: > >>> > >>> On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <racerd123 at gmail.com> > wrote: > >>>> > >>>> In other programming languages such as python, you can specify the > last > >>>> element of a list with "list[-1]" but in javascript you have to do > >>>> "list[list.length-1]". Is there maybe a way to make this feature in > >>>> javascript? > >>>> > >>> > >>> This could be a good addition, although `slice` may work as well. This > >>> has been discussed previously as well in the last 4-5 years. In > addition > >>> with non-enumerable properties you can just monkey-patch > `Array.prototype` > >>> with the `peek` or `last` method. I guess approach when some library > forces > >>> some method to widely used, can be a good candidate for adding it to > the > >>> spec (this how it was with `Function.prototype.bind`, e.g., although > today > >>> monkey-patching is a bad practice of course). > >>> > >>> In addition, you can monkey-patch just `-1`, and other indexes, e.g. a > >>> gist from 5 years old, when a similar topic was proposed here: > >>> https://gist.github.com/DmitrySoshnikov/984921 > >>> > >>> Dmitry > >>> > >>> _______________________________________________ > >>> es-discuss mailing list > >>> es-discuss at mozilla.org > >>> https://mail.mozilla.org/listinfo/es-discuss > >>> > >> > >> > >> > >> ---------- Forwarded message ---------- > >> From: "Alican Çubukçuoğlu" <alicancubukcuoglu at gmail.com> > >> To: es-discuss at mozilla.org > >> Cc: > >> Date: Fri, 22 Jan 2016 22:32:42 +0200 > >> Subject: Re: Re: Javascript Language feature Idea > >> More cool stuff: > >> ```javascript > >> const arr = [1, 2, 3]; > >> > >> // Easy push > >> arr[] = 4; // => arr[arr.length]; > >> > >> // Easy s(p)lice > >> arr[begin, end];, > >> arr[begin,]; // => arr[begin, arr.length]; > >> arr[begin, end] = [1, 2, 3]; > >> ``` > >> > >> A terrible example (terrible because this should be done with WebGL > >> shaders): > >> ```javascript > >> const image = [ /* Umbagajillion of RGBA pixels */ ]; > >> > >> function manipulate(rgba) { > >> rgba[0] += 10; > >> rgba[1] += 10; > >> rgba[2] += 10; > >> } > >> > >> for (let i = 0; i < image.length / 4; i++) { > >> const begin = i * 4; > >> const end = begin + 4; > >> > >> /* > >> In case easy s(p)lice doesn't actually Array.p.slice > >> and just creates a limited view of the array > >> without breaking reference > >> (image[begin, end] === image[begin, end]) > >> */ > >> manipulate(image[begin, end]); > >> > >> /* > >> In case easy s(p)lice does Array.p.slice > >> and creates a new array > >> (image[begin, end] !== image[begin, end]) > >> */ > >> const pixel = image[begin, end]; > >> manipulate(pixel); > >> image[begin, end] = pixel; > >> } > >> ``` > >> > >> > >> ---------- Forwarded message ---------- > >> From: kdex <kdex at kdex.de> > >> To: es-discuss at mozilla.org > >> Cc: > >> Date: Fri, 22 Jan 2016 22:00:01 +0100 > >> Subject: Re: Javascript Language feature Idea > >> I really adore the slicing syntax. Just as a quick fix, though, > >> > arr[begin,]; // => arr[begin, arr.length]; > >> should obviously return `arr[begin, arr.length - 1]`. > >> > >> Honestly, I'm not too sure if the "easy push" syntax is particularly > self- > >> explanatory. There might be better alternatives. > >> > >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > >> > More cool stuff: > >> > ```javascript > >> > const arr = [1, 2, 3]; > >> > > >> > // Easy push > >> > arr[] = 4; // => arr[arr.length]; > >> > > >> > // Easy s(p)lice > >> > arr[begin, end];, > >> > arr[begin,]; // => arr[begin, arr.length]; > >> > arr[begin, end] = [1, 2, 3]; > >> > ``` > >> > > >> > A terrible example (terrible because this should be done with WebGL > >> > shaders): > >> > ```javascript > >> > const image = [ /* Umbagajillion of RGBA pixels */ ]; > >> > > >> > function manipulate(rgba) { > >> > rgba[0] += 10; > >> > rgba[1] += 10; > >> > rgba[2] += 10; > >> > } > >> > > >> > for (let i = 0; i < image.length / 4; i++) { > >> > const begin = i * 4; > >> > const end = begin + 4; > >> > > >> > /* > >> > In case easy s(p)lice doesn't actually Array.p.slice > >> > and just creates a limited view of the array > >> > without breaking reference > >> > (image[begin, end] === image[begin, end]) > >> > */ > >> > manipulate(image[begin, end]); > >> > > >> > /* > >> > In case easy s(p)lice does Array.p.slice > >> > and creates a new array > >> > (image[begin, end] !== image[begin, end]) > >> > */ > >> > const pixel = image[begin, end]; > >> > manipulate(pixel); > >> > image[begin, end] = pixel; > >> > } > >> > ``` > >> > >> > >> > >> > >> > >> ---------- Forwarded message ---------- > >> From: kdex <kdex at kdex.de> > >> To: es-discuss at mozilla.org > >> Cc: > >> Date: Fri, 22 Jan 2016 22:14:20 +0100 > >> Subject: Re: Javascript Language feature Idea > >> Standardizing unused array keys breaks compatibility about as much as > >> extending the prototype does, really. Users can already mangle with > both. > >> > >> The problems are a little more subtle, and yes, it would severely break > >> backwards compatibility. Consider this example (accessing an element > based > >> on > >> a computed index): > >> > >> ```js > >> let a = [1, 2, 3]; > >> let occurrence = a.indexOf(4); > >> a[occurrence]; > >> ``` > >> > >> Currently, this should result in `undefined`. After your proposal, you > >> could > >> introduce a potential bug into every program that accesses arrays using > an > >> index computed with `Array.prototype.indexOf`, since it would now return > >> `3`. > >> > >> On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote: > >> > Since Array inherits from Object, it can have any key, including the > key > >> > "-1". So something like list[-1] would break compatibility as users > can > >> > now > >> > already assign values to the index -1. > >> > > >> > If you want a short way to access the last element, it should probably > >> > be a > >> > function in the Array prototype. Something like list.last(). > >> > > >> > Regards, > >> > Sander > >> > > >> > 2016-01-22 18:53 GMT+01:00 RacerD123 <racerd123 at gmail.com>: > >> > > In other programming languages such as python, you can specify the > >> > > last > >> > > element of a list with "list[-1]" but in javascript you have to do > >> > > "list[list.length-1]". Is there maybe a way to make this feature in > >> > > javascript? > >> > > > >> > > _______________________________________________ > >> > > es-discuss mailing list > >> > > es-discuss at mozilla.org > >> > > https://mail.mozilla.org/listinfo/es-discuss > >> > >> > >> > >> > >> > >> ---------- Forwarded message ---------- > >> From: Benoit Marchant <marchant at mac.com> > >> To: kdex <kdex at kdex.de> > >> Cc: es-discuss at mozilla.org > >> Date: Fri, 22 Jan 2016 13:35:55 -0800 > >> Subject: Re: Javascript Language feature Idea > >> Interesting! More pedestrian, it would be nice to finally have a version > >> of splice that doesn't create a new other Array as a side effect. > >> > >> > On Jan 22, 2016, at 13:00, kdex <kdex at kdex.de> wrote: > >> > > >> > I really adore the slicing syntax. Just as a quick fix, though, > >> >> arr[begin,]; // => arr[begin, arr.length]; > >> > should obviously return `arr[begin, arr.length - 1]`. > >> > > >> > Honestly, I'm not too sure if the "easy push" syntax is particularly > >> > self- > >> > explanatory. There might be better alternatives. > >> > > >> >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote: > >> >> More cool stuff: > >> >> ```javascript > >> >> const arr = [1, 2, 3]; > >> >> > >> >> // Easy push > >> >> arr[] = 4; // => arr[arr.length]; > >> >> > >> >> // Easy s(p)lice > >> >> arr[begin, end];, > >> >> arr[begin,]; // => arr[begin, arr.length]; > >> >> arr[begin, end] = [1, 2, 3]; > >> >> ``` > >> >> > >> >> A terrible example (terrible because this should be done with WebGL > >> >> shaders): > >> >> ```javascript > >> >> const image = [ /* Umbagajillion of RGBA pixels */ ]; > >> >> > >> >> function manipulate(rgba) { > >> >> rgba[0] += 10; > >> >> rgba[1] += 10; > >> >> rgba[2] += 10; > >> >> } > >> >> > >> >> for (let i = 0; i < image.length / 4; i++) { > >> >> const begin = i * 4; > >> >> const end = begin + 4; > >> >> > >> >> /* > >> >> In case easy s(p)lice doesn't actually Array.p.slice > >> >> and just creates a limited view of the array > >> >> without breaking reference > >> >> (image[begin, end] === image[begin, end]) > >> >> */ > >> >> manipulate(image[begin, end]); > >> >> > >> >> /* > >> >> In case easy s(p)lice does Array.p.slice > >> >> and creates a new array > >> >> (image[begin, end] !== image[begin, end]) > >> >> */ > >> >> const pixel = image[begin, end]; > >> >> manipulate(pixel); > >> >> image[begin, end] = pixel; > >> >> } > >> >> ``` > >> > > >> > > >> > _______________________________________________ > >> > es-discuss mailing list > >> > es-discuss at mozilla.org > >> > https://mail.mozilla.org/listinfo/es-discuss > >> > >> > >> _______________________________________________ > >> es-discuss mailing list > >> es-discuss at mozilla.org > >> https://mail.mozilla.org/listinfo/es-discuss > >> > > > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160123/2ee7c799/attachment-0001.html>
@Thomas: I think your implementation has a bug for negative values of n. It
should have been + n
instead of -n
, probably.
To me, It would feel a little more "natural" if it behaved somewhere around this:
/* Used like the [] operator, but indices are counted from right to left and
also works with negative numbers */
Array.prototype.last = function(n) {
if (n === undefined) {
n = 0;
}
else if (typeof n !== "number") {
throw new Error("First argument must be a number");
}
if (n < 0) {
return this[Math.abs(n) - 1];
}
return this[this.length - 1 - n];
};
/* Used like the [] operator, but also works with negative numbers */
Array.prototype.nth = function(n) {
if (n === undefined) {
n = 0;
}
else if (typeof n !== "number") {
throw new Error("First argument must be a number");
}
if (n < 0) {
return this.last(Math.abs(n) - 1);
}
else {
return this[n];
}
};
[1, 2, 3].last(); // 3
[1, 2, 3].last(0); // 3
[1, 2, 3].last(1); // 2
[1, 2, 3].last(2); // 1
[1, 2, 3].last(3); // undefined
[1, 2, 3].last(-1); // 1
[1, 2, 3].last(-2); // 2
[1, 2, 3].last(-3); // 3
[1, 2, 3].nth(); // 1
[1, 2, 3].nth(0); // 1
[1, 2, 3].nth(1); // 2
[1, 2, 3].nth(-1); // 3
[1, 2, 3].nth(-4); // undefined
[1, 2, 3].nth(null); // error
[1, 2, 3].last(null); // error
@Thomas: I think your implementation has a bug for negative values of n. It should have been `+ n` instead of `-n`, probably. To me, It would feel a little more "natural" if it behaved somewhere around this: ```js /* Used like the [] operator, but indices are counted from right to left and also works with negative numbers */ Array.prototype.last = function(n) { if (n === undefined) { n = 0; } else if (typeof n !== "number") { throw new Error("First argument must be a number"); } if (n < 0) { return this[Math.abs(n) - 1]; } return this[this.length - 1 - n]; }; /* Used like the [] operator, but also works with negative numbers */ Array.prototype.nth = function(n) { if (n === undefined) { n = 0; } else if (typeof n !== "number") { throw new Error("First argument must be a number"); } if (n < 0) { return this.last(Math.abs(n) - 1); } else { return this[n]; } }; [1, 2, 3].last(); // 3 [1, 2, 3].last(0); // 3 [1, 2, 3].last(1); // 2 [1, 2, 3].last(2); // 1 [1, 2, 3].last(3); // undefined [1, 2, 3].last(-1); // 1 [1, 2, 3].last(-2); // 2 [1, 2, 3].last(-3); // 3 [1, 2, 3].nth(); // 1 [1, 2, 3].nth(0); // 1 [1, 2, 3].nth(1); // 2 [1, 2, 3].nth(-1); // 3 [1, 2, 3].nth(-4); // undefined [1, 2, 3].nth(null); // error [1, 2, 3].last(null); // error ``` On Samstag, 23. Januar 2016 16:51:21 CET Thomas wrote: > Is this what you're thinking? > > Array.prototype.nth = function (n){ > if(n < 0){ > return this[this.length -n]; > } else { > return this[n]; > } > } > > Thomas Foster > > @thomasfoster96 > Ph: +61477808008 > http://thomasfoster.co/ > > > On 23 Jan 2016, at 4:40 PM, kdex <kdex at kdex.de> wrote: > > > > While John's solution doesn't run into conflicts with downward > > compatibility, it still wouldn't solve the problem of getting the n-th > > last element of an array. To solve this, it'd probably be a good idea to > > extend the prototype and specify a parameter, defaulting to 1. > > > > `Array.prototype.last` doesn't show up a terrible lot on search engines, > > either, so we might actually be lucky here. Other than that, I also found > > two more threads[1][2] on the EcmaScript discussion archives that propose > > it. > > > > They might be worth a read. > > > > [1] https://esdiscuss.org/topic/array-prototype-last > > [2] https://esdiscuss.org/topic/proposal-array-prototype-last > > > >> On Samstag, 23. Januar 2016 15:44:19 CET John Gardner wrote: > >> Using a well-known symbol to access an array's last element is probably > >> wiser than a typical method or property: > >> > >> let a = [0, 1, 2, 3]; > >> console.log( > >> a[Symbol.last] === 3 > >> /* true */ > >> ); > >> > >> There're obviously instances where authors have extended Array prototypes > >> with "last" methods or properties, but we can't guarantee they'd all work > >> the same. For instance, assume there are some implementations that skip > >> undefined values: > >> > >> var a = [0, 1, 2, undefined, undefined]; > >> Array.prototype.last = function(){ > >> return this[this.length - 1]; > >> }; > >> /** One that skips undefined values */ > >> Array.prototype.last = function(){ > >> var offset = 1; > >> while(offset < this.length && undefined === this[this.length - offset]) > >> ++offset; > >> return this[this.length - offset]; > >> } > >> > >> These discrepancies are subtle, but have the potential to break backwards > >> compatibility. > >> > >> Using a well-known symbol eliminates the potential for conflict. > >> Furthermore, it also offers an opportunity to complement any iterable > >> object's ability to synthesise array-like behaviour. For instance, it > >> enables iterables to also return the last object in their list of values: > >> > >> let pruebas = { > >> data: ["Probando", "la", "mierda", "esta", undefined], > >> > >> [Symbol.iterator](){ > >> /* Stuff with .data */ > >> }, > >> [Symbol.last](){ > >> /** Stuff to skip undefined values or whatever */ > >> let offset = 1; > >> let data = this.data; > >> while( > >> offset < data.length && > >> undefined === data[data.length - offset] > >> ) > >> ++offset; > >> return data[data.length - offset]; > >> } > >> } > >> > >> O
On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote:
[1, 2, 3].last(); // 3
I'm wondering what the ultimate motivation for suggestions like this is. Is it to save key strokes? Allow more semantic coding? Support new paradigms? Performance? 'm sure someone has already come up with a good categorization like this, would someone mind providing a link? Could one of these be considered the "theme" for the next version?
I have to admit to be being quite negative about proposals of the form
"Hey, this other language does X, can we do that too?", or "It would be so
cool if we could do Y", especially when these are mostly about syntax. Is a
missing last
really one of our painpoints?
Bob
On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: > [1, 2, 3].last(); // 3 I'm wondering what the ultimate motivation for suggestions like this is. Is it to save key strokes? Allow more semantic coding? Support new paradigms? Performance? 'm sure someone has already come up with a good categorization like this, would someone mind providing a link? Could one of these be considered the "theme" for the next version? I have to admit to be being quite negative about proposals of the form "Hey, this other language does X, can we do that too?", or "It would be so cool if we could do Y", especially when these are mostly about syntax. Is a missing `last` really one of our painpoints? Bob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160123/a9b88c3a/attachment.html>
Not every feature addition is due to performance or paradigms. Just have a
look at ES2015: I'm sure that this has neither been the motivation for
String.prototype.startsWith
nor for String.prototype.includes
. Even
String.prototype.repeat
appears so simple that a loop paired with a
concatenation could have become a popular alternative.
Of course you could solve most of these string problems with earlier versions of the language, too, often explicitly thinking with incides. But on the downside, your code suddenly becomes a potentially unintuitive, index-ridden mess, introducing off-by-one and out-of-bound errors (it even happened to someone on this thread, too, if you review Thomas' code from above). This isn't really all too much about saving keystrokes, but mainly about writing clean, readable and maintainable code.
There's array::back in C++, negative indices in Python as well as Bash or end in PHP, so I don't see any reason why we should complicate things for people coming from these languages. Nor to I see why we should torture ourselves thinking about how the underlying data structure stores its elements internally when all I care about is reading the last element.
Just ask yourself: Do you think it's substantially more readable to write
[1, 2, 3].slice(-2)[1];
over
[1, 2, 3].last(1);
?
If it comes to write access, I agree thatSymbol.last
could be another handy
addition (it doesn't have to be an "either/or" discussion, really):
[1, 2, 3][Symbol.last]; // 3 [1, 2, 3][Symbol.last] = 4; // 4 [1, 2, 3].last(1); // 2
Not every feature addition is due to performance or paradigms. Just have a look at ES2015: I'm sure that this has neither been the motivation for `String.prototype.startsWith`nor for `String.prototype.includes`. Even `String.prototype.repeat` appears so simple that a loop paired with a concatenation could have become a popular alternative. Of course you could solve most of these string problems with earlier versions of the language, too, often explicitly thinking with incides. But on the downside, your code suddenly becomes a potentially unintuitive, index-ridden mess, introducing off-by-one and out-of-bound errors (it even happened to someone on this thread, too, if you review Thomas' code from above). This isn't really all too much about saving keystrokes, but mainly about writing clean, readable and maintainable code. There's array::back in C++, negative indices in Python as well as Bash or end in PHP, so I don't see any reason why we should complicate things for people coming from these languages. Nor to I see why we should torture ourselves thinking about how the underlying data structure stores its elements internally when all I care about is reading the last element. Just ask yourself: Do you think it's substantially more readable to write ```js [1, 2, 3].slice(-2)[1]; ``` over ``` [1, 2, 3].last(1); ``` ? If it comes to write access, I agree that`Symbol.last` could be another handy addition (it doesn't have to be an "either/or" discussion, really): [1, 2, 3][Symbol.last]; // 3 [1, 2, 3][Symbol.last] = 4; // 4 [1, 2, 3].last(1); // 2 On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: > > [1, 2, 3].last(); // 3 > > I'm wondering what the ultimate motivation for suggestions like this is. Is > it to save key strokes? Allow more semantic coding? Support new paradigms? > Performance? 'm sure someone has already come up with a good categorization > like this, would someone mind providing a link? Could one of these be > considered the "theme" for the next version? > > I have to admit to be being quite negative about proposals of the form > "Hey, this other language does X, can we do that too?", or "It would be so > cool if we could do Y", especially when these are mostly about syntax. Is a > missing `last` really one of our painpoints? > > Bob
I can't consider .last(1)
method to be readable...
But I think .nth(n)
method with support for negative index would be
really useful.
2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>:
I can't consider `.last(1)` method to be readable... But I think `.nth(n)` method with support for negative index would be really useful. 2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>: > Not every feature addition is due to performance or paradigms. Just have a > look at ES2015: I'm sure that this has neither been the motivation for > `String.prototype.startsWith`nor for `String.prototype.includes`. Even > `String.prototype.repeat` appears so simple that a loop paired with a > concatenation could have become a popular alternative. > > Of course you could solve most of these string problems with earlier > versions > of the language, too, often explicitly thinking with incides. But on the > downside, your code suddenly becomes a potentially unintuitive, > index-ridden > mess, introducing off-by-one and out-of-bound errors (it even happened to > someone on this thread, too, if you review Thomas' code from above). This > isn't really all too much about saving keystrokes, but mainly about writing > clean, readable and maintainable code. > > There's array::back in C++, negative indices in Python as well as Bash or > end > in PHP, so I don't see any reason why we should complicate things for > people > coming from these languages. Nor to I see why we should torture ourselves > thinking about how the underlying data structure stores its elements > internally when all I care about is reading the last element. > > Just ask yourself: Do you think it's substantially more readable to write > > ```js > [1, 2, 3].slice(-2)[1]; > ``` > over > ``` > [1, 2, 3].last(1); > ``` > ? > > If it comes to write access, I agree that`Symbol.last` could be another > handy > addition (it doesn't have to be an "either/or" discussion, really): > > [1, 2, 3][Symbol.last]; // 3 > [1, 2, 3][Symbol.last] = 4; // 4 > [1, 2, 3].last(1); // 2 > > On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: > > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: > > > [1, 2, 3].last(); // 3 > > > > I'm wondering what the ultimate motivation for suggestions like this is. > Is > > it to save key strokes? Allow more semantic coding? Support new > paradigms? > > Performance? 'm sure someone has already come up with a good > categorization > > like this, would someone mind providing a link? Could one of these be > > considered the "theme" for the next version? > > > > I have to admit to be being quite negative about proposals of the form > > "Hey, this other language does X, can we do that too?", or "It would be > so > > cool if we could do Y", especially when these are mostly about syntax. > Is a > > missing `last` really one of our painpoints? > > > > Bob > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160123/4f7ee1a5/attachment-0001.html>
Just a short note:
I was not aware that it was an explicit design goal to simplify things for people coming from other languages.
Well, it most certainly was. That's why we're "blessed" with ASI. :)
Just a short note: > I was not aware that it was an explicit design goal to simplify things for > people coming from other languages. Well, it most certainly was. That's why we're "blessed" with ASI. :) On Samstag, 23. Januar 2016 23:41:45 CET you wrote: > I can't remember the last time I wanted to get the next-to-last element of > an array. If I did, I would write `arr[arr.length-2]` and be done with it. > If you want to methodize this as `Array.prototype.last` feel free; who's > stopping you? > > I was not aware that it was an explicit design goal to simplify things for > people coming from other languages. In some cases, things like array > slicing was built into these languages in extremely clean fashion from the > start. Trying to splice equivalent syntaxes onto JS is no trivial matter in > many cases. > > Is this supposed to be the same as `push`? > > -- > Bob > > On Sat, Jan 23, 2016 at 10:02 PM, kdex <kdex at kdex.de> wrote: > > Not every feature addition is due to performance or paradigms. Just have a > > look at ES2015: I'm sure that this has neither been the motivation for > > `String.prototype.startsWith`nor for `String.prototype.includes`. Even > > `String.prototype.repeat` appears so simple that a loop paired with a > > concatenation could have become a popular alternative. > > > > Of course you could solve most of these string problems with earlier > > versions > > of the language, too, often explicitly thinking with incides. But on the > > downside, your code suddenly becomes a potentially unintuitive, > > index-ridden > > mess, introducing off-by-one and out-of-bound errors (it even happened to > > someone on this thread, too, if you review Thomas' code from above). This > > isn't really all too much about saving keystrokes, but mainly about > > writing > > clean, readable and maintainable code. > > > > There's array::back in C++, negative indices in Python as well as Bash or > > end > > in PHP, so I don't see any reason why we should complicate things for > > people > > coming from these languages. Nor to I see why we should torture ourselves > > thinking about how the underlying data structure stores its elements > > internally when all I care about is reading the last element. > > > > Just ask yourself: Do you think it's substantially more readable to write > > > > ```js > > [1, 2, 3].slice(-2)[1]; > > ``` > > over > > ``` > > [1, 2, 3].last(1); > > ``` > > ? > > > > If it comes to write access, I agree that`Symbol.last` could be another > > handy > > addition (it doesn't have to be an "either/or" discussion, really): > > > > [1, 2, 3][Symbol.last]; // 3 > > [1, 2, 3][Symbol.last] = 4; // 4 > > [1, 2, 3].last(1); // 2 > > > > On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: > > > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: > > > > [1, 2, 3].last(); // 3 > > > > > > I'm wondering what the ultimate motivation for suggestions like this is. > > > > Is > > > > > it to save key strokes? Allow more semantic coding? Support new > > > > paradigms? > > > > > Performance? 'm sure someone has already come up with a good > > > > categorization > > > > > like this, would someone mind providing a link? Could one of these be > > > considered the "theme" for the next version? > > > > > > I have to admit to be being quite negative about proposals of the form > > > "Hey, this other language does X, can we do that too?", or "It would be > > > > so > > > > > cool if we could do Y", especially when these are mostly about syntax. > > > > Is a > > > > > missing `last` really one of our painpoints? > > > > > > Bob
@Michał: That really depends on the point of view: If you need zero-based
indexing from the right, as []
does from the left, you'd use
Array.prototype.last
.
@Michał: That really depends on the point of view: If you need zero-based indexing from the right, as `[]` does from the left, you'd use `Array.prototype.last`. On Samstag, 23. Januar 2016 20:56:02 CET Michał Wadas wrote: > I can't consider `.last(1)` method to be readable... > But I think `.nth(n)` method with support for negative index would be > really useful. > > 2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>: > > Not every feature addition is due to performance or paradigms. Just have a > > look at ES2015: I'm sure that this has neither been the motivation for > > `String.prototype.startsWith`nor for `String.prototype.includes`. Even > > `String.prototype.repeat` appears so simple that a loop paired with a > > concatenation could have become a popular alternative. > > > > Of course you could solve most of these string problems with earlier > > versions > > of the language, too, often explicitly thinking with incides. But on the > > downside, your code suddenly becomes a potentially unintuitive, > > index-ridden > > mess, introducing off-by-one and out-of-bound errors (it even happened to > > someone on this thread, too, if you review Thomas' code from above). This > > isn't really all too much about saving keystrokes, but mainly about > > writing > > clean, readable and maintainable code. > > > > There's array::back in C++, negative indices in Python as well as Bash or > > end > > in PHP, so I don't see any reason why we should complicate things for > > people > > coming from these languages. Nor to I see why we should torture ourselves > > thinking about how the underlying data structure stores its elements > > internally when all I care about is reading the last element. > > > > Just ask yourself: Do you think it's substantially more readable to write > > > > ```js > > [1, 2, 3].slice(-2)[1]; > > ``` > > over > > ``` > > [1, 2, 3].last(1); > > ``` > > ? > > > > If it comes to write access, I agree that`Symbol.last` could be another > > handy > > addition (it doesn't have to be an "either/or" discussion, really): > > > > [1, 2, 3][Symbol.last]; // 3 > > [1, 2, 3][Symbol.last] = 4; // 4 > > [1, 2, 3].last(1); // 2 > > > > On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: > > > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: > > > > [1, 2, 3].last(); // 3 > > > > > > I'm wondering what the ultimate motivation for suggestions like this is. > > > > Is > > > > > it to save key strokes? Allow more semantic coding? Support new > > > > paradigms? > > > > > Performance? 'm sure someone has already come up with a good > > > > categorization > > > > > like this, would someone mind providing a link? Could one of these be > > > considered the "theme" for the next version? > > > > > > I have to admit to be being quite negative about proposals of the form > > > "Hey, this other language does X, can we do that too?", or "It would be > > > > so > > > > > cool if we could do Y", especially when these are mostly about syntax. > > > > Is a > > > > > missing `last` really one of our painpoints? > > > > > > Bob > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss
Freedom of choice for the win. I like it.
Freedom of choice for the win. I like it. On Sat, Jan 23, 2016 at 12:46 PM, kdex <kdex at kdex.de> wrote: > @Michał: That really depends on the point of view: If you need zero-based > indexing from the right, as `[]` does from the left, you'd use > `Array.prototype.last`. > > On Samstag, 23. Januar 2016 20:56:02 CET Michał Wadas wrote: >> I can't consider `.last(1)` method to be readable... >> But I think `.nth(n)` method with support for negative index would be >> really useful. >> >> 2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>: >> > Not every feature addition is due to performance or paradigms. Just have a >> > look at ES2015: I'm sure that this has neither been the motivation for >> > `String.prototype.startsWith`nor for `String.prototype.includes`. Even >> > `String.prototype.repeat` appears so simple that a loop paired with a >> > concatenation could have become a popular alternative. >> > >> > Of course you could solve most of these string problems with earlier >> > versions >> > of the language, too, often explicitly thinking with incides. But on the >> > downside, your code suddenly becomes a potentially unintuitive, >> > index-ridden >> > mess, introducing off-by-one and out-of-bound errors (it even happened to >> > someone on this thread, too, if you review Thomas' code from above). This >> > isn't really all too much about saving keystrokes, but mainly about >> > writing >> > clean, readable and maintainable code. >> > >> > There's array::back in C++, negative indices in Python as well as Bash or >> > end >> > in PHP, so I don't see any reason why we should complicate things for >> > people >> > coming from these languages. Nor to I see why we should torture ourselves >> > thinking about how the underlying data structure stores its elements >> > internally when all I care about is reading the last element. >> > >> > Just ask yourself: Do you think it's substantially more readable to write >> > >> > ```js >> > [1, 2, 3].slice(-2)[1]; >> > ``` >> > over >> > ``` >> > [1, 2, 3].last(1); >> > ``` >> > ? >> > >> > If it comes to write access, I agree that`Symbol.last` could be another >> > handy >> > addition (it doesn't have to be an "either/or" discussion, really): >> > >> > [1, 2, 3][Symbol.last]; // 3 >> > [1, 2, 3][Symbol.last] = 4; // 4 >> > [1, 2, 3].last(1); // 2 >> > >> > On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: >> > > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: >> > > > [1, 2, 3].last(); // 3 >> > > >> > > I'm wondering what the ultimate motivation for suggestions like this is. >> > >> > Is >> > >> > > it to save key strokes? Allow more semantic coding? Support new >> > >> > paradigms? >> > >> > > Performance? 'm sure someone has already come up with a good >> > >> > categorization >> > >> > > like this, would someone mind providing a link? Could one of these be >> > > considered the "theme" for the next version? >> > > >> > > I have to admit to be being quite negative about proposals of the form >> > > "Hey, this other language does X, can we do that too?", or "It would be >> > >> > so >> > >> > > cool if we could do Y", especially when these are mostly about syntax. >> > >> > Is a >> > >> > > missing `last` really one of our painpoints? >> > > >> > > Bob >> > >> > _______________________________________________ >> > es-discuss mailing list >> > es-discuss at mozilla.org >> > https://mail.mozilla.org/listinfo/es-discuss > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
On Sat, Jan 23, 2016 at 12:46 PM, kdex <kdex at kdex.de> wrote:
@Michał: That really depends on the point of view: If you need zero-based indexing from the right, as
[]
does from the left, you'd useArray.prototype.last
.On Samstag, 23. Januar 2016 20:56:02 CET Michał Wadas wrote:
I can't consider
.last(1)
method to be readable... But I think.nth(n)
method with support for negative index would be really useful.
you can also slice from the end of an array:
var a = [1,2,3,4]; // Get the second-to-last item. a.slice(-2,-1)
A method to find an item at a given index could be designed.
a.itemAt(-2);
I trimmed the rest. I have enough difficulty with advanced GMail view. I can't get back to Basic HTML view as default. Top posting makes editing a lot harder in GMail Advance View. Plus it auto-saves on every undo/redo, and coupling that with El Capitan, and it's all so slow and clunky.
So I didn't fix yuour top post completely. Because I'm saving my energy up for figuring out how to paste into youtube comments. Man, this web stuff, google… so cutting edge. Wow!
On Sat, Jan 23, 2016 at 12:46 PM, kdex <kdex at kdex.de> wrote: > @Michał: That really depends on the point of view: If you need zero-based > indexing from the right, as `[]` does from the left, you'd use > `Array.prototype.last`. > > On Samstag, 23. Januar 2016 20:56:02 CET Michał Wadas wrote: >> I can't consider `.last(1)` method to be readable... >> But I think `.nth(n)` method with support for negative index would be >> really useful. >> you can also slice from the end of an array: var a = [1,2,3,4]; // Get the second-to-last item. a.slice(-2,-1) A method to find an item at a given index could be designed. a.itemAt(-2); I trimmed the rest. I have enough difficulty with advanced GMail view. I can't get back to Basic HTML view as default. Top posting makes editing a lot harder in GMail Advance View. Plus it auto-saves on every undo/redo, and coupling that with El Capitan, and it's all so slow and clunky. So I didn't fix yuour top post completely. Because I'm saving my energy up for figuring out how to paste into youtube comments. Man, this web stuff, google… so cutting edge. Wow! -- Garrett @xkit ChordCycles.wordpress.com garretts.github.io personx.tumblr.com
I oppose the Symbol approach. It makes code looks ugly just for adding write access. There is already a .push()
, and we only need to add .last()
or .back()
to make it complete.
I oppose the Symbol approach. It makes code looks ugly just for adding write access. There is already a `.push()`, and we only need to add `.last()` or `.back()` to make it complete. > From: kdex at kdex.de > If it comes to write access, I agree that`Symbol.last` could be another handy > addition (it doesn't have to be an "either/or" discussion, really): > > [1, 2, 3][Symbol.last]; // 3 > [1, 2, 3][Symbol.last] = 4; // 4 > [1, 2, 3].last(1); // 2 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160125/ef71bb4a/attachment.html>
Array.prototype.nth(n=0)
looks great indeed, +1 here
About the Symbol ... ugly as hell also we need to write even more and it doesn't scale as utility compared to .nth
a[Symbol.last]
a[a.length-1]
I mean, seriously ... don't even consider that or someone might ask to
implement Symbol.first
with second, third and all others too ... how
about Symbol.odd
/sarcasm
Best
`Array.prototype.nth(n=0)` looks great indeed, +1 here About the Symbol ... ugly as hell also we need to write even more and it doesn't scale as utility compared to .nth ```js a[Symbol.last] a[a.length-1] ``` I mean, seriously ... don't even consider that or someone might ask to implement `Symbol.first` with second, third and all others too ... how about `Symbol.odd` /sarcasm Best Regards On Sat, Jan 23, 2016 at 8:56 PM, Michał Wadas <michalwadas at gmail.com> wrote: > I can't consider `.last(1)` method to be readable... > But I think `.nth(n)` method with support for negative index would be > really useful. > > 2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>: > >> Not every feature addition is due to performance or paradigms. Just have a >> look at ES2015: I'm sure that this has neither been the motivation for >> `String.prototype.startsWith`nor for `String.prototype.includes`. Even >> `String.prototype.repeat` appears so simple that a loop paired with a >> concatenation could have become a popular alternative. >> >> Of course you could solve most of these string problems with earlier >> versions >> of the language, too, often explicitly thinking with incides. But on the >> downside, your code suddenly becomes a potentially unintuitive, >> index-ridden >> mess, introducing off-by-one and out-of-bound errors (it even happened to >> someone on this thread, too, if you review Thomas' code from above). This >> isn't really all too much about saving keystrokes, but mainly about >> writing >> clean, readable and maintainable code. >> >> There's array::back in C++, negative indices in Python as well as Bash or >> end >> in PHP, so I don't see any reason why we should complicate things for >> people >> coming from these languages. Nor to I see why we should torture ourselves >> thinking about how the underlying data structure stores its elements >> internally when all I care about is reading the last element. >> >> Just ask yourself: Do you think it's substantially more readable to write >> >> ```js >> [1, 2, 3].slice(-2)[1]; >> ``` >> over >> ``` >> [1, 2, 3].last(1); >> ``` >> ? >> >> If it comes to write access, I agree that`Symbol.last` could be another >> handy >> addition (it doesn't have to be an "either/or" discussion, really): >> >> [1, 2, 3][Symbol.last]; // 3 >> [1, 2, 3][Symbol.last] = 4; // 4 >> [1, 2, 3].last(1); // 2 >> >> On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: >> > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: >> > > [1, 2, 3].last(); // 3 >> > >> > I'm wondering what the ultimate motivation for suggestions like this >> is. Is >> > it to save key strokes? Allow more semantic coding? Support new >> paradigms? >> > Performance? 'm sure someone has already come up with a good >> categorization >> > like this, would someone mind providing a link? Could one of these be >> > considered the "theme" for the next version? >> > >> > I have to admit to be being quite negative about proposals of the form >> > "Hey, this other language does X, can we do that too?", or "It would be >> so >> > cool if we could do Y", especially when these are mostly about syntax. >> Is a >> > missing `last` really one of our painpoints? >> > >> > Bob >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160125/a8b4ab82/attachment.html>
Nitpicking here, but the nth
method is traditionally named at
, if it were going to be formally proposed
Nitpicking here, but the `nth` method is traditionally named `at`, if it were going to be formally proposed > On Jan 25, 2016, at 3:00 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > > `Array.prototype.nth(n=0)` looks great indeed, +1 here > > About the Symbol ... ugly as hell also we need to write even more and it doesn't scale as utility compared to .nth > > ```js > a[Symbol.last] > a[a.length-1] > ``` > > I mean, seriously ... don't even consider that or someone might ask to implement `Symbol.first` with second, third and all others too ... how about `Symbol.odd` /sarcasm > > Best Regards > > > >> On Sat, Jan 23, 2016 at 8:56 PM, Michał Wadas <michalwadas at gmail.com> wrote: >> I can't consider `.last(1)` method to be readable... >> But I think `.nth(n)` method with support for negative index would be really useful. >> >> 2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>: >>> Not every feature addition is due to performance or paradigms. Just have a >>> look at ES2015: I'm sure that this has neither been the motivation for >>> `String.prototype.startsWith`nor for `String.prototype.includes`. Even >>> `String.prototype.repeat` appears so simple that a loop paired with a >>> concatenation could have become a popular alternative. >>> >>> Of course you could solve most of these string problems with earlier versions >>> of the language, too, often explicitly thinking with incides. But on the >>> downside, your code suddenly becomes a potentially unintuitive, index-ridden >>> mess, introducing off-by-one and out-of-bound errors (it even happened to >>> someone on this thread, too, if you review Thomas' code from above). This >>> isn't really all too much about saving keystrokes, but mainly about writing >>> clean, readable and maintainable code. >>> >>> There's array::back in C++, negative indices in Python as well as Bash or end >>> in PHP, so I don't see any reason why we should complicate things for people >>> coming from these languages. Nor to I see why we should torture ourselves >>> thinking about how the underlying data structure stores its elements >>> internally when all I care about is reading the last element. >>> >>> Just ask yourself: Do you think it's substantially more readable to write >>> >>> ```js >>> [1, 2, 3].slice(-2)[1]; >>> ``` >>> over >>> ``` >>> [1, 2, 3].last(1); >>> ``` >>> ? >>> >>> If it comes to write access, I agree that`Symbol.last` could be another handy >>> addition (it doesn't have to be an "either/or" discussion, really): >>> >>> [1, 2, 3][Symbol.last]; // 3 >>> [1, 2, 3][Symbol.last] = 4; // 4 >>> [1, 2, 3].last(1); // 2 >>> >>> On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: >>> > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: >>> > > [1, 2, 3].last(); // 3 >>> > >>> > I'm wondering what the ultimate motivation for suggestions like this is. Is >>> > it to save key strokes? Allow more semantic coding? Support new paradigms? >>> > Performance? 'm sure someone has already come up with a good categorization >>> > like this, would someone mind providing a link? Could one of these be >>> > considered the "theme" for the next version? >>> > >>> > I have to admit to be being quite negative about proposals of the form >>> > "Hey, this other language does X, can we do that too?", or "It would be so >>> > cool if we could do Y", especially when these are mostly about syntax. Is a >>> > missing `last` really one of our painpoints? >>> > >>> > Bob >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160125/8c2a6936/attachment-0001.html>
FWIW .at
works for me. Anything really, as long as Symbol.last
won't
even be proposed :D
FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't even be proposed :D On Mon, Jan 25, 2016 at 9:33 PM, Caitlin Potter <caitpotter88 at gmail.com> wrote: > Nitpicking here, but the `nth` method is traditionally named `at`, if it > were going to be formally proposed > > On Jan 25, 2016, at 3:00 PM, Andrea Giammarchi < > andrea.giammarchi at gmail.com> wrote: > > `Array.prototype.nth(n=0)` looks great indeed, +1 here > > About the Symbol ... ugly as hell also we need to write even more and it > doesn't scale as utility compared to .nth > > ```js > a[Symbol.last] > a[a.length-1] > ``` > > I mean, seriously ... don't even consider that or someone might ask to > implement `Symbol.first` with second, third and all others too ... how > about `Symbol.odd` /sarcasm > > Best Regards > > > > On Sat, Jan 23, 2016 at 8:56 PM, Michał Wadas <michalwadas at gmail.com> > wrote: > >> I can't consider `.last(1)` method to be readable... >> But I think `.nth(n)` method with support for negative index would be >> really useful. >> >> 2016-01-23 17:32 GMT+01:00 kdex <kdex at kdex.de>: >> >>> Not every feature addition is due to performance or paradigms. Just have >>> a >>> look at ES2015: I'm sure that this has neither been the motivation for >>> `String.prototype.startsWith`nor for `String.prototype.includes`. Even >>> `String.prototype.repeat` appears so simple that a loop paired with a >>> concatenation could have become a popular alternative. >>> >>> Of course you could solve most of these string problems with earlier >>> versions >>> of the language, too, often explicitly thinking with incides. But on the >>> downside, your code suddenly becomes a potentially unintuitive, >>> index-ridden >>> mess, introducing off-by-one and out-of-bound errors (it even happened to >>> someone on this thread, too, if you review Thomas' code from above). This >>> isn't really all too much about saving keystrokes, but mainly about >>> writing >>> clean, readable and maintainable code. >>> >>> There's array::back in C++, negative indices in Python as well as Bash >>> or end >>> in PHP, so I don't see any reason why we should complicate things for >>> people >>> coming from these languages. Nor to I see why we should torture ourselves >>> thinking about how the underlying data structure stores its elements >>> internally when all I care about is reading the last element. >>> >>> Just ask yourself: Do you think it's substantially more readable to write >>> >>> ```js >>> [1, 2, 3].slice(-2)[1]; >>> ``` >>> over >>> ``` >>> [1, 2, 3].last(1); >>> ``` >>> ? >>> >>> If it comes to write access, I agree that`Symbol.last` could be another >>> handy >>> addition (it doesn't have to be an "either/or" discussion, really): >>> >>> [1, 2, 3][Symbol.last]; // 3 >>> [1, 2, 3][Symbol.last] = 4; // 4 >>> [1, 2, 3].last(1); // 2 >>> >>> On Samstag, 23. Januar 2016 18:01:24 CET Bob Myers wrote: >>> > On Sat, Jan 23, 2016 at 12:54 PM, kdex <kdex at kdex.de> wrote: >>> > > [1, 2, 3].last(); // 3 >>> > >>> > I'm wondering what the ultimate motivation for suggestions like this >>> is. Is >>> > it to save key strokes? Allow more semantic coding? Support new >>> paradigms? >>> > Performance? 'm sure someone has already come up with a good >>> categorization >>> > like this, would someone mind providing a link? Could one of these be >>> > considered the "theme" for the next version? >>> > >>> > I have to admit to be being quite negative about proposals of the form >>> > "Hey, this other language does X, can we do that too?", or "It would >>> be so >>> > cool if we could do Y", especially when these are mostly about syntax. >>> Is a >>> > missing `last` really one of our painpoints? >>> > >>> > Bob >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160125/0c53bfde/attachment.html>
On 01/25/2016 12:00, Andrea Giammarchi wrote:
Array.prototype.nth(n=0)
looks great indeed, +1 hereAbout the Symbol ... ugly as hell also we need to write even more and it doesn't scale as utility compared to .nth
a[Symbol.last] a[a.length-1]
I fail to see the point of this, other than trying to increase the complexity of the language by adding even more cases which do the same things but work somewhat differently from existing cases.
We'd have done a lot of things differently if we were starting from scratch. But arrays have a large amount of legacy behavior we can't realistically change and, given that, this doesn't improve things much.
Waldemar
On 01/25/2016 12:00, Andrea Giammarchi wrote: > `Array.prototype.nth(n=0)` looks great indeed, +1 here > > About the Symbol ... ugly as hell also we need to write even more and it doesn't scale as utility compared to .nth > > ```js > a[Symbol.last] > a[a.length-1] > ``` I fail to see the point of this, other than trying to increase the complexity of the language by adding even more cases which do the same things but work somewhat differently from existing cases. We'd have done a lot of things differently if we were starting from scratch. But arrays have a large amount of legacy behavior we can't realistically change and, given that, this doesn't improve things much. Waldemar
The syntactical construct array()
is unused as far as I know, since
currently it would always generate a syntax error--an array is not a
function. Thus we can use this as in
[1,2,3](-1)
Shouldn't break anything.
Bob
The syntactical construct `array()` is unused as far as I know, since currently it would always generate a syntax error--an array is not a function. Thus we can use this as in ``` [1,2,3](-1) ``` Shouldn't break anything. Bob On Tue, Jan 26, 2016 at 2:08 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote: > FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't > even be proposed :D > > On Mon, Jan 25, 2016 at 9:33 PM, Caitlin Potter <caitpotter88 at gmail.com> > wrote: > >> Nitpicking here, but the `nth` method is traditionally named `at`, if it >> were going to be formally proposed >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160126/5dc7cc40/attachment.html>
But it implies a function call, which isn't the case. It could possibly be confusing when reading code.
> [1,2,3](-1) But it implies a function call, which isn't the case. It could possibly be confusing when reading code. On Mon, Jan 25, 2016 at 1:04 PM, Bob Myers <rtm at gol.com> wrote: > The syntactical construct `array()` is unused as far as I know, since > currently it would always generate a syntax error--an array is not a > function. Thus we can use this as in > > ``` > [1,2,3](-1) > ``` > > Shouldn't break anything. > > Bob > > On Tue, Jan 26, 2016 at 2:08 AM, Andrea Giammarchi > <andrea.giammarchi at gmail.com> wrote: >> >> FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't >> even be proposed :D >> >> On Mon, Jan 25, 2016 at 9:33 PM, Caitlin Potter <caitpotter88 at gmail.com> >> wrote: >>> >>> Nitpicking here, but the `nth` method is traditionally named `at`, if it >>> were going to be formally proposed >>> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
Bob Myers schrieb:
The syntactical construct
array()
is unused as far as I know, since currently it would always generate a syntax error--an array is not a function.
It's a runtime TypeError
rather.
Thus we can use this as in
[1,2,3](-1)
Shouldn't break anything.
This would break much more than a last
getter/method or nth
/at
method.
Arrays becoming callable would mean that their typeof
changes from
"object"
to "function"
, which is a very bad idea.
, Bergi
Bob Myers schrieb: > The syntactical construct `array()` is unused as far as I know, since > currently it would always generate a syntax error--an array is not a > function. It's a runtime `TypeError` rather. > Thus we can use this as in > > ``` > [1,2,3](-1) > ``` > > Shouldn't break anything. This would break much more than a `last` getter/method or `nth`/`at` method. Arrays becoming callable would mean that their `typeof` changes from `"object"` to `"function"`, which is a very bad idea. Regards, Bergi
Not sure if you are talking about Array.prototype or Symbols but whatever worry you have is identical. Having a Symbol in the prototype or adding a method ... I don't see much difference. Which one is best? History shows it's the method. It plays well, it's easy to polyfill, no complexity added ... is just an Array.prototype.method.
We can survive witohut the .at or .nth like we've done long time, but if a library would add such prototype I won't blame it. Prototype and others made most of ES5, after all, and I think for good, common, useful, use cases.
I'm also off this conversation since I don't have any strong need for such method.
Not sure if you are talking about Array.prototype or Symbols but whatever worry you have is identical. Having a Symbol in the prototype or adding a method ... I don't see much difference. Which one is best? History shows it's the method. It plays well, it's easy to polyfill, no complexity added ... is just an Array.prototype.method. We can survive witohut the .at or .nth like we've done long time, but if a library would add such prototype I won't blame it. Prototype and others made most of ES5, after all, and I think for good, common, useful, use cases. I'm also off this conversation since I don't have any strong need for such method. Regards On Mon, Jan 25, 2016 at 9:57 PM, Waldemar Horwat <waldemar at google.com> wrote: > On 01/25/2016 12:00, Andrea Giammarchi wrote: > >> `Array.prototype.nth(n=0)` looks great indeed, +1 here >> >> About the Symbol ... ugly as hell also we need to write even more and it >> doesn't scale as utility compared to .nth >> >> ```js >> a[Symbol.last] >> a[a.length-1] >> ``` >> > > I fail to see the point of this, other than trying to increase the > complexity of the language by adding even more cases which do the same > things but work somewhat differently from existing cases. > > We'd have done a lot of things differently if we were starting from > scratch. But arrays have a large amount of legacy behavior we can't > realistically change and, given that, this doesn't improve things much. > > Waldemar > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160125/173882cd/attachment.html>
[1,2,3](-1)
I will not beat this dead horse further, and it may be visually undesirable, and/or hard to implement, but for what it's worth, the idea is not to make arrays callable; it's just new syntax to allow parenthesized expressions following arrays, which would be interpreted as an index whose value to extract, with negative values meaning to go from the end.
``` [1,2,3](-1) ``` I will not beat this dead horse further, and it may be visually undesirable, and/or hard to implement, but for what it's worth, the idea is not to make arrays callable; it's just new syntax to allow parenthesized expressions following arrays, which would be interpreted as an index whose value to extract, with negative values meaning to go from the end. On Tue, Jan 26, 2016 at 4:19 AM, Bergi <a.d.bergi at web.de> wrote: > Bob Myers schrieb: > >> The syntactical construct `array()` is unused as far as I know, since >> currently it would always generate a syntax error--an array is not a >> function. >> > > Thus we can use this as in >> >> ``` >> [1,2,3](-1) >> ``` >> >> Shouldn't break anything. >> > > This would break much more than a `last` getter/method or `nth`/`at` > method. > Arrays becoming callable would mean that their `typeof` changes from > `"object"` to `"function"`, which is a very bad idea. > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160126/bec8dff3/attachment-0001.html>
On Mon, Jan 25, 2016 at 12:38 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:
FWIW
.at
works for me. Anything really, as long asSymbol.last
won't even be proposed :D
If we name it .item
that would mean that a whole bunch of DOM
classes could be replaced with plain JS Arrays.
For example FileList, MessagePortList, DOMRectList, TouchList, etc.
It would also mean API compatibility with a whole lot of more APIs, like NodeList, DOMTokenList and CSSValueList. While we couldn't replace these with actual Arrays (for varying reasons), we'd end up with classes that have more API surface in common.
/ Jonas
On Mon, Jan 25, 2016 at 12:38 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't > even be proposed :D If we name it `.item` that would mean that a whole bunch of DOM classes could be replaced with plain JS Arrays. For example FileList, MessagePortList, DOMRectList, TouchList, etc. It would also mean API compatibility with a whole lot of more APIs, like NodeList, DOMTokenList and CSSValueList. While we couldn't replace these with actual Arrays (for varying reasons), we'd end up with classes that have more API surface in common. / Jonas
On Tue, Feb 2, 2016 at 12:15 PM, Jonas Sicking <jonas at sicking.cc> wrote:
On Mon, Jan 25, 2016 at 12:38 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:
FWIW
.at
works for me. Anything really, as long asSymbol.last
won't even be proposed :DIf we name it
.item
that would mean that a whole bunch of DOM classes could be replaced with plain JS Arrays.For example FileList, MessagePortList, DOMRectList, TouchList, etc.
It would also mean API compatibility with a whole lot of more APIs, like NodeList, DOMTokenList and CSSValueList. While we couldn't replace these with actual Arrays (for varying reasons), we'd end up with classes that have more API surface in common.
I love a good bird-killing stone. ^_^ Let's do this!
On Tue, Feb 2, 2016 at 12:15 PM, Jonas Sicking <jonas at sicking.cc> wrote: > On Mon, Jan 25, 2016 at 12:38 PM, Andrea Giammarchi > <andrea.giammarchi at gmail.com> wrote: >> FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't >> even be proposed :D > > If we name it `.item` that would mean that a whole bunch of DOM > classes could be replaced with plain JS Arrays. > > For example FileList, MessagePortList, DOMRectList, TouchList, etc. > > It would also mean API compatibility with a whole lot of more APIs, > like NodeList, DOMTokenList and CSSValueList. While we couldn't > replace these with actual Arrays (for varying reasons), we'd end up > with classes that have more API surface in common. I love a good bird-killing stone. ^_^ Let's do this! ~TJ
Another possibility is Array.prototype.get()
, which would be in line with ES6 Maps.
Another possibility is `Array.prototype.get()`, which would be in line with ES6 Maps. > On 02 Feb 2016, at 21:15, Jonas Sicking <jonas at sicking.cc> wrote: > > On Mon, Jan 25, 2016 at 12:38 PM, Andrea Giammarchi > <andrea.giammarchi at gmail.com> wrote: >> FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't >> even be proposed :D > > If we name it `.item` that would mean that a whole bunch of DOM > classes could be replaced with plain JS Arrays. > > For example FileList, MessagePortList, DOMRectList, TouchList, etc. > > It would also mean API compatibility with a whole lot of more APIs, > like NodeList, DOMTokenList and CSSValueList. While we couldn't > replace these with actual Arrays (for varying reasons), we'd end up > with classes that have more API surface in common. -- Dr. Axel Rauschmayer axel at rauschma.de rauschma.de
We cam make this simpler, in Javascript Array.slice() already accept negative index. Developers from Javascript and other languages are familiar with negative value for index parameter. So why cant we make array accept negative index.
in comparison with Bob Myers' proposal
[1,2,3](-1)
will become
[1,2,3][-1]
This will also allow us to set value using negative index, example
var array_data = [1, 2, 3, 4]; array_data[-1] = 5; array_data[-3] = 6;
// now array_data is [1, 6, 3, 5]
We cam make this simpler, in Javascript Array.slice() already accept negative index. Developers from Javascript and other languages are familiar with negative value for index parameter. So why cant we make array accept negative index. in comparison with Bob Myers' proposal > ``` > [1,2,3](-1) > ``` will become ``` [1,2,3][-1] ``` This will also allow us to set value using negative index, example var array_data = [1, 2, 3, 4]; array_data[-1] = 5; array_data[-3] = 6; // now array_data is [1, 6, 3, 5]
That would break backward compatibility;
var a = ['a'];
a['-1'] = 'test';
Object.keys(a) // ['0', '-1']
That would break backward compatibility; ```js var a = ['a']; a['-1'] = 'test'; Object.keys(a) // ['0', '-1'] ``` On Sun, Apr 17, 2016 at 11:53 AM, Biju <bijumaillist at gmail.com> wrote: > We cam make this simpler, in Javascript Array.slice() already accept > negative index. > Developers from Javascript and other languages are familiar with > negative value for index parameter. > So why cant we make array accept negative index. > > in comparison with Bob Myers' proposal > > > ``` > > [1,2,3](-1) > > ``` > > will become > > ``` > [1,2,3][-1] > ``` > > This will also allow us to set value using negative index, > example > > var array_data = [1, 2, 3, 4]; > array_data[-1] = 5; > array_data[-3] = 6; > > // now array_data is [1, 6, 3, 5] > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160417/b56d7bf8/attachment.html>
On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> wrote:
That would break backward compatibility;
var a = ['a']; a['-1'] = 'test'; Object.keys(a) // ['0', '-1']
Do we have statistics how many sties depend on that?
On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> wrote: > That would break backward compatibility; > > ```js > var a = ['a']; > a['-1'] = 'test'; > Object.keys(a) // ['0', '-1'] > ``` Do we have statistics how many sties depend on that?
Backwards compatibility has been broken before. I don't think this one is too bad of a breakage.
Backwards compatibility has been broken before. I don't think this one is too bad of a breakage. On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> wrote: > On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> wrote: >> That would break backward compatibility; >> >> ```js >> var a = ['a']; >> a['-1'] = 'test'; >> Object.keys(a) // ['0', '-1'] >> ``` > > Do we have statistics how many sties depend on that? > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
I don't see a good reason why to mangle with this. Note that you can achieve this behavior without breaking backwards compatibility with ES6 Proxies:
class MyArray extends Array {
constructor(...args) {
super(...args);
function computeProperty(target, property) {
const index = +property;
return index < 0 ? String(target.length + index) : property;
}
return new Proxy(this, {
get(target, property, receiver) {
return Reflect.get(target, computeProperty(target, property), receiver);
},
set(target, property, receiver) {
return Reflect.set(target, computeProperty(target, property), receiver);
}
});
}
}
I don't see a good reason why to mangle with this. Note that you can achieve this behavior without breaking backwards compatibility with ES6 Proxies: ```js class MyArray extends Array { constructor(...args) { super(...args); function computeProperty(target, property) { const index = +property; return index < 0 ? String(target.length + index) : property; } return new Proxy(this, { get(target, property, receiver) { return Reflect.get(target, computeProperty(target, property), receiver); }, set(target, property, receiver) { return Reflect.set(target, computeProperty(target, property), receiver); } }); } } ``` On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: > Backwards compatibility has been broken before. I don't think this one > is too bad of a breakage. > > On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> wrote: > > On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> wrote: > >> That would break backward compatibility; > >> > >> ```js > >> var a = ['a']; > >> a['-1'] = 'test'; > >> Object.keys(a) // ['0', '-1'] > >> ``` > > > > Do we have statistics how many sties depend on that? > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
But, can
let a = [1,2,3]
create a new MyArray? Maybe, instead of having negative indices by default (which breaks some backwards compatibility) we can introduce a symbol for overriding property access? Something like
Array.prototype[Symbol.propertyAccess] = function(index) {
if (index < 0) ...
else ...
}
? Just an idea; I'm not sure if that's a good use for Symbols. We could then easily add this helper code to a given app.
But, can ```js let a = [1,2,3] ``` create a new MyArray? Maybe, instead of having negative indices by default (which breaks some backwards compatibility) we can introduce a symbol for overriding property access? Something like ```js Array.prototype[Symbol.propertyAccess] = function(index) { if (index < 0) ... else ... } ``` ? Just an idea; I'm not sure if that's a good use for Symbols. We could then easily add this helper code to a given app. On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: > I don't see a good reason why to mangle with this. > Note that you can achieve this behavior without breaking backwards compatibility with ES6 Proxies: > > ```js > class MyArray extends Array { > constructor(...args) { > super(...args); > function computeProperty(target, property) { > const index = +property; > return index < 0 ? String(target.length + index) : property; > } > return new Proxy(this, { > get(target, property, receiver) { > return Reflect.get(target, computeProperty(target, property), receiver); > }, > set(target, property, receiver) { > return Reflect.set(target, computeProperty(target, property), receiver); > } > }); > } > } > ``` > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: >> Backwards compatibility has been broken before. I don't think this one >> is too bad of a breakage. >> >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> wrote: >> > On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> wrote: >> >> That would break backward compatibility; >> >> >> >> ```js >> >> var a = ['a']; >> >> a['-1'] = 'test'; >> >> Object.keys(a) // ['0', '-1'] >> >> ``` >> > >> > Do we have statistics how many sties depend on that? >> > _______________________________________________ >> > es-discuss mailing list >> > es-discuss at mozilla.org >> > https://mail.mozilla.org/listinfo/es-discuss >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
Yes, now we're heading in the right direction.
The problem with something like Symbol.propertyAccess
is that this might lead to a flood of new well-known Symbols.
Conceptually, Symbol.propertyAccess
sounds like it should have been a Proxy
trap, anyway.
Here's an more general idea: Why not allow users to set a derived class for literals via well-known Symbols?
Thus, users could provide custom implementations for RegExp
, Array
, Object
(…) literals, as long as the value points to a derived class.
We could even introduce negative array indices in a way that doesn't break the web like this:
[1, 2, 3][-1]; // undefined
Array[Symbol.implementation] = MyArray;
[1, 2, 3][-1]; // 3
Array[Symbol.implementation] = 3; // TypeError: Array implementations must extend Array (→ Array.isPrototypeOf(Number(3)) is false)
Yes, now we're heading in the right direction. The problem with something like `Symbol.propertyAccess` is that this might lead to a flood of new well-known Symbols. Conceptually, `Symbol.propertyAccess` sounds like it should have been a `Proxy` trap, anyway. Here's an more general idea: Why not allow users to set a derived class for literals via well-known Symbols? Thus, users could provide custom implementations for `RegExp`, `Array`, `Object` (…) literals, as long as the value points to a derived class. We could even introduce negative array indices in a way that doesn't break the web like this: ```js [1, 2, 3][-1]; // undefined Array[Symbol.implementation] = MyArray; [1, 2, 3][-1]; // 3 Array[Symbol.implementation] = 3; // TypeError: Array implementations must extend Array (→ Array.isPrototypeOf(Number(3)) is false) ``` On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: > But, can > > ```js > let a = [1,2,3] > ``` > > create a new MyArray? Maybe, instead of having negative indices by > default (which breaks some backwards compatibility) we can introduce a > symbol for overriding property access? Something like > > ```js > Array.prototype[Symbol.propertyAccess] = function(index) { > if (index < 0) ... > else ... > } > ``` > > ? Just an idea; I'm not sure if that's a good use for Symbols. We > could then easily add this helper code to a given app. > > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: > > I don't see a good reason why to mangle with this. > > Note that you can achieve this behavior without breaking backwards compatibility with ES6 Proxies: > > > > ```js > > class MyArray extends Array { > > constructor(...args) { > > super(...args); > > function computeProperty(target, property) { > > const index = +property; > > return index < 0 ? String(target.length + index) : property; > > } > > return new Proxy(this, { > > get(target, property, receiver) { > > return Reflect.get(target, computeProperty(target, property), receiver); > > }, > > set(target, property, receiver) { > > return Reflect.set(target, computeProperty(target, property), receiver); > > } > > }); > > } > > } > > ``` > > > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: > >> Backwards compatibility has been broken before. I don't think this one > >> is too bad of a breakage. > >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> wrote: > >> > On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> wrote: > >> >> That would break backward compatibility; > >> >> > >> >> ```js > >> >> var a = ['a']; > >> >> a['-1'] = 'test'; > >> >> Object.keys(a) // ['0', '-1'] > >> >> ``` > >> > > >> > Do we have statistics how many sties depend on that? > >> > _______________________________________________ > >> > es-discuss mailing list > >> > es-discuss at mozilla.org > >> > https://mail.mozilla.org/listinfo/es-discuss > >> _______________________________________________ > >> es-discuss mailing list > >> es-discuss at mozilla.org > >> https://mail.mozilla.org/listinfo/es-discuss > >> > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss >
That would mean all other programs executing on the page would be forced to use that Array implementation, imposing potentially critical problems with, for example, performance and expected behavior. It's just not a good idea.
I missed off esdiscuss when I replied earlier, but I mentioned that the only reasonable solution is to introduce new syntax, e.g.
myArray[:-1]
However, it's been said that there needs to be a compelling reason to add new syntax and I'm not sure this qualifies imo.
That would mean all other programs executing on the page would be forced to use that Array implementation, imposing potentially critical problems with, for example, performance and expected behavior. It's just not a good idea. I missed off esdiscuss when I replied earlier, but I mentioned that the only reasonable solution is to introduce new syntax, e.g. myArray[:-1] However, it's been said that there needs to be a compelling reason to add new syntax and I'm not sure this qualifies imo. On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: > Yes, now we're heading in the right direction. > > The problem with something like `Symbol.propertyAccess` is that this might > lead to a flood of new well-known Symbols. > Conceptually, `Symbol.propertyAccess` sounds like it should have been a > `Proxy` trap, anyway. > > Here's an more general idea: Why not allow users to set a derived class > for literals via well-known Symbols? > Thus, users could provide custom implementations for `RegExp`, `Array`, > `Object` (…) literals, as long as the value points to a derived class. > > We could even introduce negative array indices in a way that doesn't break > the web like this: > > ```js > [1, 2, 3][-1]; // undefined > Array[Symbol.implementation] = MyArray; > [1, 2, 3][-1]; // 3 > Array[Symbol.implementation] = 3; // TypeError: Array implementations must > extend Array (→ Array.isPrototypeOf(Number(3)) is false) > ``` > > On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: > > But, can > > > > ```js > > let a = [1,2,3] > > ``` > > > > create a new MyArray? Maybe, instead of having negative indices by > > default (which breaks some backwards compatibility) we can introduce a > > symbol for overriding property access? Something like > > > > ```js > > Array.prototype[Symbol.propertyAccess] = function(index) { > > if (index < 0) ... > > else ... > > } > > ``` > > > > ? Just an idea; I'm not sure if that's a good use for Symbols. We > > could then easily add this helper code to a given app. > > > > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: > > > I don't see a good reason why to mangle with this. > > > Note that you can achieve this behavior without breaking backwards > compatibility with ES6 Proxies: > > > > > > ```js > > > class MyArray extends Array { > > > constructor(...args) { > > > super(...args); > > > function computeProperty(target, property) { > > > const index = +property; > > > return index < 0 ? String(target.length + > index) : property; > > > } > > > return new Proxy(this, { > > > get(target, property, receiver) { > > > return Reflect.get(target, > computeProperty(target, property), receiver); > > > }, > > > set(target, property, receiver) { > > > return Reflect.set(target, > computeProperty(target, property), receiver); > > > } > > > }); > > > } > > > } > > > ``` > > > > > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: > > >> Backwards compatibility has been broken before. I don't think this one > > >> is too bad of a breakage. > > >> > > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> wrote: > > >> > On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> > wrote: > > >> >> That would break backward compatibility; > > >> >> > > >> >> ```js > > >> >> var a = ['a']; > > >> >> a['-1'] = 'test'; > > >> >> Object.keys(a) // ['0', '-1'] > > >> >> ``` > > >> > > > >> > Do we have statistics how many sties depend on that? > > >> > _______________________________________________ > > >> > es-discuss mailing list > > >> > es-discuss at mozilla.org > > >> > https://mail.mozilla.org/listinfo/es-discuss > > >> _______________________________________________ > > >> es-discuss mailing list > > >> es-discuss at mozilla.org > > >> https://mail.mozilla.org/listinfo/es-discuss > > >> > > > _______________________________________________ > > > es-discuss mailing list > > > es-discuss at mozilla.org > > > https://mail.mozilla.org/listinfo/es-discuss > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160418/c36f6963/attachment-0001.html>
Array[Symbol.implementation] = MyArray;
That would mean all other programs executing on the page would be forced to use that Array implementation
And also with my suggestion that would impact all code too.
Would it be possible to limit the effect of using certain symbols to a scope where the symbol is used? For example:
function main() {
Array[Symbol.implementation] = MyArray;
let a = [1,2,3] // uses MyArray
}
let a = [1,2,3] // uses Array
main()
or
Array[Symbol.implementation] = MyArray;
function main() {
let a = [1,2,3] // uses MyArray, from outer scope
}
let a = [1,2,3] // uses MyArray
main()
Or maybe some other method on a per-scope basis?
> ```js > Array[Symbol.implementation] = MyArray; > ``` > That would mean all other programs executing on the page would be forced to use that Array implementation And also with my suggestion that would impact all code too. Would it be possible to limit the effect of using certain symbols to a scope where the symbol is used? For example: ```js function main() { Array[Symbol.implementation] = MyArray; let a = [1,2,3] // uses MyArray } let a = [1,2,3] // uses Array main() ``` or ```js Array[Symbol.implementation] = MyArray; function main() { let a = [1,2,3] // uses MyArray, from outer scope } let a = [1,2,3] // uses MyArray main() ``` Or maybe some other method on a per-scope basis? On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw <andyearnshaw at gmail.com> wrote: > That would mean all other programs executing on the page would be forced to > use that Array implementation, imposing potentially critical problems with, > for example, performance and expected behavior. It's just not a good idea. > > I missed off esdiscuss when I replied earlier, but I mentioned that the only > reasonable solution is to introduce new syntax, e.g. > > myArray[:-1] > > However, it's been said that there needs to be a compelling reason to add > new syntax and I'm not sure this qualifies imo. > > > On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: >> >> Yes, now we're heading in the right direction. >> >> The problem with something like `Symbol.propertyAccess` is that this might >> lead to a flood of new well-known Symbols. >> Conceptually, `Symbol.propertyAccess` sounds like it should have been a >> `Proxy` trap, anyway. >> >> Here's an more general idea: Why not allow users to set a derived class >> for literals via well-known Symbols? >> Thus, users could provide custom implementations for `RegExp`, `Array`, >> `Object` (…) literals, as long as the value points to a derived class. >> >> We could even introduce negative array indices in a way that doesn't break >> the web like this: >> >> ```js >> [1, 2, 3][-1]; // undefined >> Array[Symbol.implementation] = MyArray; >> [1, 2, 3][-1]; // 3 >> Array[Symbol.implementation] = 3; // TypeError: Array implementations must >> extend Array (→ Array.isPrototypeOf(Number(3)) is false) >> ``` >> >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: >> > But, can >> > >> > ```js >> > let a = [1,2,3] >> > ``` >> > >> > create a new MyArray? Maybe, instead of having negative indices by >> > default (which breaks some backwards compatibility) we can introduce a >> > symbol for overriding property access? Something like >> > >> > ```js >> > Array.prototype[Symbol.propertyAccess] = function(index) { >> > if (index < 0) ... >> > else ... >> > } >> > ``` >> > >> > ? Just an idea; I'm not sure if that's a good use for Symbols. We >> > could then easily add this helper code to a given app. >> > >> > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: >> > > I don't see a good reason why to mangle with this. >> > > Note that you can achieve this behavior without breaking backwards >> > > compatibility with ES6 Proxies: >> > > >> > > ```js >> > > class MyArray extends Array { >> > > constructor(...args) { >> > > super(...args); >> > > function computeProperty(target, property) { >> > > const index = +property; >> > > return index < 0 ? String(target.length + >> > > index) : property; >> > > } >> > > return new Proxy(this, { >> > > get(target, property, receiver) { >> > > return Reflect.get(target, >> > > computeProperty(target, property), receiver); >> > > }, >> > > set(target, property, receiver) { >> > > return Reflect.set(target, >> > > computeProperty(target, property), receiver); >> > > } >> > > }); >> > > } >> > > } >> > > ``` >> > > >> > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: >> > >> Backwards compatibility has been broken before. I don't think this >> > >> one >> > >> is too bad of a breakage. >> > >> >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> wrote: >> > >> > On 17 April 2016 at 17:29, Frankie Bagnardi <f.bagnardi at gmail.com> >> > >> > wrote: >> > >> >> That would break backward compatibility; >> > >> >> >> > >> >> ```js >> > >> >> var a = ['a']; >> > >> >> a['-1'] = 'test'; >> > >> >> Object.keys(a) // ['0', '-1'] >> > >> >> ``` >> > >> > >> > >> > Do we have statistics how many sties depend on that? >> > >> > _______________________________________________ >> > >> > es-discuss mailing list >> > >> > es-discuss at mozilla.org >> > >> > https://mail.mozilla.org/listinfo/es-discuss >> > >> _______________________________________________ >> > >> es-discuss mailing list >> > >> es-discuss at mozilla.org >> > >> https://mail.mozilla.org/listinfo/es-discuss >> > >> >> > > _______________________________________________ >> > > es-discuss mailing list >> > > es-discuss at mozilla.org >> > > https://mail.mozilla.org/listinfo/es-discuss >> > >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss
I don't think that would be trivial to implement and there might not be a common enough use case for it. You might want to look into something like sweetjs.org if it's the syntactic sugar you're looking for.
I don't think that would be trivial to implement and there might not be a common enough use case for it. You might want to look into something like http://sweetjs.org if it's the syntactic sugar you're looking for. On Mon, 18 Apr 2016 19:35 /#!/JoePea, <joe at trusktr.io> wrote: > > ```js > > Array[Symbol.implementation] = MyArray; > > ``` > > > That would mean all other programs executing on the page would be forced > to use that Array implementation > > And also with my suggestion that would impact all code too. > > Would it be possible to limit the effect of using certain symbols to a > scope where the symbol is used? For example: > > ```js > function main() { > Array[Symbol.implementation] = MyArray; > > let a = [1,2,3] // uses MyArray > } > let a = [1,2,3] // uses Array > main() > ``` > > or > > ```js > Array[Symbol.implementation] = MyArray; > function main() { > let a = [1,2,3] // uses MyArray, from outer scope > } > let a = [1,2,3] // uses MyArray > main() > ``` > > Or maybe some other method on a per-scope basis? > > On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw <andyearnshaw at gmail.com> > wrote: > > That would mean all other programs executing on the page would be forced > to > > use that Array implementation, imposing potentially critical problems > with, > > for example, performance and expected behavior. It's just not a good > idea. > > > > I missed off esdiscuss when I replied earlier, but I mentioned that the > only > > reasonable solution is to introduce new syntax, e.g. > > > > myArray[:-1] > > > > However, it's been said that there needs to be a compelling reason to add > > new syntax and I'm not sure this qualifies imo. > > > > > > On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: > >> > >> Yes, now we're heading in the right direction. > >> > >> The problem with something like `Symbol.propertyAccess` is that this > might > >> lead to a flood of new well-known Symbols. > >> Conceptually, `Symbol.propertyAccess` sounds like it should have been a > >> `Proxy` trap, anyway. > >> > >> Here's an more general idea: Why not allow users to set a derived class > >> for literals via well-known Symbols? > >> Thus, users could provide custom implementations for `RegExp`, `Array`, > >> `Object` (…) literals, as long as the value points to a derived class. > >> > >> We could even introduce negative array indices in a way that doesn't > break > >> the web like this: > >> > >> ```js > >> [1, 2, 3][-1]; // undefined > >> Array[Symbol.implementation] = MyArray; > >> [1, 2, 3][-1]; // 3 > >> Array[Symbol.implementation] = 3; // TypeError: Array implementations > must > >> extend Array (→ Array.isPrototypeOf(Number(3)) is false) > >> ``` > >> > >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: > >> > But, can > >> > > >> > ```js > >> > let a = [1,2,3] > >> > ``` > >> > > >> > create a new MyArray? Maybe, instead of having negative indices by > >> > default (which breaks some backwards compatibility) we can introduce a > >> > symbol for overriding property access? Something like > >> > > >> > ```js > >> > Array.prototype[Symbol.propertyAccess] = function(index) { > >> > if (index < 0) ... > >> > else ... > >> > } > >> > ``` > >> > > >> > ? Just an idea; I'm not sure if that's a good use for Symbols. We > >> > could then easily add this helper code to a given app. > >> > > >> > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: > >> > > I don't see a good reason why to mangle with this. > >> > > Note that you can achieve this behavior without breaking backwards > >> > > compatibility with ES6 Proxies: > >> > > > >> > > ```js > >> > > class MyArray extends Array { > >> > > constructor(...args) { > >> > > super(...args); > >> > > function computeProperty(target, property) { > >> > > const index = +property; > >> > > return index < 0 ? String(target.length + > >> > > index) : property; > >> > > } > >> > > return new Proxy(this, { > >> > > get(target, property, receiver) { > >> > > return Reflect.get(target, > >> > > computeProperty(target, property), receiver); > >> > > }, > >> > > set(target, property, receiver) { > >> > > return Reflect.set(target, > >> > > computeProperty(target, property), receiver); > >> > > } > >> > > }); > >> > > } > >> > > } > >> > > ``` > >> > > > >> > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: > >> > >> Backwards compatibility has been broken before. I don't think this > >> > >> one > >> > >> is too bad of a breakage. > >> > >> > >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> > wrote: > >> > >> > On 17 April 2016 at 17:29, Frankie Bagnardi < > f.bagnardi at gmail.com> > >> > >> > wrote: > >> > >> >> That would break backward compatibility; > >> > >> >> > >> > >> >> ```js > >> > >> >> var a = ['a']; > >> > >> >> a['-1'] = 'test'; > >> > >> >> Object.keys(a) // ['0', '-1'] > >> > >> >> ``` > >> > >> > > >> > >> > Do we have statistics how many sties depend on that? > >> > >> > _______________________________________________ > >> > >> > es-discuss mailing list > >> > >> > es-discuss at mozilla.org > >> > >> > https://mail.mozilla.org/listinfo/es-discuss > >> > >> _______________________________________________ > >> > >> es-discuss mailing list > >> > >> es-discuss at mozilla.org > >> > >> https://mail.mozilla.org/listinfo/es-discuss > >> > >> > >> > > _______________________________________________ > >> > > es-discuss mailing list > >> > > es-discuss at mozilla.org > >> > > https://mail.mozilla.org/listinfo/es-discuss > >> > > >> _______________________________________________ > >> es-discuss mailing list > >> es-discuss at mozilla.org > >> https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160418/5925c4c1/attachment-0001.html>
Symbol.implementation
should be fairly trivial to implement once Realms are around, without affecting global scope.
`Symbol.implementation` should be fairly trivial to implement once [Realm](https://github.com/caridy/proposal-realms)s are around, without affecting global scope. On Montag, 18. April 2016 18:58:06 CEST Andy Earnshaw wrote: > I don't think that would be trivial to implement and there might not be a > common enough use case for it. You might want to look into something like > http://sweetjs.org if it's the syntactic sugar you're looking for. > > On Mon, 18 Apr 2016 19:35 /#!/JoePea, <joe at trusktr.io> wrote: > > > > ```js > > > Array[Symbol.implementation] = MyArray; > > > ``` > > > > > That would mean all other programs executing on the page would be forced > > to use that Array implementation > > > > And also with my suggestion that would impact all code too. > > > > Would it be possible to limit the effect of using certain symbols to a > > scope where the symbol is used? For example: > > > > ```js > > function main() { > > Array[Symbol.implementation] = MyArray; > > > > let a = [1,2,3] // uses MyArray > > } > > let a = [1,2,3] // uses Array > > main() > > ``` > > > > or > > > > ```js > > Array[Symbol.implementation] = MyArray; > > function main() { > > let a = [1,2,3] // uses MyArray, from outer scope > > } > > let a = [1,2,3] // uses MyArray > > main() > > ``` > > > > Or maybe some other method on a per-scope basis? > > > > On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw <andyearnshaw at gmail.com> > > wrote: > > > That would mean all other programs executing on the page would be forced > > to > > > use that Array implementation, imposing potentially critical problems > > with, > > > for example, performance and expected behavior. It's just not a good > > idea. > > > > > > I missed off esdiscuss when I replied earlier, but I mentioned that the > > only > > > reasonable solution is to introduce new syntax, e.g. > > > > > > myArray[:-1] > > > > > > However, it's been said that there needs to be a compelling reason to add > > > new syntax and I'm not sure this qualifies imo. > > > > > > > > > On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: > > >> > > >> Yes, now we're heading in the right direction. > > >> > > >> The problem with something like `Symbol.propertyAccess` is that this > > might > > >> lead to a flood of new well-known Symbols. > > >> Conceptually, `Symbol.propertyAccess` sounds like it should have been a > > >> `Proxy` trap, anyway. > > >> > > >> Here's an more general idea: Why not allow users to set a derived class > > >> for literals via well-known Symbols? > > >> Thus, users could provide custom implementations for `RegExp`, `Array`, > > >> `Object` (…) literals, as long as the value points to a derived class. > > >> > > >> We could even introduce negative array indices in a way that doesn't > > break > > >> the web like this: > > >> > > >> ```js > > >> [1, 2, 3][-1]; // undefined > > >> Array[Symbol.implementation] = MyArray; > > >> [1, 2, 3][-1]; // 3 > > >> Array[Symbol.implementation] = 3; // TypeError: Array implementations > > must > > >> extend Array (→ Array.isPrototypeOf(Number(3)) is false) > > >> ``` > > >> > > >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: > > >> > But, can > > >> > > > >> > ```js > > >> > let a = [1,2,3] > > >> > ``` > > >> > > > >> > create a new MyArray? Maybe, instead of having negative indices by > > >> > default (which breaks some backwards compatibility) we can introduce a > > >> > symbol for overriding property access? Something like > > >> > > > >> > ```js > > >> > Array.prototype[Symbol.propertyAccess] = function(index) { > > >> > if (index < 0) ... > > >> > else ... > > >> > } > > >> > ``` > > >> > > > >> > ? Just an idea; I'm not sure if that's a good use for Symbols. We > > >> > could then easily add this helper code to a given app. > > >> > > > >> > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: > > >> > > I don't see a good reason why to mangle with this. > > >> > > Note that you can achieve this behavior without breaking backwards > > >> > > compatibility with ES6 Proxies: > > >> > > > > >> > > ```js > > >> > > class MyArray extends Array { > > >> > > constructor(...args) { > > >> > > super(...args); > > >> > > function computeProperty(target, property) { > > >> > > const index = +property; > > >> > > return index < 0 ? String(target.length + > > >> > > index) : property; > > >> > > } > > >> > > return new Proxy(this, { > > >> > > get(target, property, receiver) { > > >> > > return Reflect.get(target, > > >> > > computeProperty(target, property), receiver); > > >> > > }, > > >> > > set(target, property, receiver) { > > >> > > return Reflect.set(target, > > >> > > computeProperty(target, property), receiver); > > >> > > } > > >> > > }); > > >> > > } > > >> > > } > > >> > > ``` > > >> > > > > >> > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: > > >> > >> Backwards compatibility has been broken before. I don't think this > > >> > >> one > > >> > >> is too bad of a breakage. > > >> > >> > > >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> > > wrote: > > >> > >> > On 17 April 2016 at 17:29, Frankie Bagnardi < > > f.bagnardi at gmail.com> > > >> > >> > wrote: > > >> > >> >> That would break backward compatibility; > > >> > >> >> > > >> > >> >> ```js > > >> > >> >> var a = ['a']; > > >> > >> >> a['-1'] = 'test'; > > >> > >> >> Object.keys(a) // ['0', '-1'] > > >> > >> >> ``` > > >> > >> > > > >> > >> > Do we have statistics how many sties depend on that? > > >> > >> > _______________________________________________ > > >> > >> > es-discuss mailing list > > >> > >> > es-discuss at mozilla.org > > >> > >> > https://mail.mozilla.org/listinfo/es-discuss > > >> > >> _______________________________________________ > > >> > >> es-discuss mailing list > > >> > >> es-discuss at mozilla.org > > >> > >> https://mail.mozilla.org/listinfo/es-discuss > > >> > >> > > >> > > _______________________________________________ > > >> > > es-discuss mailing list > > >> > > es-discuss at mozilla.org > > >> > > https://mail.mozilla.org/listinfo/es-discuss > > >> > > > >> _______________________________________________ > > >> es-discuss mailing list > > >> es-discuss at mozilla.org > > >> https://mail.mozilla.org/listinfo/es-discuss > > >
This can be trivially done with proxies. I don't think arrays should have a special trap dependent on whether or not a symbol is set. If I were to make a custom array with proxies I would then have to check if someone changed standard behavior by inserting a symbol, and pass the symbol to the target just to work properly.
If the var arr = [1,2,3];
syntax is the real reason to change default
behavior then just use Array.from
like such var arr = InvertedArray.from([1,2,3]);
. See below...
var getProp = (target, property) => typeof property !== 'symbol' && target.length && property < 0 && property >= -target.length
? +property + target.length
: property;
var handler = {
get: (target, property, receiver) => Reflect.get(target, getProp(target, property), receiver),
set: (target, property, value, receiver) => Reflect.set(target, getProp(target, property), value, receiver)
};
var InvertedArray = new Proxy(function InvertedArray(arg1) {}, {
construct: (target, arguments, newTarget) => new Proxy(Reflect.construct(Array, arguments, InvertedArray), handler)
});
Reflect.setPrototypeOf(InvertedArray, Array);
InvertedArray.prototype = Object.create(Array.prototype);
Arrays are effectively regular objects with traps on get/set to update the
length property. I don't think they should have a special new syntax to
access negative indices like arr[:-1]
since it would logically have to
work on all objects and is dependent on a length property; it's just
syntactic sugar for yet another trap.
You can also make a callable array without the typeof issue...
var getProp = (target, property) => typeof property !== 'symbol' && target.length && property < 0 && property >= -target.length
? +property + target.length
: property;
var handler = {
apply: (target, thisArg, arguments) => Reflect.get(target, getProp(target, arguments[0]))
};
var CallableArray = new Proxy(function CallableArray(arg1) {}, {
construct: (target, arguments, newTarget) => new Proxy(Reflect.construct(Array, arguments, CallableArray), handler)
});
Reflect.setPrototypeOf(CallableArray, Array);
CallableArray.prototype = Object.create(Array.prototype);
... but you can't set anything with the arr(-1)
syntax obviously.
This can be trivially done with proxies. I don't think arrays should have a special trap dependent on whether or not a symbol is set. If I were to make a custom array with proxies I would then have to check if someone changed standard behavior by inserting a symbol, and pass the symbol to the target just to work properly. If the `var arr = [1,2,3];` syntax is the real reason to change default behavior then just use `Array.from` like such `var arr = InvertedArray.from([1,2,3]);`. See below... ``` var getProp = (target, property) => typeof property !== 'symbol' && target.length && property < 0 && property >= -target.length ? +property + target.length : property; var handler = { get: (target, property, receiver) => Reflect.get(target, getProp(target, property), receiver), set: (target, property, value, receiver) => Reflect.set(target, getProp(target, property), value, receiver) }; var InvertedArray = new Proxy(function InvertedArray(arg1) {}, { construct: (target, arguments, newTarget) => new Proxy(Reflect.construct(Array, arguments, InvertedArray), handler) }); Reflect.setPrototypeOf(InvertedArray, Array); InvertedArray.prototype = Object.create(Array.prototype); ``` Arrays are effectively regular objects with traps on get/set to update the length property. I don't think they should have a special new syntax to access negative indices like `arr[:-1]` since it would logically have to work on all objects and is dependent on a length property; it's just syntactic sugar for yet another trap. On Mon, Apr 18, 2016 at 2:05 PM, kdex <kdex at kdex.de> wrote: > `Symbol.implementation` should be fairly trivial to implement once [Realm]( > https://github.com/caridy/proposal-realms)s are around, without affecting > global scope. > > On Montag, 18. April 2016 18:58:06 CEST Andy Earnshaw wrote: > > I don't think that would be trivial to implement and there might not be a > > common enough use case for it. You might want to look into something > like > > http://sweetjs.org if it's the syntactic sugar you're looking for. > > > > On Mon, 18 Apr 2016 19:35 /#!/JoePea, <joe at trusktr.io> wrote: > > > > > > ```js > > > > Array[Symbol.implementation] = MyArray; > > > > ``` > > > > > > > That would mean all other programs executing on the page would be > forced > > > to use that Array implementation > > > > > > And also with my suggestion that would impact all code too. > > > > > > Would it be possible to limit the effect of using certain symbols to a > > > scope where the symbol is used? For example: > > > > > > ```js > > > function main() { > > > Array[Symbol.implementation] = MyArray; > > > > > > let a = [1,2,3] // uses MyArray > > > } > > > let a = [1,2,3] // uses Array > > > main() > > > ``` > > > > > > or > > > > > > ```js > > > Array[Symbol.implementation] = MyArray; > > > function main() { > > > let a = [1,2,3] // uses MyArray, from outer scope > > > } > > > let a = [1,2,3] // uses MyArray > > > main() > > > ``` > > > > > > Or maybe some other method on a per-scope basis? > > > > > > On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw < > andyearnshaw at gmail.com> > > > wrote: > > > > That would mean all other programs executing on the page would be > forced > > > to > > > > use that Array implementation, imposing potentially critical problems > > > with, > > > > for example, performance and expected behavior. It's just not a good > > > idea. > > > > > > > > I missed off esdiscuss when I replied earlier, but I mentioned that > the > > > only > > > > reasonable solution is to introduce new syntax, e.g. > > > > > > > > myArray[:-1] > > > > > > > > However, it's been said that there needs to be a compelling reason > to add > > > > new syntax and I'm not sure this qualifies imo. > > > > > > > > > > > > On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: > > > >> > > > >> Yes, now we're heading in the right direction. > > > >> > > > >> The problem with something like `Symbol.propertyAccess` is that this > > > might > > > >> lead to a flood of new well-known Symbols. > > > >> Conceptually, `Symbol.propertyAccess` sounds like it should have > been a > > > >> `Proxy` trap, anyway. > > > >> > > > >> Here's an more general idea: Why not allow users to set a derived > class > > > >> for literals via well-known Symbols? > > > >> Thus, users could provide custom implementations for `RegExp`, > `Array`, > > > >> `Object` (…) literals, as long as the value points to a derived > class. > > > >> > > > >> We could even introduce negative array indices in a way that doesn't > > > break > > > >> the web like this: > > > >> > > > >> ```js > > > >> [1, 2, 3][-1]; // undefined > > > >> Array[Symbol.implementation] = MyArray; > > > >> [1, 2, 3][-1]; // 3 > > > >> Array[Symbol.implementation] = 3; // TypeError: Array > implementations > > > must > > > >> extend Array (→ Array.isPrototypeOf(Number(3)) is false) > > > >> ``` > > > >> > > > >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: > > > >> > But, can > > > >> > > > > >> > ```js > > > >> > let a = [1,2,3] > > > >> > ``` > > > >> > > > > >> > create a new MyArray? Maybe, instead of having negative indices by > > > >> > default (which breaks some backwards compatibility) we can > introduce a > > > >> > symbol for overriding property access? Something like > > > >> > > > > >> > ```js > > > >> > Array.prototype[Symbol.propertyAccess] = function(index) { > > > >> > if (index < 0) ... > > > >> > else ... > > > >> > } > > > >> > ``` > > > >> > > > > >> > ? Just an idea; I'm not sure if that's a good use for Symbols. We > > > >> > could then easily add this helper code to a given app. > > > >> > > > > >> > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: > > > >> > > I don't see a good reason why to mangle with this. > > > >> > > Note that you can achieve this behavior without breaking > backwards > > > >> > > compatibility with ES6 Proxies: > > > >> > > > > > >> > > ```js > > > >> > > class MyArray extends Array { > > > >> > > constructor(...args) { > > > >> > > super(...args); > > > >> > > function computeProperty(target, property) { > > > >> > > const index = +property; > > > >> > > return index < 0 ? String(target.length > + > > > >> > > index) : property; > > > >> > > } > > > >> > > return new Proxy(this, { > > > >> > > get(target, property, receiver) { > > > >> > > return Reflect.get(target, > > > >> > > computeProperty(target, property), receiver); > > > >> > > }, > > > >> > > set(target, property, receiver) { > > > >> > > return Reflect.set(target, > > > >> > > computeProperty(target, property), receiver); > > > >> > > } > > > >> > > }); > > > >> > > } > > > >> > > } > > > >> > > ``` > > > >> > > > > > >> > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: > > > >> > >> Backwards compatibility has been broken before. I don't think > this > > > >> > >> one > > > >> > >> is too bad of a breakage. > > > >> > >> > > > >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com> > > > wrote: > > > >> > >> > On 17 April 2016 at 17:29, Frankie Bagnardi < > > > f.bagnardi at gmail.com> > > > >> > >> > wrote: > > > >> > >> >> That would break backward compatibility; > > > >> > >> >> > > > >> > >> >> ```js > > > >> > >> >> var a = ['a']; > > > >> > >> >> a['-1'] = 'test'; > > > >> > >> >> Object.keys(a) // ['0', '-1'] > > > >> > >> >> ``` > > > >> > >> > > > > >> > >> > Do we have statistics how many sties depend on that? > > > >> > >> > _______________________________________________ > > > >> > >> > es-discuss mailing list > > > >> > >> > es-discuss at mozilla.org > > > >> > >> > https://mail.mozilla.org/listinfo/es-discuss > > > >> > >> _______________________________________________ > > > >> > >> es-discuss mailing list > > > >> > >> es-discuss at mozilla.org > > > >> > >> https://mail.mozilla.org/listinfo/es-discuss > > > >> > >> > > > >> > > _______________________________________________ > > > >> > > es-discuss mailing list > > > >> > > es-discuss at mozilla.org > > > >> > > https://mail.mozilla.org/listinfo/es-discuss > > > >> > > > > >> _______________________________________________ > > > >> es-discuss mailing list > > > >> es-discuss at mozilla.org > > > >> https://mail.mozilla.org/listinfo/es-discuss > > > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160418/2c69c543/attachment-0001.html>
I assume if you were to spec out the additional syntax you'd go the whole hog and add ranges, e.g.
arr[:-4, -2];
Like I said, not particularly compelling as it's not a huge saving over slice() and selecting single negative indices can be done with Proxy.
I assume if you were to spec out the additional syntax you'd go the whole hog and add ranges, e.g. arr[:-4, -2]; Like I said, not particularly compelling as it's not a huge saving over slice() and selecting single negative indices can be done with Proxy. On Mon, 18 Apr 2016 20:32 Michael Theriot, <michael.lee.theriot at gmail.com> wrote: > This can be trivially done with proxies. I don't think arrays should have > a special trap dependent on whether or not a symbol is set. If I were to > make a custom array with proxies I would then have to check if someone > changed standard behavior by inserting a symbol, and pass the symbol to the > target just to work properly. > > If the `var arr = [1,2,3];` syntax is the real reason to change default > behavior then just use `Array.from` like such `var arr = > InvertedArray.from([1,2,3]);`. See below... > > ``` > var getProp = (target, property) => typeof property !== 'symbol' && > target.length && property < 0 && property >= -target.length ? +property + > target.length : property; > > var handler = { > get: (target, property, receiver) => Reflect.get(target, getProp(target, > property), receiver), > set: (target, property, value, receiver) => Reflect.set(target, > getProp(target, property), value, receiver) > }; > > var InvertedArray = new Proxy(function InvertedArray(arg1) {}, { > construct: (target, arguments, newTarget) => new > Proxy(Reflect.construct(Array, arguments, InvertedArray), handler) > }); > > Reflect.setPrototypeOf(InvertedArray, Array); > > InvertedArray.prototype = Object.create(Array.prototype); > ``` > > Arrays are effectively regular objects with traps on get/set to update the > length property. I don't think they should have a special new syntax to > access negative indices like `arr[:-1]` since it would logically have to > work on all objects and is dependent on a length property; it's just > syntactic sugar for yet another trap. > > On Mon, Apr 18, 2016 at 2:05 PM, kdex <kdex at kdex.de> wrote: > >> `Symbol.implementation` should be fairly trivial to implement once >> [Realm](https://github.com/caridy/proposal-realms)s are around, without >> affecting global scope. >> >> On Montag, 18. April 2016 18:58:06 CEST Andy Earnshaw wrote: >> > I don't think that would be trivial to implement and there might not be >> a >> > common enough use case for it. You might want to look into something >> like >> > http://sweetjs.org if it's the syntactic sugar you're looking for. >> > >> > On Mon, 18 Apr 2016 19:35 /#!/JoePea, <joe at trusktr.io> wrote: >> > >> > > > ```js >> > > > Array[Symbol.implementation] = MyArray; >> > > > ``` >> > > >> > > > That would mean all other programs executing on the page would be >> forced >> > > to use that Array implementation >> > > >> > > And also with my suggestion that would impact all code too. >> > > >> > > Would it be possible to limit the effect of using certain symbols to a >> > > scope where the symbol is used? For example: >> > > >> > > ```js >> > > function main() { >> > > Array[Symbol.implementation] = MyArray; >> > > >> > > let a = [1,2,3] // uses MyArray >> > > } >> > > let a = [1,2,3] // uses Array >> > > main() >> > > ``` >> > > >> > > or >> > > >> > > ```js >> > > Array[Symbol.implementation] = MyArray; >> > > function main() { >> > > let a = [1,2,3] // uses MyArray, from outer scope >> > > } >> > > let a = [1,2,3] // uses MyArray >> > > main() >> > > ``` >> > > >> > > Or maybe some other method on a per-scope basis? >> > > >> > > On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw < >> andyearnshaw at gmail.com> >> > > wrote: >> > > > That would mean all other programs executing on the page would be >> forced >> > > to >> > > > use that Array implementation, imposing potentially critical >> problems >> > > with, >> > > > for example, performance and expected behavior. It's just not a good >> > > idea. >> > > > >> > > > I missed off esdiscuss when I replied earlier, but I mentioned that >> the >> > > only >> > > > reasonable solution is to introduce new syntax, e.g. >> > > > >> > > > myArray[:-1] >> > > > >> > > > However, it's been said that there needs to be a compelling reason >> to add >> > > > new syntax and I'm not sure this qualifies imo. >> > > > >> > > > >> > > > On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: >> > > >> >> > > >> Yes, now we're heading in the right direction. >> > > >> >> > > >> The problem with something like `Symbol.propertyAccess` is that >> this >> > > might >> > > >> lead to a flood of new well-known Symbols. >> > > >> Conceptually, `Symbol.propertyAccess` sounds like it should have >> been a >> > > >> `Proxy` trap, anyway. >> > > >> >> > > >> Here's an more general idea: Why not allow users to set a derived >> class >> > > >> for literals via well-known Symbols? >> > > >> Thus, users could provide custom implementations for `RegExp`, >> `Array`, >> > > >> `Object` (…) literals, as long as the value points to a derived >> class. >> > > >> >> > > >> We could even introduce negative array indices in a way that >> doesn't >> > > break >> > > >> the web like this: >> > > >> >> > > >> ```js >> > > >> [1, 2, 3][-1]; // undefined >> > > >> Array[Symbol.implementation] = MyArray; >> > > >> [1, 2, 3][-1]; // 3 >> > > >> Array[Symbol.implementation] = 3; // TypeError: Array >> implementations >> > > must >> > > >> extend Array (→ Array.isPrototypeOf(Number(3)) is false) >> > > >> ``` >> > > >> >> > > >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: >> > > >> > But, can >> > > >> > >> > > >> > ```js >> > > >> > let a = [1,2,3] >> > > >> > ``` >> > > >> > >> > > >> > create a new MyArray? Maybe, instead of having negative indices >> by >> > > >> > default (which breaks some backwards compatibility) we can >> introduce a >> > > >> > symbol for overriding property access? Something like >> > > >> > >> > > >> > ```js >> > > >> > Array.prototype[Symbol.propertyAccess] = function(index) { >> > > >> > if (index < 0) ... >> > > >> > else ... >> > > >> > } >> > > >> > ``` >> > > >> > >> > > >> > ? Just an idea; I'm not sure if that's a good use for Symbols. We >> > > >> > could then easily add this helper code to a given app. >> > > >> > >> > > >> > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: >> > > >> > > I don't see a good reason why to mangle with this. >> > > >> > > Note that you can achieve this behavior without breaking >> backwards >> > > >> > > compatibility with ES6 Proxies: >> > > >> > > >> > > >> > > ```js >> > > >> > > class MyArray extends Array { >> > > >> > > constructor(...args) { >> > > >> > > super(...args); >> > > >> > > function computeProperty(target, property) { >> > > >> > > const index = +property; >> > > >> > > return index < 0 ? >> String(target.length + >> > > >> > > index) : property; >> > > >> > > } >> > > >> > > return new Proxy(this, { >> > > >> > > get(target, property, receiver) { >> > > >> > > return Reflect.get(target, >> > > >> > > computeProperty(target, property), receiver); >> > > >> > > }, >> > > >> > > set(target, property, receiver) { >> > > >> > > return Reflect.set(target, >> > > >> > > computeProperty(target, property), receiver); >> > > >> > > } >> > > >> > > }); >> > > >> > > } >> > > >> > > } >> > > >> > > ``` >> > > >> > > >> > > >> > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: >> > > >> > >> Backwards compatibility has been broken before. I don't think >> this >> > > >> > >> one >> > > >> > >> is too bad of a breakage. >> > > >> > >> >> > > >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju <bijumaillist at gmail.com >> > >> > > wrote: >> > > >> > >> > On 17 April 2016 at 17:29, Frankie Bagnardi < >> > > f.bagnardi at gmail.com> >> > > >> > >> > wrote: >> > > >> > >> >> That would break backward compatibility; >> > > >> > >> >> >> > > >> > >> >> ```js >> > > >> > >> >> var a = ['a']; >> > > >> > >> >> a['-1'] = 'test'; >> > > >> > >> >> Object.keys(a) // ['0', '-1'] >> > > >> > >> >> ``` >> > > >> > >> > >> > > >> > >> > Do we have statistics how many sties depend on that? >> > > >> > >> > _______________________________________________ >> > > >> > >> > es-discuss mailing list >> > > >> > >> > es-discuss at mozilla.org >> > > >> > >> > https://mail.mozilla.org/listinfo/es-discuss >> > > >> > >> _______________________________________________ >> > > >> > >> es-discuss mailing list >> > > >> > >> es-discuss at mozilla.org >> > > >> > >> https://mail.mozilla.org/listinfo/es-discuss >> > > >> > >> >> > > >> > > _______________________________________________ >> > > >> > > es-discuss mailing list >> > > >> > > es-discuss at mozilla.org >> > > >> > > https://mail.mozilla.org/listinfo/es-discuss >> > > >> > >> > > >> _______________________________________________ >> > > >> es-discuss mailing list >> > > >> es-discuss at mozilla.org >> > > >> https://mail.mozilla.org/listinfo/es-discuss >> > > >> > >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160418/114fe9d9/attachment.html>
Although there seems to have been a decisive lack of interest in my extended pick notation proposal, it cleanly subsumes the entire idea of "lastElement" and its endless rehashed variations involving new prototype methods or symbols or whatever else people proposed.
In my proposal, "lastElement" is just
array.-1
An arbitrary expression can follow the dot, so
index = -1;
array.(index);
As far as I am aware, no one has said this is bad, or unparseable, or backward incompatible, just that it is excessive and gratuitous and unnecessary sugar.
If extending the dot to take expressions to the right is considered aesthetically undesirable for whatever reason--personally, to me, it seems completely intuitive--then at the cost of eating up a precious special operator, the proposal suggests the alternative of the pound sign:
array # -1
This proposal does much more than just let you take the last element of an array. As a trivial example, an alternative way to reverse an array falls out of it naturally:
array.[-1 to 0]
And, it also provides a way to build new objects from other objects' properties, which was the motivation for the whole thing.
object.{a, b}
Take another look at it if you're interested.
Bob
Although there seems to have been a decisive lack of interest in my extended pick notation proposal, it cleanly subsumes the entire idea of "lastElement" and its endless rehashed variations involving new prototype methods or symbols or whatever else people proposed. In my proposal, "lastElement" is just ```js array.-1 ``` An arbitrary expression can follow the dot, so ```js index = -1; array.(index); ``` As far as I am aware, no one has said this is bad, or unparseable, or backward incompatible, just that it is excessive and gratuitous and unnecessary sugar. If extending the dot to take expressions to the right is considered aesthetically undesirable for whatever reason--personally, to me, it seems completely intuitive--then at the cost of eating up a precious special operator, the proposal suggests the alternative of the pound sign: ```js array # -1 ``` This proposal does much more than just let you take the last element of an array. As a trivial example, an alternative way to reverse an array falls out of it naturally: ```js array.[-1 to 0] ``` And, it also provides a way to build new objects from other objects' properties, which was the motivation for the whole thing. ```js object.{a, b} ``` Take another look at it if you're interested. Bob On Tue, Apr 19, 2016 at 1:18 AM, Andy Earnshaw <andyearnshaw at gmail.com> wrote: > I assume if you were to spec out the additional syntax you'd go the whole > hog and add ranges, e.g. > > arr[:-4, -2]; > > Like I said, not particularly compelling as it's not a huge saving over > slice() and selecting single negative indices can be done with Proxy. > > On Mon, 18 Apr 2016 20:32 Michael Theriot, <michael.lee.theriot at gmail.com> > wrote: > >> This can be trivially done with proxies. I don't think arrays should have >> a special trap dependent on whether or not a symbol is set. If I were to >> make a custom array with proxies I would then have to check if someone >> changed standard behavior by inserting a symbol, and pass the symbol to the >> target just to work properly. >> >> If the `var arr = [1,2,3];` syntax is the real reason to change default >> behavior then just use `Array.from` like such `var arr = >> InvertedArray.from([1,2,3]);`. See below... >> >> ``` >> var getProp = (target, property) => typeof property !== 'symbol' && >> target.length && property < 0 && property >= -target.length ? +property + >> target.length : property; >> >> var handler = { >> get: (target, property, receiver) => Reflect.get(target, >> getProp(target, property), receiver), >> set: (target, property, value, receiver) => Reflect.set(target, >> getProp(target, property), value, receiver) >> }; >> >> var InvertedArray = new Proxy(function InvertedArray(arg1) {}, { >> construct: (target, arguments, newTarget) => new >> Proxy(Reflect.construct(Array, arguments, InvertedArray), handler) >> }); >> >> Reflect.setPrototypeOf(InvertedArray, Array); >> >> InvertedArray.prototype = Object.create(Array.prototype); >> ``` >> >> Arrays are effectively regular objects with traps on get/set to update >> the length property. I don't think they should have a special new syntax to >> access negative indices like `arr[:-1]` since it would logically have to >> work on all objects and is dependent on a length property; it's just >> syntactic sugar for yet another trap. >> >> On Mon, Apr 18, 2016 at 2:05 PM, kdex <kdex at kdex.de> wrote: >> >>> `Symbol.implementation` should be fairly trivial to implement once >>> [Realm](https://github.com/caridy/proposal-realms)s are around, without >>> affecting global scope. >>> >>> On Montag, 18. April 2016 18:58:06 CEST Andy Earnshaw wrote: >>> > I don't think that would be trivial to implement and there might not >>> be a >>> > common enough use case for it. You might want to look into something >>> like >>> > http://sweetjs.org if it's the syntactic sugar you're looking for. >>> > >>> > On Mon, 18 Apr 2016 19:35 /#!/JoePea, <joe at trusktr.io> wrote: >>> > >>> > > > ```js >>> > > > Array[Symbol.implementation] = MyArray; >>> > > > ``` >>> > > >>> > > > That would mean all other programs executing on the page would be >>> forced >>> > > to use that Array implementation >>> > > >>> > > And also with my suggestion that would impact all code too. >>> > > >>> > > Would it be possible to limit the effect of using certain symbols to >>> a >>> > > scope where the symbol is used? For example: >>> > > >>> > > ```js >>> > > function main() { >>> > > Array[Symbol.implementation] = MyArray; >>> > > >>> > > let a = [1,2,3] // uses MyArray >>> > > } >>> > > let a = [1,2,3] // uses Array >>> > > main() >>> > > ``` >>> > > >>> > > or >>> > > >>> > > ```js >>> > > Array[Symbol.implementation] = MyArray; >>> > > function main() { >>> > > let a = [1,2,3] // uses MyArray, from outer scope >>> > > } >>> > > let a = [1,2,3] // uses MyArray >>> > > main() >>> > > ``` >>> > > >>> > > Or maybe some other method on a per-scope basis? >>> > > >>> > > On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw < >>> andyearnshaw at gmail.com> >>> > > wrote: >>> > > > That would mean all other programs executing on the page would be >>> forced >>> > > to >>> > > > use that Array implementation, imposing potentially critical >>> problems >>> > > with, >>> > > > for example, performance and expected behavior. It's just not a >>> good >>> > > idea. >>> > > > >>> > > > I missed off esdiscuss when I replied earlier, but I mentioned >>> that the >>> > > only >>> > > > reasonable solution is to introduce new syntax, e.g. >>> > > > >>> > > > myArray[:-1] >>> > > > >>> > > > However, it's been said that there needs to be a compelling reason >>> to add >>> > > > new syntax and I'm not sure this qualifies imo. >>> > > > >>> > > > >>> > > > On Mon, 18 Apr 2016 19:11 kdex, <kdex at kdex.de> wrote: >>> > > >> >>> > > >> Yes, now we're heading in the right direction. >>> > > >> >>> > > >> The problem with something like `Symbol.propertyAccess` is that >>> this >>> > > might >>> > > >> lead to a flood of new well-known Symbols. >>> > > >> Conceptually, `Symbol.propertyAccess` sounds like it should have >>> been a >>> > > >> `Proxy` trap, anyway. >>> > > >> >>> > > >> Here's an more general idea: Why not allow users to set a derived >>> class >>> > > >> for literals via well-known Symbols? >>> > > >> Thus, users could provide custom implementations for `RegExp`, >>> `Array`, >>> > > >> `Object` (…) literals, as long as the value points to a derived >>> class. >>> > > >> >>> > > >> We could even introduce negative array indices in a way that >>> doesn't >>> > > break >>> > > >> the web like this: >>> > > >> >>> > > >> ```js >>> > > >> [1, 2, 3][-1]; // undefined >>> > > >> Array[Symbol.implementation] = MyArray; >>> > > >> [1, 2, 3][-1]; // 3 >>> > > >> Array[Symbol.implementation] = 3; // TypeError: Array >>> implementations >>> > > must >>> > > >> extend Array (→ Array.isPrototypeOf(Number(3)) is false) >>> > > >> ``` >>> > > >> >>> > > >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote: >>> > > >> > But, can >>> > > >> > >>> > > >> > ```js >>> > > >> > let a = [1,2,3] >>> > > >> > ``` >>> > > >> > >>> > > >> > create a new MyArray? Maybe, instead of having negative indices >>> by >>> > > >> > default (which breaks some backwards compatibility) we can >>> introduce a >>> > > >> > symbol for overriding property access? Something like >>> > > >> > >>> > > >> > ```js >>> > > >> > Array.prototype[Symbol.propertyAccess] = function(index) { >>> > > >> > if (index < 0) ... >>> > > >> > else ... >>> > > >> > } >>> > > >> > ``` >>> > > >> > >>> > > >> > ? Just an idea; I'm not sure if that's a good use for Symbols. >>> We >>> > > >> > could then easily add this helper code to a given app. >>> > > >> > >>> > > >> > On Mon, Apr 18, 2016 at 10:25 AM, kdex <kdex at kdex.de> wrote: >>> > > >> > > I don't see a good reason why to mangle with this. >>> > > >> > > Note that you can achieve this behavior without breaking >>> backwards >>> > > >> > > compatibility with ES6 Proxies: >>> > > >> > > >>> > > >> > > ```js >>> > > >> > > class MyArray extends Array { >>> > > >> > > constructor(...args) { >>> > > >> > > super(...args); >>> > > >> > > function computeProperty(target, property) { >>> > > >> > > const index = +property; >>> > > >> > > return index < 0 ? >>> String(target.length + >>> > > >> > > index) : property; >>> > > >> > > } >>> > > >> > > return new Proxy(this, { >>> > > >> > > get(target, property, receiver) { >>> > > >> > > return Reflect.get(target, >>> > > >> > > computeProperty(target, property), receiver); >>> > > >> > > }, >>> > > >> > > set(target, property, receiver) { >>> > > >> > > return Reflect.set(target, >>> > > >> > > computeProperty(target, property), receiver); >>> > > >> > > } >>> > > >> > > }); >>> > > >> > > } >>> > > >> > > } >>> > > >> > > ``` >>> > > >> > > >>> > > >> > > On Montag, 18. April 2016 09:59:15 CEST /#!/JoePea wrote: >>> > > >> > >> Backwards compatibility has been broken before. I don't >>> think this >>> > > >> > >> one >>> > > >> > >> is too bad of a breakage. >>> > > >> > >> >>> > > >> > >> On Sun, Apr 17, 2016 at 9:48 PM, Biju < >>> bijumaillist at gmail.com> >>> > > wrote: >>> > > >> > >> > On 17 April 2016 at 17:29, Frankie Bagnardi < >>> > > f.bagnardi at gmail.com> >>> > > >> > >> > wrote: >>> > > >> > >> >> That would break backward compatibility; >>> > > >> > >> >> >>> > > >> > >> >> ```js >>> > > >> > >> >> var a = ['a']; >>> > > >> > >> >> a['-1'] = 'test'; >>> > > >> > >> >> Object.keys(a) // ['0', '-1'] >>> > > >> > >> >> ``` >>> > > >> > >> > >>> > > >> > >> > Do we have statistics how many sties depend on that? >>> > > >> > >> > _______________________________________________ >>> > > >> > >> > es-discuss mailing list >>> > > >> > >> > es-discuss at mozilla.org >>> > > >> > >> > https://mail.mozilla.org/listinfo/es-discuss >>> > > >> > >> _______________________________________________ >>> > > >> > >> es-discuss mailing list >>> > > >> > >> es-discuss at mozilla.org >>> > > >> > >> https://mail.mozilla.org/listinfo/es-discuss >>> > > >> > >> >>> > > >> > > _______________________________________________ >>> > > >> > > es-discuss mailing list >>> > > >> > > es-discuss at mozilla.org >>> > > >> > > https://mail.mozilla.org/listinfo/es-discuss >>> > > >> > >>> > > >> _______________________________________________ >>> > > >> es-discuss mailing list >>> > > >> es-discuss at mozilla.org >>> > > >> https://mail.mozilla.org/listinfo/es-discuss >>> > > >>> > >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/3a0639e9/attachment-0001.html>
Why new syntax here? This is just a method that's missing: array.last(n)
.
array[-1]
would break things and it is difficult to find out where.
Consider:
for (var i = array.length - 1; array[i]; i--) doSomething(array[i]);
Not the best way to write such a loop but changing array[-1]
would break
it.
Why new syntax here? This is just a method that's missing: `array.last(n)`. `array[-1]` would break things and it is difficult to find out where. Consider: ``` javascript for (var i = array.length - 1; array[i]; i--) doSomething(array[i]); ``` Not the best way to write such a loop but changing `array[-1]` would break it. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/25ed2965/attachment.html>
Please go back and read the existing threads. We've been over this territory ad nauseum.
Yes, of course array[-1]
would break the web and that's why no one is
seriously proposing that.
As already discussed extensively, Array#last
may be an option, but it
could collide with libraries or other code which extends Array.prototype
,
and they seem too specialized (why not also lastButOne
?).
Bob
Please go back and read the existing threads. We've been over this territory ad nauseum. Yes, of course `array[-1]` would break the web and that's why no one is seriously proposing that. As already discussed extensively, `Array#last` may be an option, but it could collide with libraries or other code which extends `Array.prototype`, and they seem too specialized (why not also `lastButOne`?). Bob On Tue, Apr 19, 2016 at 10:47 AM, Bruno Jouhier <bjouhier at gmail.com> wrote: > Why new syntax here? This is just a method that's missing: `array.last(n)`. > > `array[-1]` would break things and it is difficult to find out where. > Consider: > > ``` javascript > for (var i = array.length - 1; array[i]; i--) doSomething(array[i]); > ``` > > Not the best way to write such a loop but changing `array[-1]` would break > it. > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/4f851a11/attachment.html>
This is why we can't have nice things... Literally anything we do with the
language at all can collide with libraries. Introducing new syntax? Code
that was using eval and throwing syntax errors is now behaving differently
and you 'broke the web'... Adding a Symbol.last
method to Array#
?
People who were abusing Arrays as property bags might have code that was
adding that key as a property already and you 'broke the web'...
If this is seriously the attitude we're taking as a community, we should stop wasting our time and just accept that WebAssembly is the only reasonable way forward. All of these modern nice-to-haves are a crutch and a distraction from this and obfuscate the need for a real solution.
Of course, we cleaned up parts of the language once already with 'use strict'. I don't see why we can't do it again once or twice a decade...
Alex
This is why we can't have nice things... Literally anything we do with the language *at all* can collide with libraries. Introducing new syntax? Code that was using eval and throwing syntax errors is now behaving differently and you 'broke the web'... Adding a `Symbol.last` method to `Array#`? People who were abusing Arrays as property bags might have code that was adding that key as a property already and you 'broke the web'... If this is seriously the attitude we're taking as a community, we should stop wasting our time and just accept that WebAssembly is the only reasonable way forward. All of these modern nice-to-haves are a crutch and a distraction from this and obfuscate the need for a real solution. Of course, we cleaned up parts of the language once already with 'use strict'. I don't see why we can't do it again once or twice a decade... Alex On Tuesday, 19 April 2016, Bob Myers <rtm at gol.com> wrote: > Please go back and read the existing threads. We've been over this > territory ad nauseum. > > Yes, of course `array[-1]` would break the web and that's why no one is > seriously proposing that. > > As already discussed extensively, `Array#last` may be an option, but it > could collide with libraries or other code which extends `Array.prototype`, > and they seem too specialized (why not also `lastButOne`?). > > Bob > > On Tue, Apr 19, 2016 at 10:47 AM, Bruno Jouhier <bjouhier at gmail.com > <javascript:_e(%7B%7D,'cvml','bjouhier at gmail.com');>> wrote: > >> Why new syntax here? This is just a method that's missing: >> `array.last(n)`. >> >> `array[-1]` would break things and it is difficult to find out where. >> Consider: >> >> ``` javascript >> for (var i = array.length - 1; array[i]; i--) doSomething(array[i]); >> ``` >> >> Not the best way to write such a loop but changing `array[-1]` would >> break it. >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/965ea28f/attachment.html>
Adding last
to Array.prototype
is no different than adding endsWith
to String.prototype
. ES2015 did it.
It won't break most existing code that defines Array.prototype.last
. Such
code will just overwrite the new last
method and will continue to work as
before.
You won't be able to mix old libraries that have their own last
method
with new code if the methods behave differently but that's a different
story; that's not breaking existing web pages.
What will break though is existing code that test the existence of
Array.prototype.last
; but String.prototype.endsWith
had the same issue.
last(1) would return last but one, and last() would be the same as last(0)
Adding `last` to `Array.prototype` is no different than adding `endsWith` to `String.prototype`. ES2015 did it. It won't break most existing code that defines `Array.prototype.last`. Such code will just overwrite the new `last` method and will continue to work as before. You won't be able to mix old libraries that have their own `last` method with new code if the methods behave differently but that's a different story; that's not breaking existing web pages. What will break though is existing code that test the existence of `Array.prototype.last`; but `String.prototype.endsWith` had the same issue. last(1) would return last but one, and last() would be the same as last(0) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/1c9bc3a5/attachment.html>
If we're talking about adding a new method anyway, why not just add a
more general get
method with support for both positive and negative
indices? That would be consistent with the other array methods, and
additionally I think it is more natural to use arr.get(-2)
than
arr.last(1)
. Using last
to get anything but the very last element
just seems weird to me.
If we're talking about adding a new method anyway, why not just add a more general `get` method with support for both positive and negative indices? That would be consistent with the other array methods, and additionally I think it is more natural to use `arr.get(-2)` than `arr.last(1)`. Using `last` to get anything but the very last element just seems weird to me. On 04/19/2016 10:00 AM, Bruno Jouhier wrote: > Adding `last` to `Array.prototype` is no different than adding > `endsWith` to `String.prototype`. ES2015 did it. > > It won't break most existing code that defines `Array.prototype.last`. > Such code will just overwrite the new `last` method and will continue > to work as before. > > You won't be able to mix old libraries that have their own `last` > method with new code if the methods behave differently but that's a > different story; that's not breaking existing web pages. > > What will break though is existing code that test the existence of > `Array.prototype.last`; but `String.prototype.endsWith` had the same > issue. > > last(1) would return last but one, and last() would be the same as last(0) > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/dcde5305/attachment-0001.html>
Let's not cry doomsday because there's not an easy path to adding "-1" array access, when indexing into a list of things in the first place is already a potential code smell.
endsWith
was able to be added because it didn't break anything.
contains
was renamed to includes
because the former did break
something. There's lots of examples of this principle at work. New things
can be added any time they don't break the web. Nothing will ever be
knowingly added that does break the web. Please accept that. Creating a new
web language won't necessarily "solve" this "problem" - future iterations
of that language would almost certainly still be subject to the
overriding principle of not breaking the web.
I think Array#get/Array#set are the most reasonable suggestions offered so
far, but I don't think the added value will be enough to convince the
committee that it's worth adding to the already large API surface of the
language - and the asymmetry with the similar methods on Map
/Set
would
be problematic (note that Set#get(-1)
does not retrieve the last item in
the set, for example).
Let's not cry doomsday because there's not an easy path to adding "-1" array access, when indexing into a list of things *in the first place* is already a potential code smell. `endsWith` was able to be added because *it didn't break anything*. `contains` was renamed to `includes` because the former *did* break something. There's lots of examples of this principle at work. New things can be added any time they don't break the web. Nothing will ever be knowingly added that does break the web. Please accept that. Creating a new web language won't necessarily "solve" this "problem" - future iterations of *that* language would almost certainly still be subject to the overriding principle of not breaking the web. I think Array#get/Array#set are the most reasonable suggestions offered so far, but I don't think the added value will be enough to convince the committee that it's worth adding to the already large API surface of the language - and the asymmetry with the similar methods on `Map`/`Set` would be problematic (note that `Set#get(-1)` does not retrieve the last item in the set, for example). On Tue, Apr 19, 2016 at 1:17 AM, Tiddo Langerak <tiddolangerak at gmail.com> wrote: > If we're talking about adding a new method anyway, why not just add a more > general `get` method with support for both positive and negative indices? > That would be consistent with the other array methods, and additionally I > think it is more natural to use `arr.get(-2)` than `arr.last(1)`. Using > `last` to get anything but the very last element just seems weird to me. > > On 04/19/2016 10:00 AM, Bruno Jouhier wrote: > > Adding `last` to `Array.prototype` is no different than adding `endsWith` > to `String.prototype`. ES2015 did it. > > It won't break most existing code that defines `Array.prototype.last`. > Such code will just overwrite the new `last` method and will continue to > work as before. > > You won't be able to mix old libraries that have their own `last` method > with new code if the methods behave differently but that's a different > story; that's not breaking existing web pages. > > What will break though is existing code that test the existence of > `Array.prototype.last`; but `String.prototype.endsWith` had the same issue. > > last(1) would return last but one, and last() would be the same as last(0) > > > _______________________________________________ > es-discuss mailing listes-discuss at mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/76312a23/attachment.html>
2016-04-19 10:40 GMT+02:00 Jordan Harband <ljharb at gmail.com>:
(note that
Set#get(-1)
does not retrieve the last item in the set, for example).
Because Set.prototype.get doesn't even exist. And Set by definition is an unordered collection, so there is no "last" element.
I think Array.prototype.get and Array.prototype.set are the way to go - it should not break backward compatibility. And it's consistent with Array.prototype.slice behaviour.
BTW, this was discussed 3 years ago: esdiscuss.org/topic/array
2016-04-19 10:40 GMT+02:00 Jordan Harband <ljharb at gmail.com>: > (note that `Set#get(-1)` does not retrieve the last item in the set, for > example). > Because Set.prototype.get doesn't even exist. And Set by definition is an unordered collection, so there is no "last" element. I think Array.prototype.get and Array.prototype.set are the way to go - it should not break backward compatibility. And it's consistent with Array.prototype.slice behaviour. BTW, this was discussed 3 years ago: https://esdiscuss.org/topic/array-prototype-last -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/192cda3c/attachment.html>
And Set by definition is an unordered collection, so there is no "last" element.
Sets in ES6 are iterated in insertion order.
I don't think a .get or .set needs to be made for Array. Why would you use
arr.set(1, 4)
over arr[1] = 4
, and why should there be more ways of
doing the same thing? It would only ever be used for negative indices, and
Reflect.get/Reflect.set already exists without that behavior.
The original question was to use negative indices, which you can do with proxies. If a method should be added I think .last is the safest and would expect any implementation of it to have the same behavior.
An array[Symbol.last]
getter/setter would also be safe. You can even add
it yourself without collision.
var last = Symbol();
Reflect.defineProperty(Array.prototype, last, {
get: function () {
return Reflect.get(this, this.length - 1);
},
set: function (value) {
return Reflect.set(this, this.length - 1, value);
}
});
var arr = [1,2,3];
arr[last] = 0;
console.log(arr); // 1,2,0
Maybe a .last (string) property getter/setter would also work here.
> > And Set by definition is an unordered collection, so there is no "last" > element. Sets in ES6 are iterated in insertion order. I don't think a .get or .set needs to be made for Array. Why would you use `arr.set(1, 4)` over `arr[1] = 4`, and why should there be more ways of doing the same thing? It would only ever be used for negative indices, and Reflect.get/Reflect.set already exists without that behavior. The original question was to use negative indices, which you can do with proxies. If a method should be added I think .last is the safest and would expect any implementation of it to have the same behavior. An `array[Symbol.last]` getter/setter would also be safe. You can even add it yourself without collision. ```js var last = Symbol(); Reflect.defineProperty(Array.prototype, last, { get: function () { return Reflect.get(this, this.length - 1); }, set: function (value) { return Reflect.set(this, this.length - 1, value); } }); var arr = [1,2,3]; arr[last] = 0; console.log(arr); // 1,2,0 ``` On Tue, Apr 19, 2016 at 9:37 AM, Michał Wadas <michalwadas at gmail.com> wrote: > > 2016-04-19 10:40 GMT+02:00 Jordan Harband <ljharb at gmail.com>: > >> (note that `Set#get(-1)` does not retrieve the last item in the set, for >> example). >> > > > Because Set.prototype.get doesn't even exist. And Set by definition is an > unordered collection, so there is no "last" element. > > I think Array.prototype.get and Array.prototype.set are the way to go - it > should not break backward compatibility. And it's consistent with > Array.prototype.slice behaviour. > > > BTW, this was discussed 3 years ago: > https://esdiscuss.org/topic/array-prototype-last > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/cdf5b605/attachment.html>
On Apr 19, 2016, at 1:40 AM, Jordan Harband <ljharb at gmail.com> wrote: ... I think Array#get/Array#set are the most reasonable suggestions offered so far, but I don't think the added value will be enough to convince the committee that it's worth adding to the already large API surface of the language - and the asymmetry with the similar methods on
Map
/Set
would be problematic (note thatSet#get(-1)
does not retrieve the last item in the set, for example).
A different approach that addresses a broader set of use cases is described in web.archive.org/web/20141230040303/http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation, web.archive.org/web/20141230040303/http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation
Of course, that proposal is quite out of date (“private names” instead of Symbols, etc.) and would require some significant updating to the current state of the language.
> On Apr 19, 2016, at 1:40 AM, Jordan Harband <ljharb at gmail.com> wrote: > ... > I think Array#get/Array#set are the most reasonable suggestions offered so far, but I don't think the added value will be enough to convince the committee that it's worth adding to the already large API surface of the language - and the asymmetry with the similar methods on `Map`/`Set` would be problematic (note that `Set#get(-1)` does not retrieve the last item in the set, for example). A different approach that addresses a broader set of use cases is described in http://web.archive.org/web/20141230040303/http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation <http://web.archive.org/web/20141230040303/http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation> Of course, that proposal is quite out of date (“private names” instead of Symbols, etc.) and would require some significant updating to the current state of the language. Allen -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160419/8a297608/attachment.html>
In other programming languages such as python, you can specify the last element of a list with "list[-1]" but in javascript you have to do "list[list.length-1]". Is there maybe a way to make this feature in javascript?