It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
.NET's `System.Lazy<T>`, Swift's `lazy var`, among many other
languages. It's very useful for lazy initialization [1], such as
lazily setting up a database, requesting a resource, among other
costly things. [2]

How often do you start out with a class like this, where you have an
expensive resource you don't want to open right away?

```js
class Foo {
    constructor() {
        this._db = undefined
    }

    _initDb() {
        if (this._db) return this._db
        return this._db = new Promise((resolve, reject) => {
            // open a database connection
            // set up whatever tables you need to
            // etc.
        })
    }
}
```

Or maybe, a large lookup table that takes a while to build, and might
not even be used, so you don't want to do it on load?

```js
var table

function initTable() {
    if (table) return
    table = new Array(10000)
    // do some expensive calculations
}
```

Things you don't want to initialize right away because initialization
is expensive and/or the value might not even be used. That's the
problem I'm aiming to solve, and it's something I feel would be useful
in its own right in the language, about equal in importance to weak
references. (Slightly specialized, but the need is not non-zero.)

[1]: https://en.wikipedia.org/wiki/Lazy_initialization
[2]: 
https://stackoverflow.com/questions/978759/what-is-lazy-initialization-and-why-is-it-useful
-----

Isiah Meadows
m...@isiahmeadows.com

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Thu, Aug 31, 2017 at 12:23 PM, Andrea Giammarchi
<andrea.giammar...@gmail.com> wrote:
> right ... so ... I'm not sure I understand what this proposal would solve.
>
> Instead of this:
> ```js
> obj.val || (obj.val = getValue())
> ```
>
> you want to do this
> ```js
> (obj.val || (obj.val = new Lazy(getValue)).get();
> ```
>
> Where is the "win" and why is that?
>
>
>
> On Thu, Aug 31, 2017 at 5:18 PM, Isiah Meadows <isiahmead...@gmail.com>
> wrote:
>>
>> With my proposed `Lazy` class, if you were to use an instance as a
>> descriptor, the `this` value it'd receive would not be a `Lazy`
>> instance like it'd expect.
>>
>> Consider it the difference between `a.self` and `b.get()` in your
>> example. `b.get()` is what I'd be expecting.
>> -----
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>>
>> Looking for web consulting? Or a new website?
>> Send me an email and we can get started.
>> www.isiahmeadows.com
>>
>>
>> On Thu, Aug 31, 2017 at 12:12 PM, Andrea Giammarchi
>> <andrea.giammar...@gmail.com> wrote:
>> >> using it in a descriptor would get it passed the wrong `this`
>> >
>> > sorry, what?
>> >
>> > ```js
>> > var a = {};
>> > var b = {get() { return this; }};
>> > Object.defineProperty(a, 'self', b);
>> >
>> > a.self === a; // true
>> > ```
>> >
>> >
>> > On Thu, Aug 31, 2017 at 5:09 PM, Isiah Meadows <isiahmead...@gmail.com>
>> > wrote:
>> >>
>> >> No. `Lazy` is intended to be an object to be used directly, not a
>> >> descriptor of any kind.
>> >>
>> >> (My `lazy.get()` is an unbound method, so using it in a descriptor
>> >> would get it passed the wrong `this`.)
>> >> -----
>> >>
>> >> Isiah Meadows
>> >> m...@isiahmeadows.com
>> >>
>> >> Looking for web consulting? Or a new website?
>> >> Send me an email and we can get started.
>> >> www.isiahmeadows.com
>> >>
>> >>
>> >> On Thu, Aug 31, 2017 at 9:39 AM, Andrea Giammarchi
>> >> <andrea.giammar...@gmail.com> wrote:
>> >> > the following is how I usually consider lazy values
>> >> >
>> >> > ```js
>> >> > class Any {
>> >> >   _lazy(name) {
>> >> >     switch (name) {
>> >> >       case 'uid': return Math.random();
>> >> >       // others ... eventually
>> >> >     }
>> >> >   }
>> >> >   get uid() {
>> >> >     var value = this._lazy('uid');
>> >> >     // from now on, direct access
>> >> >     Object.defineProperty(this, 'uid', {value});
>> >> >     return value;
>> >> >   }
>> >> > }
>> >> >
>> >> > const a = new Any;
>> >> > a.uid === a.uid; // true
>> >> > ```
>> >> >
>> >> > If I understand correctly your proposal is to use Lazy as generic
>> >> > descriptor, is that correct ?
>> >> >
>> >> > ```js
>> >> > Object.defineProperty({}, 'something', new Lazy(function (val) {
>> >> >   return this.shakaLaka ? val : 'no shakaLaka';
>> >> > }));
>> >> > ```
>> >> >
>> >> > ???
>> >> >
>> >> > If that's the case I see already people confused by arrow function
>> >> > in case they need to access the context,
>> >> > plus no property access optimization once resolved.
>> >> >
>> >> > It's also not clear if such property can be set again later on (right
>> >> > now it
>> >> > cannot)
>> >> > 'cause lazy definition doesn't always necessarily mean inability to
>> >> > reassign.
>> >> >
>> >> > What am I missing/misunderstanding?
>> >> >
>> >> > Regards
>> >> >
>> >> >
>> >> >
>> >> > On Thu, Aug 31, 2017 at 2:21 PM, Isiah Meadows
>> >> > <isiahmead...@gmail.com>
>> >> > wrote:
>> >> >>
>> >> >> It'd be really nice if lazy values made it into the spec somehow.
>> >> >> I've
>> >> >> already found myself using things like this [1] quite a bit, and
>> >> >> I've
>> >> >> also found myself frequently initializing properties not on first
>> >> >> access.
>> >> >>
>> >> >> [1]:
>> >> >>
>> >> >> https://gist.github.com/isiahmeadows/4c0723bdfa555a1c2cb01341b323c3d4
>> >> >>
>> >> >> As for what would be a nice API, maybe something like one of these?
>> >> >>
>> >> >> ```js
>> >> >> class Lazy<T> {
>> >> >>     constructor(init: () => T);
>> >> >>     get(): T; // or error thrown
>> >> >> }
>> >> >>
>> >> >> function lazy<T>(init: () => T): () => T; // or error thrown
>> >> >>
>> >> >> function lazy<T>(init: () => T): {
>> >> >>     get(): T; // or error thrown
>> >> >> }
>> >> >> ```
>> >> >>
>> >> >> Alternatively, syntax might work, with `do` expression semantics:
>> >> >>
>> >> >> ```js
>> >> >> const x = lazy do { ... }
>> >> >> // expose via `x.get()` or just `x()`
>> >> >> ```
>> >> >>
>> >> >> -----
>> >> >>
>> >> >> Isiah Meadows
>> >> >> m...@isiahmeadows.com
>> >> >>
>> >> >> Looking for web consulting? Or a new website?
>> >> >> Send me an email and we can get started.
>> >> >> www.isiahmeadows.com
>> >> >> _______________________________________________
>> >> >> 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