Re: Lazy evaluation

2017-09-16 Thread Andrea Giammarchi
there's nothing bad in using accessors (getters/setters) but you can do
what you want, just don't tell everyone what you do is the only way 'cause
it's not.

I'm off this thread, there's probably nothing else to add.

Best Regards

On Sat, Sep 16, 2017 at 9:15 AM, kai zhu <kaizhu...@gmail.com> wrote:

> you can call it dogma.  i call it the the javascript-way of solving
> frontend-engineering problems, which is simpler and more practical for
> laymen than what i learned from cs-theory in school using c++/java.
>
> its time we showed some pride in javascript (like the haskell/lisp/etc
> folks), and admit some of our 20+ year-old “hacks” are actually good
> design-patterns that rival and challenge traditional cs-teachings, instead
> of replacing them with bad-practices from other languages (*cough*
> operator-overloading *cough*).
>
> On Sep 14, 2017, at 4:26 PM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
> > please use normal method-calls instead, which are more maintainable
>
> no, thanks.
>
>
> > WeakMap's implicit-garbage-collecting feature is error-prone, hard to
> validate with tests, and generally becomes unmaintainable over time.
>
> no, thanks.
>
> We were discussing patterns here, nothing to "please don't" and IMO, dogma
> oriented rules are over-engineered anti-pattern too.
>
> Let's not make this ML an awkward place for who wants to just learn or
> explore JS language features, thanks.
>
>
>
>
>
> On Thu, Sep 14, 2017 at 9:55 AM, kai zhu <kaizhu...@gmail.com> wrote:
>
>> inline
>>
>> ```js
>>> class A {
>>>   #random;
>>>   get random() {
>>> return this.#random ||
>>>   (this.#random = Math.random());
>>>   }
>>> }
>>>
>>>
>>> // transpiled
>>> var A = function (wm) {
>>>   function A() {
>>> wm.set(this, {random: void 0});
>>>   }
>>>   Object.defineProperties(
>>> A.prototype,
>>> {
>>>   random: {
>>> configurable: true,
>>> get: function () {
>>>   return wm.get(this).random ||
>>> (wm.get(this).random = Math.random());
>>> }
>>>   }
>>> }
>>>   );
>>>   return A;
>>> }(new WeakMap);
>>> ```
>>
>>
>> - overloaded getters/setters and Object.defineProperties are generally 
>> *over-engineered
>> *anti-patterns in javascript-programming
>> * please use normal method-calls instead, which are more maintainable
>>
>> - WeakMap is an *over-engineered *anti-pattern in javascript-programming
>> * they are inferior to using a plain-object cache-dictionary in pretty
>> much every use-case.
>> * WeakMap's implicit-garbage-collecting feature is error-prone, hard to
>> validate with tests, and generally becomes unmaintainable over time.
>>
>> ```javascript
>> /*jslint node: true */
>> 'use strict';
>>
>> function LazyClass() {
>> this.cacheDict = {};
>> }
>> LazyClass.prototype.getRandomCached = function () {
>> this.cacheDict.random = this.cacheDict.random || Math.random();
>> return this.cacheDict.random;
>> };
>> LazyClass.prototype.clearCache = function () {
>> this.cacheDict = {};
>> };
>>
>> var lazyObject = new LazyClass();
>> console.log(lazyObject.getRandomCached());
>> console.log(lazyObject.getRandomCached());
>> lazyObject.clearCache();
>> console.log(lazyObject.getRandomCached());
>> ```
>>
>> 
>>
>>
>>
>> On Sep 13, 2017, at 9:32 PM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>> > Maybe you mean "will behave more or less as if (except more
>> efficiently)"?
>>
>> no, I meant: it will transpiled into something using private WeakMaps.
>>
>> I don't have any interest in talk nanoseconds for something unrelated to
>> the topic though.
>>
>> Best Regards
>>
>> On Wed, Sep 13, 2017 at 1:54 PM, Alex Kodat <alexko...@gmail.com> wrote:
>>
>>> What do you mean by “will be transpiled through”? My understanding of
>>> the private property proposal is that private properties will be in fixed
>>> slots (inaccessible outside the class) in the object so there would be no
>>> WeakMap. Maybe you mean "will behave more or less as if (except more
>>> efficiently)"?
>>>
>>> 
>>> Alex Kodat
>>>
>>> From: es-discuss [mailto:e

Re: Lazy evaluation

2017-09-16 Thread kai zhu
you can call it dogma.  i call it the the javascript-way of solving 
frontend-engineering problems, which is simpler and more practical for laymen 
than what i learned from cs-theory in school using c++/java.

its time we showed some pride in javascript (like the haskell/lisp/etc folks), 
and admit some of our 20+ year-old “hacks” are actually good design-patterns 
that rival and challenge traditional cs-teachings, instead of replacing them 
with bad-practices from other languages (*cough* operator-overloading *cough*).

> On Sep 14, 2017, at 4:26 PM, Andrea Giammarchi <andrea.giammar...@gmail.com> 
> wrote:
> 
> > please use normal method-calls instead, which are more maintainable
> 
> no, thanks.
> 
> 
> > WeakMap's implicit-garbage-collecting feature is error-prone, hard to 
> > validate with tests, and generally becomes unmaintainable over time.
> 
> no, thanks.
> 
> We were discussing patterns here, nothing to "please don't" and IMO, dogma 
> oriented rules are over-engineered anti-pattern too.
> 
> Let's not make this ML an awkward place for who wants to just learn or 
> explore JS language features, thanks.
> 
> 


> 
> On Thu, Sep 14, 2017 at 9:55 AM, kai zhu <kaizhu...@gmail.com 
> <mailto:kaizhu...@gmail.com>> wrote:
> inline
> 
>> ```js
>> class A {
>>   #random;
>>   get random() {
>> return this.#random ||
>>   (this.#random = Math.random());
>>   }
>> }
>> 
>> 
>> // transpiled
>> var A = function (wm) {
>>   function A() {
>> wm.set(this, {random: void 0});
>>   }
>>   Object.defineProperties(
>> A.prototype,
>> {
>>   random: {
>> configurable: true,
>> get: function () {
>>   return wm.get(this).random ||
>> (wm.get(this).random = Math.random());
>> }
>>   }
>> }
>>   );
>>   return A;
>> }(new WeakMap);
>> ```
> 
> 
> - overloaded getters/setters and Object.defineProperties are generally 
> over-engineered anti-patterns in javascript-programming
>   * please use normal method-calls instead, which are more maintainable
> 
> - WeakMap is an over-engineered anti-pattern in javascript-programming
>   * they are inferior to using a plain-object cache-dictionary in pretty 
> much every use-case.
>   * WeakMap's implicit-garbage-collecting feature is error-prone, hard to 
> validate with tests, and generally becomes unmaintainable over time.
> 
> ```javascript
> /*jslint node: true */
> 'use strict';
> 
> function LazyClass() {
> this.cacheDict = {};
> }
> LazyClass.prototype.getRandomCached = function () {
> this.cacheDict.random = this.cacheDict.random || Math.random();
> return this.cacheDict.random;
> };
> LazyClass.prototype.clearCache = function () {
> this.cacheDict = {};
> };
> 
> var lazyObject = new LazyClass();
> console.log(lazyObject.getRandomCached());
> console.log(lazyObject.getRandomCached());
> lazyObject.clearCache();
> console.log(lazyObject.getRandomCached());
> ```
> 
> 
> 
> 
> 
>> On Sep 13, 2017, at 9:32 PM, Andrea Giammarchi <andrea.giammar...@gmail.com 
>> <mailto:andrea.giammar...@gmail.com>> wrote:
>> 
>> > Maybe you mean "will behave more or less as if (except more efficiently)"?
>> 
>> no, I meant: it will transpiled into something using private WeakMaps.
>> 
>> I don't have any interest in talk nanoseconds for something unrelated to the 
>> topic though.
>> 
>> Best Regards
>> 
>> On Wed, Sep 13, 2017 at 1:54 PM, Alex Kodat <alexko...@gmail.com 
>> <mailto:alexko...@gmail.com>> wrote:
>> What do you mean by “will be transpiled through”? My understanding of the 
>> private property proposal is that private properties will be in fixed slots 
>> (inaccessible outside the class) in the object so there would be no WeakMap. 
>> Maybe you mean "will behave more or less as if (except more efficiently)"?
>> 
>> 
>> Alex Kodat
>> 
>> From: es-discuss [mailto:es-discuss-boun...@mozilla.org 
>> <mailto:es-discuss-boun...@mozilla.org>] On Behalf Of Andrea Giammarchi
>> Sent: Wednesday, September 13, 2017 2:31 AM
>> To: Steve Fink <sph...@gmail.com <mailto:sph...@gmail.com>>
>> Cc: es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
>> Subject: Re: Lazy evaluation
>> 
>> > The properties already existed, so defineProperty shouldn't modify the 
>> > order IIUC
>> 
>> well, nope. the pro

RE: Lazy evaluation

2017-09-14 Thread Alex Kodat
I realize in going over the last few e-mails for this thread, that as usual, 
I’m to blame for a bit of poor communication. I had intended to include the 
link to the public-private field proposal in my comments about it but whiffed. 
So the link: https://tc39.github.io/proposal-class-fields/. And yes, this link 
has appeared on other e-mails (sorry?).

This brings me to a (noobie) meta-question. This proposal is very interesting 
and looks nice to me and it is indicated to be in Stage 3. This suggests that 
it's pretty close to going in as-is into the ECMAScript standard? In case I'm 
not the last person in the world to find the process: 
https://tc39.github.io/process-document/.

So is this the appropriate forum for questions or comments about this spec? I 
notice many of the very interesting discussions leading up to this proposal 
happened elsewhere (mostly GitHub). But there's no link in the spec proposal to 
a discussion page so maybe this is it? Sorry if this is a stupid question.


Alex Kodat

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Lazy evaluation

2017-09-13 Thread Andrea Giammarchi
> Maybe you mean "will behave more or less as if (except more efficiently)"?

no, I meant: it will transpiled into something using private WeakMaps.

I don't have any interest in talk nanoseconds for something unrelated to
the topic though.

Best Regards

On Wed, Sep 13, 2017 at 1:54 PM, Alex Kodat <alexko...@gmail.com> wrote:

> What do you mean by “will be transpiled through”? My understanding of the
> private property proposal is that private properties will be in fixed slots
> (inaccessible outside the class) in the object so there would be no
> WeakMap. Maybe you mean "will behave more or less as if (except more
> efficiently)"?
>
> 
> Alex Kodat
>
> From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of
> Andrea Giammarchi
> Sent: Wednesday, September 13, 2017 2:31 AM
> To: Steve Fink <sph...@gmail.com>
> Cc: es-discuss@mozilla.org
> Subject: Re: Lazy evaluation
>
> > The properties already existed, so defineProperty shouldn't modify the
> order IIUC
>
> well, nope. the property existed in the prototype, not in the object.
>
> anyway, I guess private properties, that are a possible solution, will be
> transpiled through a WeakMap so that most likely anything discussed in here
> won't make sense and the future code would look like the following
>
> ```js
> class A {
>   #random;
>   get random() {
> return this.#random ||
>   (this.#random = Math.random());
>   }
> }
>
>
> // transpiled
> var A = function (wm) {
>   function A() {
> wm.set(this, {random: void 0});
>   }
>   Object.defineProperties(
> A.prototype,
> {
>   random: {
> configurable: true,
> get: function () {
>   return wm.get(this).random ||
> (wm.get(this).random = Math.random());
> }
>   }
> }
>   );
>   return A;
> }(new WeakMap);
> ```
>
>
>
>
>
>
> On Tue, Sep 12, 2017 at 10:39 PM, Steve Fink <mailto:sph...@gmail.com>
> wrote:
> My intent was only to respond to the performance analysis, specifically
> the implication that the only performance cost is in building the new
> hidden class. That is not the case; everything that touches those objects
> is affected as well.
>
> Whether or not it's still the right way to accomplish what you're after, I
> wasn't venturing an opinion. I could probably come up with a benchmark
> showing that your WeakMap approach can be faster -- eg by only accessing
> the property once, but feeding the old and new versions of the object into
> code that executes many many many times (doing something that never looks
> at that property, but is now slightly slower because it isn't monomorphic).
> But I suspect that for practical usage, redefining the property *is* faster
> than a WeakMap.
>
> If I were to look beyond for other solutions for your problem, then I'm
> just speculating. Can decorators populate multiple properties once the
> expensive work is done?
>
> I really want to tell the VM what's going on. I guess if it knew that
> accessing a getter property would convert it into a value property, and
> that it was doing something that would access the getter, then it could
> know to use the outgoing shape instead of the incoming shape. If only it
> knew that the getter was pure... but that way lies madness.
>
> Given that most code that would slow down would also trigger the lazy
> defineProperty(), it's really not going to be that much of an issue. Any
> access after the first will see a single shape.
>
> meh. Just take the perf hit, with awareness that you may be triggering
> slight slowdowns in all users of that object. Or you might not. I doubt
> it'll be that big, since you'll probably just end up with an inline cache
> for both shapes and there won't be all that much to optimize based on
> knowing a single shape.
>
> Oh, and I think I was wrong about property enumeration order. The
> properties already existed, so defineProperty shouldn't modify the order
> IIUC. (I am awful with language semantics.)
>
> On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
> Steve it's not solved in any other way. Even if you use a WeakMap with an
> object, you gonna lazy attach properties to that object.
>
> I honestly would like to see alternatives, if any, 'cause so far there is
> a benchmark and it proves already lazy property assignment is around 4x
> faster.
>
> So, it's easy to say "it's not the best approach" but apparently hard to
> prove that's the case?
>
> Looking forward to see better alternatives.
>
>
> On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink <mailto:sph...@gmail.com>
> wrote:
> On 9/11/17 

Re: Lazy evaluation

2017-09-13 Thread Isiah Meadows
Nit: `_` is a very valid identifier. (Consider Underscore/Lodash)

On Wed, Sep 13, 2017, 09:32 Alex Kodat <alexko...@gmail.com> wrote:

> Also, FWIW,  since we’re talking about nanoseconds of performance, here, I
> think slightly better than:
>
> return this.#random || (this.#random = Math.random());
>
> Is
>
> return (this.#random === undefined) ? this.#random = Math.random() :
> this.#random;
>
> This is because in the former, the compiled code has to determine whether
> this.#random is coercible into a Boolean. At the very least, it has to do
> an "Is this an object and, if so, not undefined ==> true" test. From first
> principles, the ternary expression is going to be more efficient. It simply
> checks if the value at this.#random is the same as the global undefined
> value and, if not, returns that value. No extra tests necessary.
>
> And at least with V8 theory == practice in this case (at least in all my
> tests). And yes, we're talking nanosecond here.
>
> While this looks a bit like the null propagation operator would be
> applicable, it's really not.
>
> Also FWIW, if you get tired of seeing/typing undefined, we add _ to the
> global object which means the above can be written as:
>
> return (this.#random === _) ? this.#random = Math.random() :
> this.#random;
>
> You might think that this would perform worse than the undefined but, in
> fact, for V8 it's identical -- undefined and _ are both just properties of
> the global object. I think this reads especially well in function calls
> where you want an undefined placeholder
>
>   fooey(_, "whatever");
>
> Visually, _ just says undefined to me.
>
> 
> Alex Kodat
>
> From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of
> Andrea Giammarchi
> Sent: Wednesday, September 13, 2017 2:31 AM
> To: Steve Fink <sph...@gmail.com>
> Cc: es-discuss@mozilla.org
> Subject: Re: Lazy evaluation
>
> > The properties already existed, so defineProperty shouldn't modify the
> order IIUC
>
> well, nope. the property existed in the prototype, not in the object.
>
> anyway, I guess private properties, that are a possible solution, will be
> transpiled through a WeakMap so that most likely anything discussed in here
> won't make sense and the future code would look like the following
>
> ```js
> class A {
>   #random;
>   get random() {
> return this.#random ||
>   (this.#random = Math.random());
>   }
> }
>
>
> // transpiled
> var A = function (wm) {
>   function A() {
> wm.set(this, {random: void 0});
>   }
>   Object.defineProperties(
> A.prototype,
> {
>   random: {
> configurable: true,
> get: function () {
>   return wm.get(this).random ||
> (wm.get(this).random = Math.random());
> }
>   }
> }
>   );
>   return A;
> }(new WeakMap);
> ```
>
>
>
> ___
> 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


RE: Lazy evaluation

2017-09-13 Thread Alex Kodat
Also, FWIW,  since we’re talking about nanoseconds of performance, here, I 
think slightly better than:

return this.#random || (this.#random = Math.random());

Is

return (this.#random === undefined) ? this.#random = Math.random() : 
this.#random;

This is because in the former, the compiled code has to determine whether 
this.#random is coercible into a Boolean. At the very least, it has to do an 
"Is this an object and, if so, not undefined ==> true" test. From first 
principles, the ternary expression is going to be more efficient. It simply 
checks if the value at this.#random is the same as the global undefined value 
and, if not, returns that value. No extra tests necessary.

And at least with V8 theory == practice in this case (at least in all my 
tests). And yes, we're talking nanosecond here.

While this looks a bit like the null propagation operator would be applicable, 
it's really not. 

Also FWIW, if you get tired of seeing/typing undefined, we add _ to the global 
object which means the above can be written as:

return (this.#random === _) ? this.#random = Math.random() : this.#random;

You might think that this would perform worse than the undefined but, in fact, 
for V8 it's identical -- undefined and _ are both just properties of the global 
object. I think this reads especially well in function calls where you want an 
undefined placeholder

  fooey(_, "whatever");

Visually, _ just says undefined to me.


Alex Kodat

From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Andrea 
Giammarchi
Sent: Wednesday, September 13, 2017 2:31 AM
To: Steve Fink <sph...@gmail.com>
Cc: es-discuss@mozilla.org
Subject: Re: Lazy evaluation

> The properties already existed, so defineProperty shouldn't modify the order 
> IIUC

well, nope. the property existed in the prototype, not in the object.

anyway, I guess private properties, that are a possible solution, will be 
transpiled through a WeakMap so that most likely anything discussed in here 
won't make sense and the future code would look like the following

```js
class A {
  #random;
  get random() {
return this.#random ||
  (this.#random = Math.random());
  }
}


// transpiled
var A = function (wm) {
  function A() {
wm.set(this, {random: void 0});
  }
  Object.defineProperties(
A.prototype,
{
  random: {
configurable: true,
get: function () {
  return wm.get(this).random ||
(wm.get(this).random = Math.random());
}
  }
}
  );
  return A;
}(new WeakMap);
```



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Lazy evaluation

2017-09-13 Thread Alex Kodat
What do you mean by “will be transpiled through”? My understanding of the 
private property proposal is that private properties will be in fixed slots 
(inaccessible outside the class) in the object so there would be no WeakMap. 
Maybe you mean "will behave more or less as if (except more efficiently)"?


Alex Kodat

From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Andrea 
Giammarchi
Sent: Wednesday, September 13, 2017 2:31 AM
To: Steve Fink <sph...@gmail.com>
Cc: es-discuss@mozilla.org
Subject: Re: Lazy evaluation

> The properties already existed, so defineProperty shouldn't modify the order 
> IIUC

well, nope. the property existed in the prototype, not in the object.

anyway, I guess private properties, that are a possible solution, will be 
transpiled through a WeakMap so that most likely anything discussed in here 
won't make sense and the future code would look like the following

```js
class A {
  #random;
  get random() {
return this.#random ||
  (this.#random = Math.random());
  }
}


// transpiled
var A = function (wm) {
  function A() {
wm.set(this, {random: void 0});
  }
  Object.defineProperties(
A.prototype,
{
  random: {
configurable: true,
get: function () {
  return wm.get(this).random ||
(wm.get(this).random = Math.random());
}
  }
}
  );
  return A;
}(new WeakMap);
```






On Tue, Sep 12, 2017 at 10:39 PM, Steve Fink <mailto:sph...@gmail.com> wrote:
My intent was only to respond to the performance analysis, specifically the 
implication that the only performance cost is in building the new hidden class. 
That is not the case; everything that touches those objects is affected as well.

Whether or not it's still the right way to accomplish what you're after, I 
wasn't venturing an opinion. I could probably come up with a benchmark showing 
that your WeakMap approach can be faster -- eg by only accessing the property 
once, but feeding the old and new versions of the object into code that 
executes many many many times (doing something that never looks at that 
property, but is now slightly slower because it isn't monomorphic). But I 
suspect that for practical usage, redefining the property *is* faster than a 
WeakMap.

If I were to look beyond for other solutions for your problem, then I'm just 
speculating. Can decorators populate multiple properties once the expensive 
work is done?

I really want to tell the VM what's going on. I guess if it knew that accessing 
a getter property would convert it into a value property, and that it was doing 
something that would access the getter, then it could know to use the outgoing 
shape instead of the incoming shape. If only it knew that the getter was 
pure... but that way lies madness.

Given that most code that would slow down would also trigger the lazy 
defineProperty(), it's really not going to be that much of an issue. Any access 
after the first will see a single shape.

meh. Just take the perf hit, with awareness that you may be triggering slight 
slowdowns in all users of that object. Or you might not. I doubt it'll be that 
big, since you'll probably just end up with an inline cache for both shapes and 
there won't be all that much to optimize based on knowing a single shape.

Oh, and I think I was wrong about property enumeration order. The properties 
already existed, so defineProperty shouldn't modify the order IIUC. (I am awful 
with language semantics.)

On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
Steve it's not solved in any other way. Even if you use a WeakMap with an 
object, you gonna lazy attach properties to that object. 

I honestly would like to see alternatives, if any, 'cause so far there is a 
benchmark and it proves already lazy property assignment is around 4x faster.

So, it's easy to say "it's not the best approach" but apparently hard to prove 
that's the case?

Looking forward to see better alternatives.


On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink <mailto:sph...@gmail.com> wrote:
On 9/11/17 5:36 AM, Matthew Robb wrote:
> I think it's irrelevant if internally VMs are not too happy. VMs are there to 
> solve our problems, not vice-versa ;-)
​
This ^​ is very important for everyone to get on board with. Regardless the 
cost should be negligible as the shape is only changing at the point of delayed 
init. This will cause, for example V8, to deop the object and have to build a 
new hidden class but only the one time. I guess it would potentially be 
interesting to support an own property that when undefined would delegate up 
the proto chain.

(I don't know, but) I would expect it to be worse than this. The shape is 
changing at the point of delayed init, which means that if an engine is 
associating the possible set of shapes with the constructor (or some other form 
of allocation site + mandatory initialization), then that site will produce 
multiple sha

Re: Lazy evaluation

2017-09-13 Thread Andrea Giammarchi
> The properties already existed, so defineProperty shouldn't modify the
order IIUC

well, nope. the property existed in the prototype, not in the object.

anyway, I guess private properties, that are a possible solution, will be
transpiled through a WeakMap so that most likely anything discussed in here
won't make sense and the future code would look like the following

```js
class A {
  #random;
  get random() {
return this.#random ||
  (this.#random = Math.random());
  }
}


// transpiled
var A = function (wm) {
  function A() {
wm.set(this, {random: void 0});
  }
  Object.defineProperties(
A.prototype,
{
  random: {
configurable: true,
get: function () {
  return wm.get(this).random ||
(wm.get(this).random = Math.random());
}
  }
}
  );
  return A;
}(new WeakMap);
```






On Tue, Sep 12, 2017 at 10:39 PM, Steve Fink  wrote:

> My intent was only to respond to the performance analysis, specifically
> the implication that the only performance cost is in building the new
> hidden class. That is not the case; everything that touches those objects
> is affected as well.
>
> Whether or not it's still the right way to accomplish what you're after, I
> wasn't venturing an opinion. I could probably come up with a benchmark
> showing that your WeakMap approach can be faster -- eg by only accessing
> the property once, but feeding the old and new versions of the object into
> code that executes many many many times (doing something that never looks
> at that property, but is now slightly slower because it isn't monomorphic).
> But I suspect that for practical usage, redefining the property *is* faster
> than a WeakMap.
>
> If I were to look beyond for other solutions for your problem, then I'm
> just speculating. Can decorators populate multiple properties once the
> expensive work is done?
>
> I really want to tell the VM what's going on. I guess if it knew that
> accessing a getter property would convert it into a value property, and
> that it was doing something that would access the getter, then it could
> know to use the outgoing shape instead of the incoming shape. If only it
> knew that the getter was pure... but that way lies madness.
>
> Given that most code that would slow down would also trigger the lazy
> defineProperty(), it's really not going to be that much of an issue. Any
> access after the first will see a single shape.
>
> meh. Just take the perf hit, with awareness that you may be triggering
> slight slowdowns in all users of that object. Or you might not. I doubt
> it'll be that big, since you'll probably just end up with an inline cache
> for both shapes and there won't be all that much to optimize based on
> knowing a single shape.
>
> Oh, and I think I was wrong about property enumeration order. The
> properties already existed, so defineProperty shouldn't modify the order
> IIUC. (I am awful with language semantics.)
>
> On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
>
> Steve it's not solved in any other way. Even if you use a WeakMap with an
> object, you gonna lazy attach properties to that object.
>
> I honestly would like to see alternatives, if any, 'cause so far there is
> a benchmark and it proves already lazy property assignment is around 4x
> faster.
>
> So, it's easy to say "it's not the best approach" but apparently hard to
> prove that's the case?
>
> Looking forward to see better alternatives.
>
>
> On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink  wrote:
>
>> On 9/11/17 5:36 AM, Matthew Robb wrote:
>>
>> > I think it's irrelevant if internally VMs are not too happy. VMs are
>> there to solve our problems, not vice-versa ;-)
>> ​
>> This ^​ is very important for everyone to get on board with. Regardless
>> the cost should be negligible as the shape is only changing at the point of
>> delayed init. This will cause, for example V8, to deop the object and have
>> to build a new hidden class but only the one time. I guess it would
>> potentially be interesting to support an own property that when undefined
>> would delegate up the proto chain.
>>
>>
>> (I don't know, but) I would expect it to be worse than this. The shape is
>> changing at the point of delayed init, which means that if an engine is
>> associating the possible set of shapes with the constructor (or some other
>> form of allocation site + mandatory initialization), then that site will
>> produce multiple shapes. All code using such objects, if they ever see both
>> shapes, will have to handle them both. Even worse, if you have several of
>> these delayed init properties and you end up lazily initializing them in
>> different orders (which seems relatively easy to do), then the internal
>> slot offsets will vary.
>>
>> You don't need to bend over backwards to make things easy for the VMs,
>> but you don't want to be mean to them either. :-)
>>
>> Not to mention that the observable property iteration 

RE: Lazy evaluation

2017-09-12 Thread Alex Kodat
I think to the degree that almost anyone would care, the public and private key 
proposal would address most of these issues. The private keys would not be 
affected by object shape so would have rip-roaring good performance. You'd 
simply need to provide getter functions in the prototype that check for 
undefined (or whatever) in the private variable, if not undefined return value, 
otherwise calculate value, set private variable, and return the value. Unless 
you're trying to calculate pi to a million decimal places this should be pretty 
much good enough for anything.

And it gives you the encapsulation you get in many other programming languages 
such as Java and C++. Public JS APIs would end up looking a lot like these for 
many applications -- a bunch of private variables and public functions 
including getters and setters. 

Basically, most of our code already looks like this but we use closures rather 
than private variable to accomplish this. And yes, there is a dark side to 
closures, specifically the challenge in implementing closed function that don't 
gobble up a lot of memory. In V8 if I construct an object with say 20 function 
properties that's 20 JSFunction objects V8 has to create, each one being on the 
order of 72 bytes per function. It's not too horrible if we don't have a lot of 
these and they have relatively long lives but problematic for lots of 
instantiation of objects with lots of functions. The private key proposal would 
address this issue. 


Alex Kodat

From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Matthew 
Robb
Sent: Tuesday, September 12, 2017 4:49 PM
To: Steve Fink <sph...@gmail.com>
Cc: es-discuss@mozilla.org >> es-discuss <es-discuss@mozilla.org>
Subject: Re: Lazy evaluation

I think it would be nice to be able to define an own data property on an object 
that while defined delegated up the prototype chain. This would allow a getter 
in the proto to lazily assign to the own property without triggering the 
property setter. This is even more nice when combined with super as you could 
conceivably hit the setter which itself could assign to the own property of the 
current instance.

Is that all too complicated? It seems perfect if only a little complicated.

On Sep 12, 2017 5:39 PM, "Steve Fink" <mailto:sph...@gmail.com> wrote:
My intent was only to respond to the performance analysis, specifically the 
implication that the only performance cost is in building the new hidden class. 
That is not the case; everything that touches those objects is affected as well.

Whether or not it's still the right way to accomplish what you're after, I 
wasn't venturing an opinion. I could probably come up with a benchmark showing 
that your WeakMap approach can be faster -- eg by only accessing the property 
once, but feeding the old and new versions of the object into code that 
executes many many many times (doing something that never looks at that 
property, but is now slightly slower because it isn't monomorphic). But I 
suspect that for practical usage, redefining the property *is* faster than a 
WeakMap.

If I were to look beyond for other solutions for your problem, then I'm just 
speculating. Can decorators populate multiple properties once the expensive 
work is done?

I really want to tell the VM what's going on. I guess if it knew that accessing 
a getter property would convert it into a value property, and that it was doing 
something that would access the getter, then it could know to use the outgoing 
shape instead of the incoming shape. If only it knew that the getter was 
pure... but that way lies madness.

Given that most code that would slow down would also trigger the lazy 
defineProperty(), it's really not going to be that much of an issue. Any access 
after the first will see a single shape.

meh. Just take the perf hit, with awareness that you may be triggering slight 
slowdowns in all users of that object. Or you might not. I doubt it'll be that 
big, since you'll probably just end up with an inline cache for both shapes and 
there won't be all that much to optimize based on knowing a single shape.

Oh, and I think I was wrong about property enumeration order. The properties 
already existed, so defineProperty shouldn't modify the order IIUC. (I am awful 
with language semantics.)

On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
Steve it's not solved in any other way. Even if you use a WeakMap with an 
object, you gonna lazy attach properties to that object. 

I honestly would like to see alternatives, if any, 'cause so far there is a 
benchmark and it proves already lazy property assignment is around 4x faster.

So, it's easy to say "it's not the best approach" but apparently hard to prove 
that's the case?

Looking forward to see better alternatives.


On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink <mailto:sph...@gmail.com> wrote:
On 9/11/17 5:36 AM, Matthew Robb wrote:
> I think it'

Re: Lazy evaluation

2017-09-12 Thread Matthew Robb
I think it would be nice to be able to define an own data property on an
object that while defined delegated up the prototype chain. This would
allow a getter in the proto to lazily assign to the own property without
triggering the property setter. This is even more nice when combined with
super as you could conceivably hit the setter which itself could assign to
the own property of the current instance.

Is that all too complicated? It seems perfect if only a little complicated.

On Sep 12, 2017 5:39 PM, "Steve Fink"  wrote:

> My intent was only to respond to the performance analysis, specifically
> the implication that the only performance cost is in building the new
> hidden class. That is not the case; everything that touches those objects
> is affected as well.
>
> Whether or not it's still the right way to accomplish what you're after, I
> wasn't venturing an opinion. I could probably come up with a benchmark
> showing that your WeakMap approach can be faster -- eg by only accessing
> the property once, but feeding the old and new versions of the object into
> code that executes many many many times (doing something that never looks
> at that property, but is now slightly slower because it isn't monomorphic).
> But I suspect that for practical usage, redefining the property *is* faster
> than a WeakMap.
>
> If I were to look beyond for other solutions for your problem, then I'm
> just speculating. Can decorators populate multiple properties once the
> expensive work is done?
>
> I really want to tell the VM what's going on. I guess if it knew that
> accessing a getter property would convert it into a value property, and
> that it was doing something that would access the getter, then it could
> know to use the outgoing shape instead of the incoming shape. If only it
> knew that the getter was pure... but that way lies madness.
>
> Given that most code that would slow down would also trigger the lazy
> defineProperty(), it's really not going to be that much of an issue. Any
> access after the first will see a single shape.
>
> meh. Just take the perf hit, with awareness that you may be triggering
> slight slowdowns in all users of that object. Or you might not. I doubt
> it'll be that big, since you'll probably just end up with an inline cache
> for both shapes and there won't be all that much to optimize based on
> knowing a single shape.
>
> Oh, and I think I was wrong about property enumeration order. The
> properties already existed, so defineProperty shouldn't modify the order
> IIUC. (I am awful with language semantics.)
>
> On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
>
> Steve it's not solved in any other way. Even if you use a WeakMap with an
> object, you gonna lazy attach properties to that object.
>
> I honestly would like to see alternatives, if any, 'cause so far there is
> a benchmark and it proves already lazy property assignment is around 4x
> faster.
>
> So, it's easy to say "it's not the best approach" but apparently hard to
> prove that's the case?
>
> Looking forward to see better alternatives.
>
>
> On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink  wrote:
>
>> On 9/11/17 5:36 AM, Matthew Robb wrote:
>>
>> > I think it's irrelevant if internally VMs are not too happy. VMs are
>> there to solve our problems, not vice-versa ;-)
>> ​
>> This ^​ is very important for everyone to get on board with. Regardless
>> the cost should be negligible as the shape is only changing at the point of
>> delayed init. This will cause, for example V8, to deop the object and have
>> to build a new hidden class but only the one time. I guess it would
>> potentially be interesting to support an own property that when undefined
>> would delegate up the proto chain.
>>
>>
>> (I don't know, but) I would expect it to be worse than this. The shape is
>> changing at the point of delayed init, which means that if an engine is
>> associating the possible set of shapes with the constructor (or some other
>> form of allocation site + mandatory initialization), then that site will
>> produce multiple shapes. All code using such objects, if they ever see both
>> shapes, will have to handle them both. Even worse, if you have several of
>> these delayed init properties and you end up lazily initializing them in
>> different orders (which seems relatively easy to do), then the internal
>> slot offsets will vary.
>>
>> You don't need to bend over backwards to make things easy for the VMs,
>> but you don't want to be mean to them either. :-)
>>
>> Not to mention that the observable property iteration order will vary.
>>
>> On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>> Hi Peter.
>>>
>>> Unless you have a faster way to do lazy property assignment, I think
>>> it's irrelevant if internally VMs are not too happy. VMs are there to solve
>>> our problems, not vice-versa ;-)
>>>
>>> Regards
>>>
>>>
>>>
>>> On Mon, Sep 11, 2017 at 11:54 AM, 

Re: Lazy evaluation

2017-09-12 Thread Steve Fink
My intent was only to respond to the performance analysis, specifically 
the implication that the only performance cost is in building the new 
hidden class. That is not the case; everything that touches those 
objects is affected as well.


Whether or not it's still the right way to accomplish what you're after, 
I wasn't venturing an opinion. I could probably come up with a benchmark 
showing that your WeakMap approach can be faster -- eg by only accessing 
the property once, but feeding the old and new versions of the object 
into code that executes many many many times (doing something that never 
looks at that property, but is now slightly slower because it isn't 
monomorphic). But I suspect that for practical usage, redefining the 
property *is* faster than a WeakMap.


If I were to look beyond for other solutions for your problem, then I'm 
just speculating. Can decorators populate multiple properties once the 
expensive work is done?


I really want to tell the VM what's going on. I guess if it knew that 
accessing a getter property would convert it into a value property, and 
that it was doing something that would access the getter, then it could 
know to use the outgoing shape instead of the incoming shape. If only it 
knew that the getter was pure... but that way lies madness.


Given that most code that would slow down would also trigger the lazy 
defineProperty(), it's really not going to be that much of an issue. Any 
access after the first will see a single shape.


meh. Just take the perf hit, with awareness that you may be triggering 
slight slowdowns in all users of that object. Or you might not. I doubt 
it'll be that big, since you'll probably just end up with an inline 
cache for both shapes and there won't be all that much to optimize based 
on knowing a single shape.


Oh, and I think I was wrong about property enumeration order. The 
properties already existed, so defineProperty shouldn't modify the order 
IIUC. (I am awful with language semantics.)


On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
Steve it's not solved in any other way. Even if you use a WeakMap with 
an object, you gonna lazy attach properties to that object.


I honestly would like to see alternatives, if any, 'cause so far there 
is a benchmark and it proves already lazy property assignment is 
around 4x faster.


So, it's easy to say "it's not the best approach" but apparently hard 
to prove that's the case?


Looking forward to see better alternatives.


On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink > wrote:


On 9/11/17 5:36 AM, Matthew Robb wrote:

> I think it's irrelevant if internally VMs are not too happy. VMs
are there to solve our problems, not vice-versa ;-)
​
This ^​ is very important for everyone to get on board with.
Regardless the cost should be negligible as the shape is only
changing at the point of delayed init. This will cause, for
example V8, to deop the object and have to build a new hidden
class but only the one time. I guess it would potentially be
interesting to support an own property that when undefined would
delegate up the proto chain.


(I don't know, but) I would expect it to be worse than this. The
shape is changing at the point of delayed init, which means that
if an engine is associating the possible set of shapes with the
constructor (or some other form of allocation site + mandatory
initialization), then that site will produce multiple shapes. All
code using such objects, if they ever see both shapes, will have
to handle them both. Even worse, if you have several of these
delayed init properties and you end up lazily initializing them in
different orders (which seems relatively easy to do), then the
internal slot offsets will vary.

You don't need to bend over backwards to make things easy for the
VMs, but you don't want to be mean to them either. :-)

Not to mention that the observable property iteration order will vary.

On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi
>
wrote:


Hi Peter.

Unless you have a faster way to do lazy property assignment,
I think it's irrelevant if internally VMs are not too happy.
VMs are there to solve our problems, not vice-versa ;-)

Regards



On Mon, Sep 11, 2017 at 11:54 AM, peter miller
>
wrote:

Hi Andrea,

```
class CaseLazy {
  get bar() {
    var value = Math.random();
    Object.defineProperty(this, 'bar', {value});
    return value;
  }
}
```


Doesn't this count as redefining the shape of the object?
Or are the compilers 

Re: Lazy evaluation

2017-09-12 Thread Naveen Chawla
https://www.npmjs.com/package/decorator-memoize
https://www.npmjs.com/package/memoized-decorator
https://www.npmjs.com/package/memoize-decorator

Relevant?

On Tue, 12 Sep 2017 at 03:18 Andrea Giammarchi 
wrote:

> Steve it's not solved in any other way. Even if you use a WeakMap with an
> object, you gonna lazy attach properties to that object.
>
> I honestly would like to see alternatives, if any, 'cause so far there is
> a benchmark and it proves already lazy property assignment is around 4x
> faster.
>
> So, it's easy to say "it's not the best approach" but apparently hard to
> prove that's the case?
>
> Looking forward to see better alternatives.
>
>
> On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink  wrote:
>
>> On 9/11/17 5:36 AM, Matthew Robb wrote:
>>
>> > I think it's irrelevant if internally VMs are not too happy. VMs are
>> there to solve our problems, not vice-versa ;-)
>> ​
>> This ^​ is very important for everyone to get on board with. Regardless
>> the cost should be negligible as the shape is only changing at the point of
>> delayed init. This will cause, for example V8, to deop the object and have
>> to build a new hidden class but only the one time. I guess it would
>> potentially be interesting to support an own property that when undefined
>> would delegate up the proto chain.
>>
>>
>> (I don't know, but) I would expect it to be worse than this. The shape is
>> changing at the point of delayed init, which means that if an engine is
>> associating the possible set of shapes with the constructor (or some other
>> form of allocation site + mandatory initialization), then that site will
>> produce multiple shapes. All code using such objects, if they ever see both
>> shapes, will have to handle them both. Even worse, if you have several of
>> these delayed init properties and you end up lazily initializing them in
>> different orders (which seems relatively easy to do), then the internal
>> slot offsets will vary.
>>
>> You don't need to bend over backwards to make things easy for the VMs,
>> but you don't want to be mean to them either. :-)
>>
>> Not to mention that the observable property iteration order will vary.
>>
>> On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>> Hi Peter.
>>>
>>> Unless you have a faster way to do lazy property assignment, I think
>>> it's irrelevant if internally VMs are not too happy. VMs are there to solve
>>> our problems, not vice-versa ;-)
>>>
>>> Regards
>>>
>>>
>>>
>>> On Mon, Sep 11, 2017 at 11:54 AM, peter miller >> > wrote:
>>>
 Hi Andrea,

 ```
> class CaseLazy {
>   get bar() {
> var value = Math.random();
> Object.defineProperty(this, 'bar', {value});
> return value;
>   }
> }
> ```
>

 Doesn't this count as redefining the shape of the object? Or are the
 compilers fine with it?

>>>
>>
>> ___
>> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Lazy evaluation

2017-09-11 Thread Andrea Giammarchi
Steve it's not solved in any other way. Even if you use a WeakMap with an
object, you gonna lazy attach properties to that object.

I honestly would like to see alternatives, if any, 'cause so far there is a
benchmark and it proves already lazy property assignment is around 4x
faster.

So, it's easy to say "it's not the best approach" but apparently hard to
prove that's the case?

Looking forward to see better alternatives.


On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink  wrote:

> On 9/11/17 5:36 AM, Matthew Robb wrote:
>
> > I think it's irrelevant if internally VMs are not too happy. VMs are
> there to solve our problems, not vice-versa ;-)
> ​
> This ^​ is very important for everyone to get on board with. Regardless
> the cost should be negligible as the shape is only changing at the point of
> delayed init. This will cause, for example V8, to deop the object and have
> to build a new hidden class but only the one time. I guess it would
> potentially be interesting to support an own property that when undefined
> would delegate up the proto chain.
>
>
> (I don't know, but) I would expect it to be worse than this. The shape is
> changing at the point of delayed init, which means that if an engine is
> associating the possible set of shapes with the constructor (or some other
> form of allocation site + mandatory initialization), then that site will
> produce multiple shapes. All code using such objects, if they ever see both
> shapes, will have to handle them both. Even worse, if you have several of
> these delayed init properties and you end up lazily initializing them in
> different orders (which seems relatively easy to do), then the internal
> slot offsets will vary.
>
> You don't need to bend over backwards to make things easy for the VMs, but
> you don't want to be mean to them either. :-)
>
> Not to mention that the observable property iteration order will vary.
>
> On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
> Hi Peter.
>>
>> Unless you have a faster way to do lazy property assignment, I think it's
>> irrelevant if internally VMs are not too happy. VMs are there to solve our
>> problems, not vice-versa ;-)
>>
>> Regards
>>
>>
>>
>> On Mon, Sep 11, 2017 at 11:54 AM, peter miller 
>> wrote:
>>
>>> Hi Andrea,
>>>
>>> ```
 class CaseLazy {
   get bar() {
 var value = Math.random();
 Object.defineProperty(this, 'bar', {value});
 return value;
   }
 }
 ```

>>>
>>> Doesn't this count as redefining the shape of the object? Or are the
>>> compilers fine with it?
>>>
>>
>
> ___
> 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


Re: Lazy evaluation

2017-09-11 Thread Steve Fink

On 9/11/17 5:36 AM, Matthew Robb wrote:
> I think it's irrelevant if internally VMs are not too happy. VMs are 
there to solve our problems, not vice-versa ;-)

​
This ^​ is very important for everyone to get on board with. 
Regardless the cost should be negligible as the shape is only changing 
at the point of delayed init. This will cause, for example V8, to deop 
the object and have to build a new hidden class but only the one time. 
I guess it would potentially be interesting to support an own property 
that when undefined would delegate up the proto chain.


(I don't know, but) I would expect it to be worse than this. The shape 
is changing at the point of delayed init, which means that if an engine 
is associating the possible set of shapes with the constructor (or some 
other form of allocation site + mandatory initialization), then that 
site will produce multiple shapes. All code using such objects, if they 
ever see both shapes, will have to handle them both. Even worse, if you 
have several of these delayed init properties and you end up lazily 
initializing them in different orders (which seems relatively easy to 
do), then the internal slot offsets will vary.


You don't need to bend over backwards to make things easy for the VMs, 
but you don't want to be mean to them either. :-)


Not to mention that the observable property iteration order will vary.

On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi 
> wrote:


Hi Peter.

Unless you have a faster way to do lazy property assignment, I
think it's irrelevant if internally VMs are not too happy. VMs are
there to solve our problems, not vice-versa ;-)

Regards



On Mon, Sep 11, 2017 at 11:54 AM, peter miller
> wrote:

Hi Andrea,

```
class CaseLazy {
  get bar() {
    var value = Math.random();
    Object.defineProperty(this, 'bar', {value});
    return value;
  }
}
```


Doesn't this count as redefining the shape of the object? Or
are the compilers fine with it?



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Lazy evaluation

2017-09-11 Thread Matthew Robb
> I think it's irrelevant if internally VMs are not too happy. VMs are
there to solve our problems, not vice-versa ;-)
​
This ^​ is very important for everyone to get on board with. Regardless the
cost should be negligible as the shape is only changing at the point of
delayed init. This will cause, for example V8, to deop the object and have
to build a new hidden class but only the one time. I guess it would
potentially be interesting to support an own property that when undefined
would delegate up the proto chain.


- Matthew Robb

On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Hi Peter.
>
> Unless you have a faster way to do lazy property assignment, I think it's
> irrelevant if internally VMs are not too happy. VMs are there to solve our
> problems, not vice-versa ;-)
>
> Regards
>
>
>
> On Mon, Sep 11, 2017 at 11:54 AM, peter miller 
> wrote:
>
>> Hi Andrea,
>>
>> ```
>>> class CaseLazy {
>>>   get bar() {
>>> var value = Math.random();
>>> Object.defineProperty(this, 'bar', {value});
>>> return value;
>>>   }
>>> }
>>> ```
>>>
>>
>> Doesn't this count as redefining the shape of the object? Or are the
>> compilers fine with it?
>>
>> Peter
>> --
>> "There were drawings, and sheets of paper with writing on them, and it
>> seemed that they were the sustenance of life, that here were the warlocks,
>> almost the vehicles of destruction of man's life, but at the same time the
>> very reason for his living." --- Maeve Gilmore/Titus Awakes.
>>
>
>
> ___
> 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


