[Proposal] New syntax for lazy getters

Andrea Giammarchi andrea.giammarchi at gmail.com
Tue Jun 12 07:47:43 UTC 2018


in case the counter proposal is not clear enough (apologies for that), this
should read simpler than that

```js
const take = (n, xs) => n === 0 ? null : xs && {
    head: xs.head,
    lazy tail() {
      const value = take(n - 1, xs.tail);
      Object.defineProperty(this, 'tail', {
        configurable: false,
        get: () => value
      });
      return value;
    }
};
```

Hope it's clear what I'd change.

Best Regards

On Tue, Jun 12, 2018 at 9:45 AM, Andrea Giammarchi <
andrea.giammarchi at gmail.com> wrote:

> * having an extra keyword ...
>
> On Tue, Jun 12, 2018 at 9:44 AM, Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> My 2 cents,
>>   I use lazy getters since about ever and I'd love to have such syntax in
>> place but I think there is room for some improvement / simplification in
>> terms of syntax.
>>
>> *## Keep it getish*
>>
>> From parsing perspective, introducing `lazy tail()` seems way simpler
>> than introducing `lazy tail:` for the simple reason that everything that
>> can parse `get tail()` and `set tail()` is in place already in every
>> engine. I don't write them but I'm sure having an extra keyboard to catch
>> shouldn't be crazy complicated.
>>
>> *## class compatible*
>>
>> because you used `delete this.tail` and mentioned functional programming,
>> I'd like to underline ES doesn't force anyone to one programming style or
>> another. That means new syntax should play nicely with classes too, and in
>> this case the proposal doesn't seem to address that because of the direct
>> value mutation, as generic property, and the removal of that property from
>> the object, something not needed if inherited.
>>
>> My variant would do the same, except it would keep the value an accessor:
>>
>> ```js
>> const take = (n, xs) => n === 0 ? null : xs && {
>>     head: xs.head,
>>     lazy tail() {
>>       return Object.defineProperty(this, 'tail', {
>>         configurable: false,
>>         get: (value =>
>>           // still a getter
>>           () => value
>>         )(
>>           // executed once
>>           take(n - 1, xs.tail)
>>         )
>>       }).tail;
>>     }
>> };
>> ```
>>
>> This would keep initial accessor configuration, in terms of
>> enumerability, but it will freeze its value forever and, on top of that,
>> this will play already well with current valid ES2015 classes syntax.
>>
>> I also believe myself proposed something similar a while ago (or somebody
>> else and I agreed with that proposal) but for some reason it never landed.
>>
>> Hopefully this time the outcome would be different.
>>
>> Best Regards
>>
>>
>>
>>
>> On Tue, Jun 12, 2018 at 9:13 AM, Aadit M Shah <aaditmshah at fastmail.fm>
>> wrote:
>>
>>> Hello TC39,
>>>
>>> I recently opened an issue <https://github.com/tc39/ecma262/issues/1223> in
>>> the tc39/ecma262 <https://github.com/tc39/ecma262> repository,
>>> proposing a new syntax for lazy getters, and I was directed to the
>>> CONTRIBUTING
>>> <https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md> page
>>> which stated that I should start a conversation on this mailing list.
>>>
>>> So, my feature proposal is to have syntactic sugar for creating lazy
>>> getters
>>> <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters>.
>>> To summarize my original proposal (which you can read by following the very
>>> first link above), I find that creating lazy getters is very verbose. For
>>> example, consider:
>>>
>>> const take = (n, xs) => n === 0 ? null : xs && {
>>>     head: xs.head,
>>>     get tail() {
>>>         delete this.tail;
>>>         return this.tail = take(n - 1, xs.tail);
>>>     }
>>> };
>>>
>>> My proposed solution is to add a new keyword lazy to the language. This
>>> keyword can only be used as a prefix to longhand property names in object
>>> initializers, and it defers the execution of the value expression until the
>>> property is accessed. In short, it's just syntactic sugar for lazy getters:
>>>
>>> const take = (n, xs) => n === 0 ? null : xs && {
>>>     head: xs.head,
>>>     lazy tail: take(n - 1, xs.tail)
>>> };
>>>
>>> This is purely syntactic sugar. The semantics of this new syntax would
>>> remain the same as that of the desugared syntax. In particular, calling
>>> Object.getOwnPropertyDescriptor(list, "tail") would return an accessor
>>> descriptor before accessing list.tail and a data descriptor afterwards.
>>>
>>> Furthermore, there are other advantages of having this syntactic sugar.
>>> For example, creating cyclic data structures becomes much easier. Examples
>>> are provided in my original proposal which is linked above. Hope to hear
>>> your thoughts on this.
>>>
>>> Regards,
>>> Aadit M Shah
>>>
>>> _______________________________________________
>>> 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/20180612/eeffdb11/attachment-0001.html>


More information about the es-discuss mailing list