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

Reply via email to