Re: Re: Lazy evaluation

2017-09-11 Thread Andrea Giammarchi
Hi Peter.

Unless you have a faster way to do lazy property assignment, I think it's
irrelevant if internally VMs are not too happy. VMs are there to solve our
problems, not vice-versa ;-)

Regards



On Mon, Sep 11, 2017 at 11:54 AM, peter miller 
wrote:

> Hi Andrea,
>
> ```
>> class CaseLazy {
>>   get bar() {
>> var value = Math.random();
>> Object.defineProperty(this, 'bar', {value});
>> return value;
>>   }
>> }
>> ```
>>
>
> Doesn't this count as redefining the shape of the object? Or are the
> compilers fine with it?
>
> Peter
> --
> "There were drawings, and sheets of paper with writing on them, and it
> seemed that they were the sustenance of life, that here were the warlocks,
> almost the vehicles of destruction of man's life, but at the same time the
> very reason for his living." --- Maeve Gilmore/Titus Awakes.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Lazy evaluation

2017-09-11 Thread peter miller

Hi Andrea,


```
class CaseLazy {
  get bar() {
var value = Math.random();
Object.defineProperty(this, 'bar', {value});
return value;
  }
}
```


Doesn't this count as redefining the shape of the object? Or are the  
compilers fine with it?


