> What it's doesn't cover (and in my opinion should be the focus of a new
> proposal) is Decorators for literal objects. Something like the code below is
> yet not proposed:
>
> ``` js
> const foo = {
> @lazy bar: 3,
> };
> ```
what would happen if you tried to JSON.stringify foo? a core-value of
javascript to industry is as an idiot-proof/least-surprise language for
serializing json-data across browser <-> server. junior-programmers who
naively employ hard-to-serialize things like custom-getters in their low-level
code, mostly end up annoying senior-programmers when they have to debug
high-level integration-code that have problems baton-passing those states
around.
kai zhu
[email protected]
> On 12 Jun 2018, at 9:07 PM, Isiah Meadows <[email protected]> wrote:
>
> BTW, I proposed similar (lazy values) 9 months ago [1], and it's been
> on the list plenty of times [2]. I'd personally *love* to see it
> happen, but I find it not very likely it'd make it, especially as a
> property (since decorators can rectify that).
>
> [1]: https://esdiscuss.org/topic/lazy-evaluation
> [2]:
> https://www.google.com/search?q=site%3Aesdiscuss.org+lazy+property+OR+getter+OR+setter
>
> -----
>
> Isiah Meadows
> [email protected]
> www.isiahmeadows.com
>
>
> On Tue, Jun 12, 2018 at 8:48 AM, Andrea Giammarchi
> <[email protected]> wrote:
>> FWIW, I think to keep it simple `lazy: true` would be enough for the time
>> being.
>>
>> Having the new descriptor inside the descriptor seems a bit over engineering
>> at this point, imo, but having a field already won't exclude, in the
>> feature, the ability to improve that field (similar way addEventListener on
>> DOM got promoted from `(type, handler, boolean)` signature to `(type,
>> handler, boolean || options)`)
>>
>> I also agree that `lazy field = expr` is a different beast, and it won't
>> play well with descriptors as we know, but it might allow overwrites if
>> accessed directly.
>>
>> I wouldn't mind that as long as it plays well with objects and classes, and
>> as long as there is an official way to lazy define properties, and if it
>> could be so lazy that if redefined disappears, in that direct assignment
>> form, it would be a solution to all my cases.
>>
>> Regards
>>
>>
>> On Tue, Jun 12, 2018 at 2:37 PM, <[email protected]> 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.
>>>
>>> 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
>>> <[email protected]> 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, [email protected] wrote:
>>>>>
>>>>>
>>>>> On June 12, 2018 11:32:22 AM GMT+02:00, Aadit M Shah
>>>>> <[email protected]> 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
>>>>>>> <[email protected]> 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
>>>>>>>> [email protected]
>>>>>>>> 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
>> [email protected]
>> https://mail.mozilla.org/listinfo/es-discuss
>>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss