it's not about being difficult, it's about compatibility with classes, where getters are OK since ever. However, since classes fields are in Stage 3 [1] maybe it's OK to have:
```js class Test { x = 123; lazy random = () => this.x + Math.random(); } ``` However, like you've noticed, while it's easy to reason about the context within a class declaration, it's easy to create a footgun outside that. ```js const test = { x: 123, lazy random: () => this.x + Math.random() }; ``` That is a whole new meaning of arrow function I'd rather like not to ever encounter. So what about extra new syntax? ```js class Test { x = 123; lazy random() => this.x + Math.random(); } const test = { x: 123, lazy random() => this.x + Math.random() }; ``` But I'm pretty sure at methods shorthand discussions that came up and for some reason didn't work. [1] https://github.com/tc39/proposal-class-fields#field-declarations On Tue, Jun 12, 2018 at 11:32 AM, Aadit M Shah <aaditms...@fastmail.fm> wrote: > Actually, from a parsing perspective I believe it shouldn't be too > difficult to implement the `lazy name: expression` syntax. In addition, > I'm not too keen on your `lazy name() { return expression; }` syntax > because: > > > 1. It's more verbose. > 2. It seems to me that it's no different than creating a regular > getter: > > const take = (n, xs) => n === 0 ? null : xs && { > head: xs.head, > get tail() { > const value = take(n - 1, xs.tail); > Object.defineProperty(this, "tail", { > configurable: false, > get: () => value > }); > return value; > } > }; > > > Regarding the second bullet point, I've probably misunderstood what you > were trying to convey. Perhaps you could elucidate. > > Anyway, making the property non-configurable after accessing it seems like > a reasonable thing to do. > > > On Tue, Jun 12, 2018, at 3:44 AM, Andrea Giammarchi 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 <aaditms...@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@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss