On June 12, 2018 2:37:05 PM GMT+02:00, he...@mailbox.sk wrote: >Actually, by malleable I meant only configurable:true, so one can >change it via Object.defineProp… api, I did not mean necessarily to >define it as value. > >I have no strong opinion on what should be there after the first >access, but it boils down on how will it be exposed via >Object.defineProperty, really, because as little as possible should be >changed, IOW as much as possible retained.
Not to create a confusion, I _do_not_ propose that both ways be working, what I wanted to say is that only o e should be chosen, and that will select what will be there as a replacement. Though, now that I think about it, lazy field = expr; and lazy getter() { return expr; } are different beasts. Anyway, as Andrea said, enough said for the moment. >So on case things are defined as (only pondering the property >descriptor here, the call is obvious): > > { lazy: true, get: () => Math.random() } … [1] > >or, bigger example: > >{ lazy: { configurable: false }, enumerable: false, get: () => >foos.length, set: x => console.log(`set ${x}`) } … [2] > >Then what should be generated is indeed a getter so that setter may be >retained as well in [2]. > >If the definition is: > >{ lazy: { configurable: false, writable: false, enumerable: true, >compute: () => Math.random() }, enumerable: false } … [3] > >then it defines a value (which is not enumerable until first accessed >thus created; contrived example, I know). > >This post also shows a proposal how to, in future proof way, define >what attributes will the replaced getter/value have: put it In lazy >field of prop descriptor, lazy: true means shortcut for “the default >way / Inherit from what is there now”. > >Herby > >On June 12, 2018 2:02:28 PM GMT+02:00, Aadit M Shah ><aaditms...@fastmail.fm> wrote: >>Okay, so my previous statement about field declarations in classes >>being >>invalid was incorrect. I didn't see Andrea's link to the class field >>declarations proposal[1]. Hence, from what I understand we're >>considering the following syntax: >>const zeros = { head: , lazy tail: this }; >> >>class Random { >> lazy value = Math.random(); >>} >> >>As for semantics, Herby's philosophy of "malleable unless specified >>otherwise" makes sense. Hence, the above code would be transpiled to: >>const zeros = { >> head: , >> get tail() { >> return Object.defineProperty(this, "tail", { >> value: this >> }).tail; >> } >>}; >> >>class Random { >> get value() { >> return Object.defineProperty(this, "value", { >> value: Math.random() >> }).value; >> } >>} >> >>I guess we'd also be adopting the syntax for private fields and static >>fields? For example, lazy #value and lazy static #value? >> >>On Tue, Jun 12, 2018, at 7:32 AM, he...@mailbox.sk wrote: >>> >>> >>> On June 12, 2018 11:32:22 AM GMT+02:00, 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 === ? null : xs && { head: xs.head, >>>> get >>>> tail() { const value = take(n - 1, xs.tail); >>>> Object.defineProperty(this, "tail", { configurable: >>false,>> get: () => value }); return value; } }; >>> >>> I am pretty sure Andrea mixed syntax of lazy getter with its >>> implementation for brevity, and the actual lazy getter would >>> look like:> >>> lazy tail() { return take(n - 1, xs.tail); } >>> >>>> 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. >>> >>> Here I disagree. No syntax construct so far forces immutability. The >>> get x() / set x() ones are configurable. If you defined lazy getter >>> so far by get(), you could have changed it using >>> Object.defineProperties if there was some strange need for it. You >>> had to explicitly freeze etc. or defineProperty with configurable >>> false if you wanted to make it so.> >>> This autofreezing if the value sticks out out this philosophy of " >>> malleable unless specified otherwise".> >>>> >>>> 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 get*ish** >>>>> >>>>> 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[1] in the tc39/ecma262[2] repository, >>>>>> proposing a new syntax for lazy getters, and I was directed to >>the>>>> CONTRIBUTING[3] 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[4]. 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 === ? 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 === ? 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 >>>>>> >>>> >>>> >>>> Links: >>>> >>>> 1. https://github.com/tc39/ecma262/issues/1223 >>>> 2. https://github.com/tc39/ecma262 >>>> 3. https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md >>>> 4. >>>> >>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters >> >>Links: >> >> 1. https://github.com/tc39/proposal-class-fields#field-declarations >_______________________________________________ >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