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