Peter
--
"There were drawings, and sheets of paper with writing on them, and it  
seemed that they were the sustenance of life, that here were the warlocks,  
almost the vehicles of destruction of man's life, but at the same time the  
very reason for his living." --- Maeve Gilmore/Titus Awakes.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Lazy evaluation

2017-09-11 Thread Darien Valentine
Hm, I’m sorry, but I don’t follow. The accessor + shadow property pattern
is a (rather common?) way to achieve lazy instantiation of properties,
since it provides the necessary hook for "do this on first access". But I’m
not suggesting it as a new solution in any case, I was only commenting on
the subject of ways-one-can-have-stateful-access (which, it seems to me,
laziness is an example use case of).

In any case, apologies if you thought my comment was unhelpful.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Lazy evaluation

2017-09-11 Thread Andrea Giammarchi
> 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 <valentin...@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.giammar...@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 <valentin...@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

Re: Re: Lazy evaluation

2017-09-11 Thread Darien Valentine
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.giammar...@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 
> 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@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Lazy evaluation

2017-09-11 Thread Andrea Giammarchi
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 
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@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Lazy evaluation

2017-09-11 Thread Darien Valentine
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@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Lazy evaluation

2017-09-11 Thread Andrea Giammarchi
Using weakmaps has disadvantages if instances are many, due pressure, and
it's also slower than just further property access, requiring a
`wm.get(...)` each time.

