JavaScript Language feature Idea

Bob Myers rtm at gol.com
Tue Apr 19 04:59:04 UTC 2016


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>


More information about the es-discuss mailing list