Lazy evaluation

Andrea Giammarchi andrea.giammarchi at gmail.com
Mon Sep 11 09:35:04 UTC 2017


> For apps or internal classes I simply use _underscoreProps for the same
need.

that is still not an answer to lazy property definition ;-)

I agree in most you are saying but you keep diverging from the topic of
this thread: Lazy evaluation

Neither `wm.get(this)` nor `this._pseudoPrivate` are strictly solutions to
the topic.

That's all I'm saying.

Regards


On Mon, Sep 11, 2017 at 10:23 AM, Darien Valentine <valentinium at gmail.com>
wrote:

> I’m not sure what was sneaky haha ... it was in response to the prior
> discussion of that subject, and I think it is quite related to lazy props,
> example code aside, since lazy props are just a specific case for the more
> general pattern of properties with some form of associated state / stateful
> behavior.
>
> The benchmark is great info. I agree that the observability via
> hasOwnProperty/getOwnPropertyDescriptor is not at all likely to create
> issues for any given case, but I was speaking about my reservations with
> library code in mind. For apps or internal classes I simply use
> _underscoreProps for the same need. Perhaps property definition is still
> faster even then, in which case I’d switch to it for those cases. But for
> the public API of a lib, I prefer to stick with the keep-it-unobservable
> rule (people have relied on stranger things).
>
> On Mon, Sep 11, 2017 at 4:54 AM, Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> Darien you managed to sneak-in another pattern that has nothing to do
>> with laziness, it's rather an approach to simulate private variables
>> (exposing them though).
>>
>> To meaningfully compare your solution with mine you need these two
>> classes:
>>
>> ```js
>> const WM = new WeakMap();
>>
>> class CaseWM {
>>   get bar() {
>>     var shadow = WM.get(this);
>>     if (!shadow) {
>>       shadow = {bar: Math.random()};
>>       WM.set(this, shadow);
>>     }
>>     return shadow.bar;
>>   }
>> }
>>
>> class CaseLazy {
>>   get bar() {
>>     var value = Math.random();
>>     Object.defineProperty(this, 'bar', {value});
>>     return value;
>>   }
>> }
>> ```
>>
>> You can verify the benchmark here: https://jsperf.com/lazy-
>> property-patterns
>>
>> In my Chromium the lazy property is around 4X faster and there's no
>> GC/memory pressure due WeakMap.
>>
>> It's a matter of trades-off and compromise. I don't care about
>> `hasOwnProperty` for properties defined in the prototype, it's a misleading
>> check anyway and I don't see any real-world side effect, or better, I
>> cannot think of a single case I've had so far that would've been
>> problematic.
>>
>> I use the `in` operator and you should probably do the same if that's a
>> concern, or maybe explain why/when/how that could be a concern.
>>
>> Regards
>>
>>
>>
>>
>> On Mon, Sep 11, 2017 at 9:29 AM, Darien Valentine <valentinium at gmail.com>
>> wrote:
>>
>>> I use the WeakMap approach, too. Recently I find myself writing classes
>>> where the class has a corresponding WeakMap holding the "shadow instances"
>>> (as opposed to having one WM per property):
>>>
>>>     const PRIV = new WeakMap();
>>>
>>>     class Foo {
>>>       constructor() {
>>>         PRIV.set(this, { bar: 0, /*...other private state init...*/ });
>>>       }
>>>
>>>       get bar() {
>>>         return PRIV.get(this).bar;
>>>       }
>>>
>>>       set bar(val) {
>>>         if (!Number.isInteger(val)) throw new TypeError('no!');
>>>
>>>         PRIV.get(this).bar = val;
>>>       }
>>>     }
>>>
>>> I only do this for classes that are part of some public interface, where
>>> I want finer control over what state is exposed and wish to ensure that the
>>> object cannot enter an invalid state; for internal stuff it’d probably be
>>> overkill.
>>>
>>> The property-that-redefines-itself approach makes me uncomfortable
>>> because I don’t want property access to have observable side effects from
>>> the consumer side.
>>>
>>>     const foo = new ClassWithThatPattern;
>>>
>>>     Object.hasOwnProperty(foo, 'bar'); // false
>>>     foo.bar;
>>>     Object.hasOwnProperty(foo, 'bar'); // true
>>>
>>> In any case ... re: lazy initialization, I would agree that decorators
>>> represent a perfect way to make this pattern declarative & expressive. I
>>> suppose the private instance properties aspect of the class properties
>>> proposal, now at stage 3, also provides a way to reduce boilerplate by a
>>> bit, but not to the same degree.
>>>
>>> (I’d second kaizu’s opinion that the example of lazy init of a db seems
>>> kind of iffy, at least for node apps, where you kinda want to know your db
>>> is working before you even init the rest of the app, as failure almost
>>> invariably represents a terminal condition — but that said, it’s just an
>>> example, and there are certainly cases where lazy init of properties is
>>> worthwhile, e.g. when you have very large collections of many small
>>> instances and only an unknown-in-advance subset will actually need
>>> such-and-such properties calculated ultimately.)
>>>
>>> _______________________________________________
>>> 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/20170911/a73d4eea/attachment.html>


More information about the es-discuss mailing list