On top of that, you workaround the issue, but you don't solve it.

The platform way to solve your issue is the following:

```js
class Foo {
  get bar() {
if (this.constructor.prototype === this) throw 'unauthorized';
var result = [];
Object.defineProperty(this, 'bar', {value: result});
return result;
  }
}
```

I've used the long check instead of `this === Foo.prototype` because the
condition `this.constructor.prototype` works through inheritance chain too.

I also use a variable and return it instead because not everyone knows that
IE might go in recursion accessing a getter within the getter ;-)

Regards




On Mon, Sep 11, 2017 at 7:06 AM, Michał Wadas  wrote:

> BTW consider this:
>
> ```js
> class Foo {
>   get bar() {
> Object.defineProperty(this, 'bar', {value: []});
> return this.bar;
>   }
> }
> const a = new Foo;
> Foo.prototype.bar;
> const b = new Foo;
> const c = new Foo;
> // b.bar === c.bar
> ```
>
> So I recommend this instead:
>
> ```js
> const wm = new WeakMap;
> class Foo {
>   get bar() {
> if (!wm.has(this)) {
>   wm.set(this, []);
> }
> return wm.get(this);
>   }
> }
> const a = new Foo;
> Foo.prototype.bar;
> const b = new Foo;
> const c = new Foo;
> // b.bar !== c.bar
> ```
>
>
> On Fri, Sep 1, 2017 at 12:11 PM,  wrote:
>
>>
>>
>> On August 31, 2017 6:15:20 PM GMT+02:00, Isiah Meadows <
>> isiahmead...@gmail.com> wrote:
>> >Promises are inherently eager, but also async - consider that `new
>> >Promise(resolve => resolve(1))` is roughly equivalent to `var promise
>> >= Promise.resolve(1)`.
>> >
>> >My proposal is for a single immediate value, but created on demand
>> >(when you call `.get()`) rather than immediately.
>>
>> But then, it seems to me Andrea's self-rewriting getter gets to the point.
>>
>> Maybe there can be 'caching' getter planned as in:
>>
>> Object.defineProperty(foo, "bar", {
>>   get: () => "baz",
>>   caching: true
>> });
>>
>> with a shortcut
>>
>> Object.defineLazyValue(
>>   foo, "bar", () => "baz");
>>
>> which is implementable via a lib.
>>
>> Herby
>> >-
>> >
>> >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 10:37 AM, Naveen Chawla 
>> >wrote:
>> >> Could you not do this with a promise? If not, what's missing in
>> >promise that
>> >> you could do with "lazy"? Sorry if I've missed the whole premise
>> >>
>> >> On Thu, 31 Aug 2017 at 19:09 Andrea Giammarchi
>> >
>> >> 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
>> >
>> >>> 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 {
>>  constructor(init: () => T);
>>  get(): T; // or error thrown
>>  }
>> 
>>  function lazy(init: () => T): () => T; // or error thrown
>> 
>>  function lazy(init: () => T): {
>>  get(): T; // or error 

Re: Lazy evaluation

2017-09-11 Thread Michał Wadas
BTW consider this:

```js
class Foo {
  get bar() {
Object.defineProperty(this, 'bar', {value: []});
return this.bar;
  }
}
const a = new Foo;
Foo.prototype.bar;
const b = new Foo;
const c = new Foo;
// b.bar === c.bar
```

So I recommend this instead:

```js
const wm = new WeakMap;
class Foo {
  get bar() {
if (!wm.has(this)) {
  wm.set(this, []);
}
return wm.get(this);
  }
}
const a = new Foo;
Foo.prototype.bar;
const b = new Foo;
const c = new Foo;
// b.bar !== c.bar
```


On Fri, Sep 1, 2017 at 12:11 PM,  wrote:

>
>
> On August 31, 2017 6:15:20 PM GMT+02:00, Isiah Meadows <
> isiahmead...@gmail.com> wrote:
> >Promises are inherently eager, but also async - consider that `new
> >Promise(resolve => resolve(1))` is roughly equivalent to `var promise
> >= Promise.resolve(1)`.
> >
> >My proposal is for a single immediate value, but created on demand
> >(when you call `.get()`) rather than immediately.
>
> But then, it seems to me Andrea's self-rewriting getter gets to the point.
>
> Maybe there can be 'caching' getter planned as in:
>
> Object.defineProperty(foo, "bar", {
>   get: () => "baz",
>   caching: true
> });
>
> with a shortcut
>
> Object.defineLazyValue(
>   foo, "bar", () => "baz");
>
> which is implementable via a lib.
>
> Herby
> >-
> >
> >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 10:37 AM, Naveen Chawla 
> >wrote:
> >> Could you not do this with a promise? If not, what's missing in
> >promise that
> >> you could do with "lazy"? Sorry if I've missed the whole premise
> >>
> >> On Thu, 31 Aug 2017 at 19:09 Andrea Giammarchi
> >
> >> 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
> >
> >>> 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 {
>  constructor(init: () => T);
>  get(): T; // or error thrown
>  }
> 
>  function lazy(init: () => T): () => T; // or error thrown
> 
>  function lazy(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
> >___
> >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
>

Re: Lazy evaluation

2017-09-01 Thread herby


On August 31, 2017 6:15:20 PM GMT+02:00, Isiah Meadows  
wrote:
>Promises are inherently eager, but also async - consider that `new
>Promise(resolve => resolve(1))` is roughly equivalent to `var promise
>= Promise.resolve(1)`.
>
>My proposal is for a single immediate value, but created on demand
>(when you call `.get()`) rather than immediately.

But then, it seems to me Andrea's self-rewriting getter gets to the point.

Maybe there can be 'caching' getter planned as in:

Object.defineProperty(foo, "bar", {
  get: () => "baz",
  caching: true
});

with a shortcut

Object.defineLazyValue(
  foo, "bar", () => "baz");

which is implementable via a lib.

Herby
>-
>
>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 10:37 AM, Naveen Chawla 
>wrote:
>> Could you not do this with a promise? If not, what's missing in
>promise that
>> you could do with "lazy"? Sorry if I've missed the whole premise
>>
>> On Thu, 31 Aug 2017 at 19:09 Andrea Giammarchi
>
>> 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
>
>>> 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 {
 constructor(init: () => T);
 get(): T; // or error thrown
 }

 function lazy(init: () => T): () => T; // or error thrown

 function lazy(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
>___
>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


Re: Lazy evaluation

2017-09-01 Thread Andrea Giammarchi
then yes, decorators solve my use case pretty well.

```js
const lazy = (Class, prop, desc) => {
  var get = desc.get;
  desc.get = function () {
var result = get.apply(this, arguments);
Object.defineProperty(this, prop, {value: result});
return result;
  };
};

class A {
  @lazy
  get random() { return Math.random(); }
}

let a = new A;
a.random === a.random; // true
```

On Fri, Sep 1, 2017 at 8:16 AM, Michał Wadas  wrote:

> Stage 2, but they move really slow.
>
> On 1 Sep 2017 9:15 am, "Andrea Giammarchi" 
> wrote:
>
>> I thought decorators were nowhere higher than stage 0 (since ever)
>>
>> On Thu, Aug 31, 2017 at 9:53 PM, Michał Wadas 
>> wrote:
>>
>>> Why not something like decorators (not sure if decorator  proposal
>>> covers this already)?
>>>
>>> class Foo {
>>> @cached
>>> get bar() {
>>> return something(this);
>>> }
>>> }
>>>
>>> On 31 Aug 2017 10:30 pm, "Andrea Giammarchi" <
>>> andrea.giammar...@gmail.com> wrote:
>>>
>>> it's a matter of semantics.
>>>
>>> If I see this
>>>
>>> ```js
>>> var later = anyWrappingName(() => Math.random());
>>>
>>> // this is an assumption, not something obvious
>>> later() === later()
>>> ```
>>>
>>> If instead, I write this:
>>> ```js
>>> this.later === this.later;
>>> ```
>>>
>>> I expect that to never possibly fail like `arr.length === arr.length` or
>>> any `obj.prop`, in APIs with common sense, are equal to `obj.prop`.
>>>
>>> Invokes via instances and objects? It's never obvious at first look, if
>>> that is a method execution, but it's surely a new invoke.
>>>
>>> If you've trapped once the result behind the scene, reading that, is
>>> just noise for anyone eyes.
>>>
>>> So, once again, are we proposing something that results into exactly
>>> this?
>>>
>>> ```js
>>> class Later {
>>>   get thing() {
>>> return Object.defineProperty(this, 'thing', {value: anyLazy()});
>>>   }
>>>   constructor() {
>>> // always true, no matter when/where
>>> this.thing === this.thing;
>>>   }
>>> }
>>> ```
>>>
>>> If so, I'm happy. If not, this is confusing and solving not much.
>>>
>>>
>>> Best Regards
>>>
>>>
>>> On Thu, Aug 31, 2017 at 9:14 PM, Isiah Meadows 
>>> wrote:
>>>
 Yes. I'll point out that having it as a function, rather than a
 property-specific thing, makes it more flexible, since you can define
 constants as lazy values (I do that in quite a few places).

 If you want to make it transparent, it's not that hard to make a
 single-line getter/method that hides the abstraction.

 Granted, most of my lazy values are properties, not constants, so I
 could consider it an acceptable compromise.
 -

 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:54 PM, Andrea Giammarchi
  wrote:
 > 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
 >>  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(init: () => T): () => T;
 >> >> ```
 >> >>
 >> >>
 >> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
 >> >>  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
 >> >> > 
 

Re: Lazy evaluation

2017-09-01 Thread kdex
Just so that there is no confusion: There's also function expression 
decorators and method parameter decorators, both of which stage 0.

On Friday, September 1, 2017 9:16:55 AM CEST Michał Wadas wrote:
> Stage 2, but they move really slow.
> 
> On 1 Sep 2017 9:15 am, "Andrea Giammarchi" 
> 
> wrote:
> > I thought decorators were nowhere higher than stage 0 (since ever)
> > 
> > On Thu, Aug 31, 2017 at 9:53 PM, Michał Wadas 
> > 
> > wrote:
> >> Why not something like decorators (not sure if decorator  proposal covers
> >> this already)?
> >> 
> >> class Foo {
> >> @cached
> >> get bar() {
> >> return something(this);
> >> }
> >> }
> >> 
> >> On 31 Aug 2017 10:30 pm, "Andrea Giammarchi"
> >> 
> >> wrote:
> >> 
> >> it's a matter of semantics.
> >> 
> >> If I see this
> >> 
> >> ```js
> >> var later = anyWrappingName(() => Math.random());
> >> 
> >> // this is an assumption, not something obvious
> >> later() === later()
> >> ```
> >> 
> >> If instead, I write this:
> >> ```js
> >> this.later === this.later;
> >> ```
> >> 
> >> I expect that to never possibly fail like `arr.length === arr.length` or
> >> any `obj.prop`, in APIs with common sense, are equal to `obj.prop`.
> >> 
> >> Invokes via instances and objects? It's never obvious at first look, if
> >> that is a method execution, but it's surely a new invoke.
> >> 
> >> If you've trapped once the result behind the scene, reading that, is just
> >> noise for anyone eyes.
> >> 
> >> So, once again, are we proposing something that results into exactly
> >> this?
> >> 
> >> ```js
> >> class Later {
> >> 
> >>   get thing() {
> >>   
> >> return Object.defineProperty(this, 'thing', {value: anyLazy()});
> >>   
> >>   }
> >>   constructor() {
> >>   
> >> // always true, no matter when/where
> >> this.thing === this.thing;
> >>   
> >>   }
> >> 
> >> }
> >> ```
> >> 
> >> If so, I'm happy. If not, this is confusing and solving not much.
> >> 
> >> 
> >> Best Regards
> >> 
> >> 
> >> On Thu, Aug 31, 2017 at 9:14 PM, Isiah Meadows 
> >> 
> >> wrote:
> >>> Yes. I'll point out that having it as a function, rather than a
> >>> property-specific thing, makes it more flexible, since you can define
> >>> constants as lazy values (I do that in quite a few places).
> >>> 
> >>> If you want to make it transparent, it's not that hard to make a
> >>> single-line getter/method that hides the abstraction.
> >>> 
> >>> Granted, most of my lazy values are properties, not constants, so I
> >>> could consider it an acceptable compromise.
> >>> -
> >>> 
> >>> 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:54 PM, Andrea Giammarchi
> >>> 
> >>>  wrote:
> >>> > 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  >>> > 
> >>> > 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
> >>> >> 
> >>> >>  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(init: () => T): () => T;
> >>> >> >> ```
> >>> >> >> 
> >>> >> >> 
> >>> >> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
> >>> >> >> 
> >>> >> >>  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
> >>> >> >> > 

Re: Lazy evaluation

2017-09-01 Thread Michał Wadas
Stage 2, but they move really slow.

On 1 Sep 2017 9:15 am, "Andrea Giammarchi" 
wrote:

> I thought decorators were nowhere higher than stage 0 (since ever)
>
> On Thu, Aug 31, 2017 at 9:53 PM, Michał Wadas 
> wrote:
>
>> Why not something like decorators (not sure if decorator  proposal covers
>> this already)?
>>
>> class Foo {
>> @cached
>> get bar() {
>> return something(this);
>> }
>> }
>>
>> On 31 Aug 2017 10:30 pm, "Andrea Giammarchi" 
>> wrote:
>>
>> it's a matter of semantics.
>>
>> If I see this
>>
>> ```js
>> var later = anyWrappingName(() => Math.random());
>>
>> // this is an assumption, not something obvious
>> later() === later()
>> ```
>>
>> If instead, I write this:
>> ```js
>> this.later === this.later;
>> ```
>>
>> I expect that to never possibly fail like `arr.length === arr.length` or
>> any `obj.prop`, in APIs with common sense, are equal to `obj.prop`.
>>
>> Invokes via instances and objects? It's never obvious at first look, if
>> that is a method execution, but it's surely a new invoke.
>>
>> If you've trapped once the result behind the scene, reading that, is just
>> noise for anyone eyes.
>>
>> So, once again, are we proposing something that results into exactly this?
>>
>> ```js
>> class Later {
>>   get thing() {
>> return Object.defineProperty(this, 'thing', {value: anyLazy()});
>>   }
>>   constructor() {
>> // always true, no matter when/where
>> this.thing === this.thing;
>>   }
>> }
>> ```
>>
>> If so, I'm happy. If not, this is confusing and solving not much.
>>
>>
>> Best Regards
>>
>>
>> On Thu, Aug 31, 2017 at 9:14 PM, Isiah Meadows 
>> wrote:
>>
>>> Yes. I'll point out that having it as a function, rather than a
>>> property-specific thing, makes it more flexible, since you can define
>>> constants as lazy values (I do that in quite a few places).
>>>
>>> If you want to make it transparent, it's not that hard to make a
>>> single-line getter/method that hides the abstraction.
>>>
>>> Granted, most of my lazy values are properties, not constants, so I
>>> could consider it an acceptable compromise.
>>> -
>>>
>>> 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:54 PM, Andrea Giammarchi
>>>  wrote:
>>> > 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 >> >
>>> > 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
>>> >>  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(init: () => T): () => T;
>>> >> >> ```
>>> >> >>
>>> >> >>
>>> >> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
>>> >> >>  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
>>> >> >> > 
>>> >> >> > wrote:
>>> >> >> >>
>>> >> >> >> What about this (using the stage 3 class fields proposal)?
>>> >> >> >>
>>> >> >> >> ```js
>>> >> >> >> declare function lazy(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 

Re: Lazy evaluation

2017-09-01 Thread Andrea Giammarchi
I thought decorators were nowhere higher than stage 0 (since ever)

On Thu, Aug 31, 2017 at 9:53 PM, Michał Wadas  wrote:

> Why not something like decorators (not sure if decorator  proposal covers
> this already)?
>
> class Foo {
> @cached
> get bar() {
> return something(this);
> }
> }
>
> On 31 Aug 2017 10:30 pm, "Andrea Giammarchi" 
> wrote:
>
> it's a matter of semantics.
>
> If I see this
>
> ```js
> var later = anyWrappingName(() => Math.random());
>
> // this is an assumption, not something obvious
> later() === later()
> ```
>
> If instead, I write this:
> ```js
> this.later === this.later;
> ```
>
> I expect that to never possibly fail like `arr.length === arr.length` or
> any `obj.prop`, in APIs with common sense, are equal to `obj.prop`.
>
> Invokes via instances and objects? It's never obvious at first look, if
> that is a method execution, but it's surely a new invoke.
>
> If you've trapped once the result behind the scene, reading that, is just
> noise for anyone eyes.
>
> So, once again, are we proposing something that results into exactly this?
>
> ```js
> class Later {
>   get thing() {
> return Object.defineProperty(this, 'thing', {value: anyLazy()});
>   }
>   constructor() {
> // always true, no matter when/where
> this.thing === this.thing;
>   }
> }
> ```
>
> If so, I'm happy. If not, this is confusing and solving not much.
>
>
> Best Regards
>
>
> On Thu, Aug 31, 2017 at 9:14 PM, Isiah Meadows 
> wrote:
>
>> Yes. I'll point out that having it as a function, rather than a
>> property-specific thing, makes it more flexible, since you can define
>> constants as lazy values (I do that in quite a few places).
>>
>> If you want to make it transparent, it's not that hard to make a
>> single-line getter/method that hides the abstraction.
>>
>> Granted, most of my lazy values are properties, not constants, so I
>> could consider it an acceptable compromise.
>> -
>>
>> 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:54 PM, Andrea Giammarchi
>>  wrote:
>> > 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 
>> > 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
>> >>  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(init: () => T): () => T;
>> >> >> ```
>> >> >>
>> >> >>
>> >> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
>> >> >>  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
>> >> >> > 
>> >> >> > wrote:
>> >> >> >>
>> >> >> >> What about this (using the stage 3 class fields proposal)?
>> >> >> >>
>> >> >> >> ```js
>> >> >> >> declare function lazy(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
>> >> >> >>  wrote:
>> >> >> >> >> this proposal doesn't compose well with classes
>> >> >> >> >
>> >> >> >> > to expand a little, if you were proposing
>> >> >> >> >
>> >> >> >> > ```js
>> >> >> >> > class WithLazyVals {

Re: Lazy evaluation

2017-08-31 Thread kai zhu
inline

> On Sep 1, 2017, at 1:03 AM, Isiah Meadows  wrote:
> 
> It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
> .NET's `System.Lazy`, 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.
>})
>}
> }
> ```

lazy db-initialization is over-engineering and unnecessary.  almost all 
applications i encounter can be designed more simply with explicit 
db-initialization during startup.  the only problem that arises is when the 
user tries to access the db before db-initialization completes.  my solution 
(for indexeddb) is to wrap every db-crud method with a deferred-callback that 
waits for db-initialization to complete (or a promise object as andreas 
mentioned).

https://kaizhu256.github.io/node-db-lite/build..master..travis-ci.org/apidoc.html#apidoc.element.db-lite.storageDefer
 

storageGetItem = function (key, onError) {
/*
 * this function will get the item with the given key from storage
 */
defer({ action: 'getItem', key: key }, onError);
}
storageRemoveItem = function (key, onError) {
/*
 * this function will remove the item with the given key from storage
 */
defer({ action: 'removeItem', key: key }, onError);
}
storageSetItem = function (key, value, onError) {
/*
 * this function will set the item with the given key and value to storage
 */
defer({ action: 'setItem', key: key, value: value }, onError);
}
storageDefer = function (options, onError) {
/*
 * this function will defer options.action until storage is ready
 */
var data, isDone, objectStore, onError2, request, tmp;
onError = onError || function (error) {
// validate no error occurred
console.assert(!error, error);
};
if (!storage) {
deferList.push(function () {
defer(options, onError);
});
init();
return;
}
switch (modeJs) {
case 'browser':
onError2 = function () {
/* istanbul ignore next */
if (isDone) {
return;
}
isDone = true;
onError(
request && (request.error || request.transaction.error),
data || request.result || ''
);
};
switch (options.action) {
case 'clear':
case 'removeItem':
case 'setItem':
objectStore = storage
.transaction(storageDir, 'readwrite')
.objectStore(storageDir);
break;
default:
objectStore = storage
.transaction(storageDir, 'readonly')
.objectStore(storageDir);
}
switch (options.action) {
case 'clear':
request = objectStore.clear();
break;
case 'getItem':
request = objectStore.get(String(options.key));
break;
case 'keys':
data = [];
request = objectStore.openCursor();
request.onsuccess = function () {
if (!request.result) {
onError2();
return;
}
data.push(request.result.key);
request.result.continue();
};
break;
case 'length':
request = objectStore.count();
break;
case 'removeItem':
request = objectStore.delete(String(options.key));
break;
case 'setItem':
request = objectStore.put(options.value, String(options.key));
break;
}
['onabort', 'onerror', 'onsuccess'].forEach(function (handler) {
request[handler] = request[handler] || onError2;
});
// debug request
local._debugStorageRequest = request;
break;
case 'node':
switch (options.action) {
case 'clear':
child_process.spawnSync('rm -f ' + storage + '/*', {
shell: true,
stdio: ['ignore', 1, 2]
});
setTimeout(onError);
break;
case 'getItem':
fs.readFile(
storage + '/' + encodeURIComponent(String(options.key)),
'utf8',
// ignore error
function (error, data) {
  

Re: Lazy evaluation

2017-08-31 Thread Michał Wadas
Why not something like decorators (not sure if decorator  proposal covers
this already)?

class Foo {
@cached
get bar() {
return something(this);
}
}

On 31 Aug 2017 10:30 pm, "Andrea Giammarchi" 
wrote:

it's a matter of semantics.

If I see this

```js
var later = anyWrappingName(() => Math.random());

// this is an assumption, not something obvious
later() === later()
```

If instead, I write this:
```js
this.later === this.later;
```

I expect that to never possibly fail like `arr.length === arr.length` or
any `obj.prop`, in APIs with common sense, are equal to `obj.prop`.

Invokes via instances and objects? It's never obvious at first look, if
that is a method execution, but it's surely a new invoke.

If you've trapped once the result behind the scene, reading that, is just
noise for anyone eyes.

So, once again, are we proposing something that results into exactly this?

```js
class Later {
  get thing() {
return Object.defineProperty(this, 'thing', {value: anyLazy()});
  }
  constructor() {
// always true, no matter when/where
this.thing === this.thing;
  }
}
```

If so, I'm happy. If not, this is confusing and solving not much.


Best Regards


On Thu, Aug 31, 2017 at 9:14 PM, Isiah Meadows 
wrote:

> Yes. I'll point out that having it as a function, rather than a
> property-specific thing, makes it more flexible, since you can define
> constants as lazy values (I do that in quite a few places).
>
> If you want to make it transparent, it's not that hard to make a
> single-line getter/method that hides the abstraction.
>
> Granted, most of my lazy values are properties, not constants, so I
> could consider it an acceptable compromise.
> -
>
> 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:54 PM, Andrea Giammarchi
>  wrote:
> > 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 
> > 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
> >>  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(init: () => T): () => T;
> >> >> ```
> >> >>
> >> >>
> >> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
> >> >>  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
> >> >> > 
> >> >> > wrote:
> >> >> >>
> >> >> >> What about this (using the stage 3 class fields proposal)?
> >> >> >>
> >> >> >> ```js
> >> >> >> declare function lazy(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
> >> >> >>  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
> >> >> >> > 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
it's a matter of semantics.

If I see this

```js
var later = anyWrappingName(() => Math.random());

// this is an assumption, not something obvious
later() === later()
```

If instead, I write this:
```js
this.later === this.later;
```

I expect that to never possibly fail like `arr.length === arr.length` or
any `obj.prop`, in APIs with common sense, are equal to `obj.prop`.

Invokes via instances and objects? It's never obvious at first look, if
that is a method execution, but it's surely a new invoke.

If you've trapped once the result behind the scene, reading that, is just
noise for anyone eyes.

So, once again, are we proposing something that results into exactly this?

```js
class Later {
  get thing() {
return Object.defineProperty(this, 'thing', {value: anyLazy()});
  }
  constructor() {
// always true, no matter when/where
this.thing === this.thing;
  }
}
```

If so, I'm happy. If not, this is confusing and solving not much.


Best Regards


On Thu, Aug 31, 2017 at 9:14 PM, Isiah Meadows 
wrote:

> Yes. I'll point out that having it as a function, rather than a
> property-specific thing, makes it more flexible, since you can define
> constants as lazy values (I do that in quite a few places).
>
> If you want to make it transparent, it's not that hard to make a
> single-line getter/method that hides the abstraction.
>
> Granted, most of my lazy values are properties, not constants, so I
> could consider it an acceptable compromise.
> -
>
> 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:54 PM, Andrea Giammarchi
>  wrote:
> > 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 
> > 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
> >>  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(init: () => T): () => T;
> >> >> ```
> >> >>
> >> >>
> >> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
> >> >>  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
> >> >> > 
> >> >> > wrote:
> >> >> >>
> >> >> >> What about this (using the stage 3 class fields proposal)?
> >> >> >>
> >> >> >> ```js
> >> >> >> declare function lazy(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
> >> >> >>  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
> >> >> >> >  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.
> >> >> >> >>
> >> >> >> 

Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
Yes. I'll point out that having it as a function, rather than a
property-specific thing, makes it more flexible, since you can define
constants as lazy values (I do that in quite a few places).

If you want to make it transparent, it's not that hard to make a
single-line getter/method that hides the abstraction.

Granted, most of my lazy values are properties, not constants, so I
could consider it an acceptable compromise.
-

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:54 PM, Andrea Giammarchi
 wrote:
> 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 
> 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
>>  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 
>> > 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(init: () => T): () => T;
>> >> ```
>> >>
>> >>
>> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
>> >>  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
>> >> > 
>> >> > wrote:
>> >> >>
>> >> >> What about this (using the stage 3 class fields proposal)?
>> >> >>
>> >> >> ```js
>> >> >> declare function lazy(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
>> >> >>  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
>> >> >> >  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
>> >> >> >> 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
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 
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
>  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 
> > 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(init: () => T): () => T;
> >> ```
> >>
> >>
> >> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
> >>  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(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
> >> >>  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
> >> >> >  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
> >> >> >> 
> >> >> >> wrote:
> >> >> >>>
> >> >> >>> It'd solve a problem similarly to Kotlin's `by lazy { ... }`

Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
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
 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 
> 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(init: () => T): () => T;
>> ```
>>
>>
>> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
>>  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 
>> > wrote:
>> >>
>> >> What about this (using the stage 3 class fields proposal)?
>> >>
>> >> ```js
>> >> declare function lazy(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
>> >>  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
>> >> >  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
>> >> >> 
>> >> >> wrote:
>> >> >>>
>> >> >>> It'd solve a problem similarly to Kotlin's `by lazy { ... }`
>> >> >>> delegate,
>> >> >>> .NET's `System.Lazy`, 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 = 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
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 
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(init: () => T): () => T;
> ```
>
>
> On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
>  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 
> > wrote:
> >>
> >> What about this (using the stage 3 class fields proposal)?
> >>
> >> ```js
> >> declare function lazy(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
> >>  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
> >> >  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`, 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(1)
> >> >>> // do some 

Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
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(init: () => T): () => T;
```


On Thu, Aug 31, 2017 at 3:05 PM, Andrea Giammarchi
 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 
> wrote:
>>
>> What about this (using the stage 3 class fields proposal)?
>>
>> ```js
>> declare function lazy(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
>>  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
>> >  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 
>> >> wrote:
>> >>>
>> >>> It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
>> >>> .NET's `System.Lazy`, 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(1)
>> >>> // 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
>> >>> 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
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 
wrote:

> What about this (using the stage 3 class fields proposal)?
>
> ```js
> declare function lazy(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
>  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
> >  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 
> >> wrote:
> >>>
> >>> It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
> >>> .NET's `System.Lazy`, 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(1)
> >>> // 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
> >>>  wrote:
> >>> > right ... so ... I'm not sure I understand what this proposal 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
> 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 
> wrote:
>
>> It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
>> .NET's `System.Lazy`, 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(1)
>> // 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-init
>> ialization-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
>>  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 
>> > 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
>> >>  wrote:
>> >> >> using it in a descriptor would get it passed the wrong `this`
>> >> >
>> >> > sorry, what?
>> >> >
>> >> > ```js
>> >> > var a = {};
>> >> > var b = {get() { 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
> 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 
wrote:

> It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
> .NET's `System.Lazy`, 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(1)
> // 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
>  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 
> > 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
> >>  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
> 

Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
It'd solve a problem similarly to Kotlin's `by lazy { ... }` delegate,
.NET's `System.Lazy`, 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(1)
// 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
 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 
> 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
>>  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 
>> > 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
>> >>  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
>> >> > 

Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
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 
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
>  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 
> > 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
> >>  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/4c0723bdfa555a1c2cb01341b323c3
> d4
> >> >>
> >> >> As for what would be a nice API, maybe something like one of these?
> >> >>
> >> >> ```js
> >> >> class Lazy {
> >> >> constructor(init: () => T);
> >> >> get(): T; // or error thrown
> >> >> }
> >> >>
> >> >> function lazy(init: () => T): () => T; // or error thrown
> >> >>
> >> >> function lazy(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


Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
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
 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 
> 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
>>  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 
>> > 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 {
>> >> constructor(init: () => T);
>> >> get(): T; // or error thrown
>> >> }
>> >>
>> >> function lazy(init: () => T): () => T; // or error thrown
>> >>
>> >> function lazy(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


Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
Promises are inherently eager, but also async - consider that `new
Promise(resolve => resolve(1))` is roughly equivalent to `var promise
= Promise.resolve(1)`.

My proposal is for a single immediate value, but created on demand
(when you call `.get()`) rather than immediately.
-

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 10:37 AM, Naveen Chawla  wrote:
> Could you not do this with a promise? If not, what's missing in promise that
> you could do with "lazy"? Sorry if I've missed the whole premise
>
> On Thu, 31 Aug 2017 at 19:09 Andrea Giammarchi 
> 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 
>> 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 {
>>> constructor(init: () => T);
>>> get(): T; // or error thrown
>>> }
>>>
>>> function lazy(init: () => T): () => T; // or error thrown
>>>
>>> function lazy(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
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
> 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 
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
>  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 
> > 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 {
> >> constructor(init: () => T);
> >> get(): T; // or error thrown
> >> }
> >>
> >> function lazy(init: () => T): () => T; // or error thrown
> >>
> >> function lazy(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


Re: Lazy evaluation

2017-08-31 Thread Isiah Meadows
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
 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 
> 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 {
>> constructor(init: () => T);
>> get(): T; // or error thrown
>> }
>>
>> function lazy(init: () => T): () => T; // or error thrown
>>
>> function lazy(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


Re: Lazy evaluation

2017-08-31 Thread Naveen Chawla
Could you not do this with a promise? If not, what's missing in promise
that you could do with "lazy"? Sorry if I've missed the whole premise

On Thu, 31 Aug 2017 at 19:09 Andrea Giammarchi 
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 
> 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 {
>> constructor(init: () => T);
>> get(): T; // or error thrown
>> }
>>
>> function lazy(init: () => T): () => T; // or error thrown
>>
>> function lazy(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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Lazy evaluation

2017-08-31 Thread Andrea Giammarchi
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 
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 {
> constructor(init: () => T);
> get(): T; // or error thrown
> }
>
> function lazy(init: () => T): () => T; // or error thrown
>
> function lazy(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


Lazy evaluation

2017-08-31 Thread Isiah Meadows
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 {
constructor(init: () => T);
get(): T; // or error thrown
}

function lazy(init: () => T): () => T; // or error thrown

function lazy(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