so in JavaScript that results into this._db() each time, resolved lazily with the first value returned once ?
I still think my approach is cleaner and more transparent. `get _thing() { return defineProperty(this, 'thing', value) }` but if your TS-ish stuff translates into that, works for me On Thu, Aug 31, 2017 at 8:49 PM, Isiah Meadows <isiahmead...@gmail.com> wrote: > It takes a function, and returns a function that (if necessary) > initializes the value and then gets it. > ----- > > 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 3:43 PM, Andrea Giammarchi > <andrea.giammar...@gmail.com> wrote: > > Sorry I don't speak TS, I speak ES. > > > > Can you please tell me in JavaScript what does that do? > > > > On Thu, Aug 31, 2017 at 8:18 PM, Isiah Meadows <isiahmead...@gmail.com> > > wrote: > >> > >> Note the TS-ish declaration above it. That's the variant I was > >> referring to (I presented about 3 different variants initially). > >> > >> ```ts > >> // The declaration I included > >> declare function lazy<T>(init: () => T): () => T; > >> ``` > >> > >> > >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi > >> <andrea.giammar...@gmail.com> wrote: > >> > it wouldn't work, would it ? I mean, you still have to pass through > the > >> > "ugly" _db.get() thingy, right? > >> > > >> > how do you access and trigger the lazy bit within the class? > >> > > >> > On Thu, Aug 31, 2017 at 7:56 PM, Isiah Meadows < > isiahmead...@gmail.com> > >> > wrote: > >> >> > >> >> What about this (using the stage 3 class fields proposal)? > >> >> > >> >> ```js > >> >> declare function lazy<T>(init: () => T): () => T; > >> >> > >> >> class WithLazyVals { > >> >> _db = lazy(() => new Promise(...)); > >> >> } > >> >> ``` > >> >> ----- > >> >> > >> >> 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 1:34 PM, Andrea Giammarchi > >> >> <andrea.giammar...@gmail.com> wrote: > >> >> >> this proposal doesn't compose well with classes > >> >> > > >> >> > to expand a little, if you were proposing > >> >> > > >> >> > ```js > >> >> > class WithLazyVals { > >> >> > lazy _db() { return new Promise(...); } > >> >> > } > >> >> > ``` > >> >> > > >> >> > I would've taken first flight to come over and hug you. > >> >> > > >> >> > Best Regards > >> >> > > >> >> > > >> >> > > >> >> > > >> >> > On Thu, Aug 31, 2017 at 6:25 PM, Andrea Giammarchi > >> >> > <andrea.giammar...@gmail.com> wrote: > >> >> >> > >> >> >> > How often do you start out with a class like this ... > >> >> >> > >> >> >> Never, like I've said. This is the lazy pattern I know since ever. > >> >> >> > >> >> >> ```js > >> >> >> class Foo { > >> >> >> get _db() { > >> >> >> return Object.defineProperty(this, '_db', { > >> >> >> value: new Promise((resolve, reject) => { > >> >> >> // open a database connection > >> >> >> // set up whatever tables you need to > >> >> >> // etc. > >> >> >> }) > >> >> >> })._db; > >> >> >> } > >> >> >> } > >> >> >> ``` > >> >> >> > >> >> >> Whenever you need, you just access `this._db`, no need to create > an > >> >> >> enumerable variable and a class method. > >> >> >> > >> >> >> It looks cleaner to me. > >> >> >> > >> >> >> > >> >> >> > Things you don't want to initialize right away because > >> >> >> > initialization > >> >> >> > >> >> >> You don't really have to convince me, I've written lazy properties > >> >> >> since > >> >> >> getters and setters were introduced [1] > >> >> >> > >> >> >> All I am saying is that this proposal doesn't compose well with > >> >> >> classes, > >> >> >> it's just yet another SuperPrimitive for the language. > >> >> >> > >> >> >> It is also something trivial to implement on user land, yet I > >> >> >> haven't > >> >> >> seen > >> >> >> many writing code like the following: > >> >> >> > >> >> >> ```js > >> >> >> function Lazy(fn) { > >> >> >> let c = false, v; > >> >> >> return {get(){ return c ? v : (c = !c, v = fn()) }}; > >> >> >> } > >> >> >> > >> >> >> var o = Lazy(() => Math.random()); > >> >> >> o.get(); // ... > >> >> >> ``` > >> >> >> > >> >> >> Maybe it's me that hasn't seen this widely adopted from some > >> >> >> library? > >> >> >> > >> >> >> Anyway, this is just my opinion, maybe others would be happy with > >> >> >> this. > >> >> >> > >> >> >> Best Regards > >> >> >> > >> >> >> [1] Class.lazy example > >> >> >> > >> >> >> > >> >> >> https://github.com/WebReflection/prototypal/blob/master/Class.md# > classlazycallback > >> >> >> > >> >> >> > >> >> >> > >> >> >> On Thu, Aug 31, 2017 at 6:03 PM, Isiah Meadows > >> >> >> <isiahmead...@gmail.com> > >> >> >> wrote: > >> >> >>> > >> >> >>> 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 > >> >> >>> >> >> > > >> >> >>> >> >> > > >> >> >>> >> > > >> >> >>> >> > > >> >> >>> > > >> >> >>> > > >> >> >> > >> >> >> > >> >> > > >> > > >> > > >> > >> ----- > >> > >> 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