Re: operator overloading proposal

2016-05-09 Thread Kevin Barabash
> And remember that decorators are essentially just a syntax to apply
functions to objects/classes at design time, so what you're proposing is
essentially some new global function, which is going against the current
trend and effort to better modularize/namespace all these utility
functions/methods.

That's a really good point.

> It has been mentioned and discussed in numerous places over the years,
you can find more info on this with some casual googling. For example:
https://news.ycombinator.com/item?id=2983420

Thanks for the link.  I played around with sweet.js a bit over the
weekend.  Using macros should work if we went with Python style operator
overloading.  Instead of defining methods like _ADD_, _SUB_ etc. we could
create some well-known symbols, maybe Symbol.plus, Symbol.times, etc.

```
class Point {
  constructor(x, y) {
Object.assign(this, {x, y});
  }

  [Symbol.add](other) {
return new Point(this.x + other.x, this.y + other.y);
  }
}

const u = new Point(5, 10);
const v = new Point(1, -2);

const w = u + v;  // desugars to u[Symbol.add](v)
console.log(w);   // { x: 6, y: 8 };
```

This would require default implementations to be defined on
Object.prototype for Symbol.plus, Symbol.times, etc.


On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee <
balancetraveller+es-disc...@gmail.com> wrote:

> > Why not? The standard defines well-known symbols. Maybe `@operator`
> could be a well known decorator (assuming decorators get approved).
>
> Well... you make something into the standard with proposals, not why-nots,
> so in order to make that happen you need to draft another proposal for
> well-known decorators. And remember that decorators are essentially just a
> syntax to apply functions to objects/classes at design time, so what you're
> proposing is essentially some new global function, which is going against
> the current trend and effort to better modularize/namespace all these
> utility functions/methods. And maybe a new mechanism could be drafted for
> these new well-known decorators, so that we can hide these new functions
> somewhere... but by now I hope it's becoming clear that it's introducing
> way too much new surface area for the language in exchange for one small
> feature.
>
> > I haven't seen any proposals for macros, could you post a link?
>
> It has been mentioned and discussed in numerous places over the years, you
> can find more info on this with some casual googling. For example:
> https://news.ycombinator.com/item?id=2983420
>
>
>
> On Sun, May 8, 2016 at 2:51 PM, Kevin Barabash 
> wrote:
>
>> I should update the demo code to show the `@operator` decorator in
>> addition to `Function.defineOperator`.
>>
>> Initially I started out with just the `@operator` decorator, but that
>> meant that each class would have to have knowledge of each of the classes
>> it might want to interact with before hand.  Having a separate
>> `defineOperator` function avoids this situation.
>>
>> It means that prototype style classes must be converted to the new class
>> syntax before operator overloading could be used.  Lastly, there may be
>> some cases where it makes sense to overload operators with existing 3rd
>> party code or built-in classes, e.g. adding set operations to Set using
>> operator overloading.
>>
>> > It's also apparent that the `@operator decorator` part of the proposal
>> is an effort trying to address this issue, but it really is not the
>> responsibility of the standard to try to define such a thing.
>>
>> Why not?  The standard defines well-known symbols.  Maybe `@operator`
>> could be a well known decorator (assuming decorators get approved).
>>
>> Slide 15 from http://www.slideshare.net/BrendanEich/js-resp shows syntax
>> for defining operators in value types which could be adapted as follows for
>> regular classes:
>>
>> ```
>> class Point {
>>constructor(x, y) {
>>this.x = +x;
>>this.y = +y;
>>}
>>Point + Number (a, b) {
>>return new Point(a.x + b, a.y + b);
>>}
>>Number + Point (a, b) {
>>return new Point(a + b.x, a + b.y);
>>}
>>Point + Point (a, b) {
>>return new Point(a.x + b.x, a.y + b.y);
>>}
>> }
>> ```
>>
>> Having to define `+` twice for `Point + Number` and `Number + Point`
>> seems like busy work, but maybe it's better to be explicit.  What are you
>> thoughts about this syntax?
>>
>> > Another thing is that, IMHO, currently there are too much
>> quirks/conventions in the proposal that feel non-evident and non-flexible
>> which is destined to trip people over from time to time. It would be great
>> to make a proposal that's simple and don't include too much assumptions.
>>
>> Could you elaborator what quirks/conventions might trip people up?
>>
>> > Finally, I'm not sure about the current status of macros, but last I
>> heard of it, they say it's going to make its way into the standard pretty
>> soon (TM), and macros can do much of the things overloading could, 

Proposing a conditional assignment (or equals) operator

2016-05-09 Thread Doug Wade
I see this has been discussed on this list a number of times before -- I
found this thread
, and
reviewed the linked discussions and previous strawmen (I hope that link is
enough to establish context and why the operator is useful; I can provide
more insight if it would be helpful).  I understand the problem is fraught
and thorny, but I believe the language would greatly benefit from it.

I spent some time reflecting on what I think would be expected of such an
operator (most notably that it be as close to the other assignment
operators +=, -=  and the || operator as I could manage, and that it
match the ||= operator in Ruby

fairly
closely) and wrote up a quick reference implementation (-ish? see babylon
(parser) 
 and babel (compiler)
)
and an set of test cases
 to match what I
think expresses my thoughts on what I personally would expect from such an
operator more eloquently than I think I could in words (please don't think
me presumptuous; I thought it easier to write out my thoughts in code than
English, not that the debate would be so simple that my implementation
would be rubber stamped).

I have reviewed the process documentation
 and the contributing guide
, and I
believe I am seeking a TC39 champion to make this a stage 0 strawman
proposal, though I will admit that from my review of the archives
 there is likely to be a lot of discussion before
we reach that point.  Please advise me as to what more I can do to get this
included in the ES standard.

All the best,
Doug Wade
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Is `undefined` garabage collectable?

2016-05-09 Thread Isiah Meadows
I'll just point this out: low level optimization like that is very
unintuitive.

Game engines often use object pools to avoid allocation and GC, since even
a single `malloc` is sometimes too expensive. There's other ways of
reducing GC as well, such as persistence (like persistent data structures -
object pooling is a similar concept), changing your algorithm to work in
place, changing your algorithm to have fewer memory requirements, or even
explicit marking of an object to be collected for GC while it's young
(engines already often do some of their own pooling of frequently created
objects).

As for language help, you're on your own, because there's little the
language can help you with, regardless of what's added.

On Mon, May 9, 2016, 14:07 /#!/JoePea  wrote:

> Thanks Andreas, that's helpful to know. In general, is there some way to
> keep a list (adding removing things over time) while avoiding GC?
>
> For example, I thought I could place and remove items into a list (f.e.
> Set or Map, while having my own references to all the items and the list
> and outside of the list as well as to the list itself), but as you pointed
> out that still can have need for GC.
>
> I know you said
>
> > In general, there is very little you can do in JavaScript that does not
> potentially cause allocation and thus GC
>
> But, I would at least want to know that I minimized GC as much as
> possible. My first hunch (for my case) would be to make a linked list out
> of the items I need to have a "list" of, where each item's link (reference)
> to the next item is also one of the references that I already hold outside
> of the list?
>
> It seems that with Arrays (and Sets and Maps) that deleting an item from
> the list also deletes the placeholder that was used for that item (in the
> case of Array, the placeholders would be the numerical keys that are
> deleted when an item is popped for example), and I'm guessing (with my
> still expanding VM knowledge) that those placeholders are GCed separately
> from the thing that was referenced to by the placeholder (so even if the
> placeholder contained `null` there would still be GC). Is that a good guess?
>
> I'll be experimenting...
>
> On Mon, May 9, 2016 at 2:28 AM, Andreas Rossberg 
> wrote:
>
>> The `undefined` value is represented in exactly the same way as `true`,
>> `false`, and `null` in V8. They're so called "oddballs" internally, global
>> values that are neither allocated nor freed.
>>
>> Either way, the key/values of a (regular) map do not keep anything alive
>> about the map. Adding or removing entries from a set or map can of course
>> cause allocation/deallocation, regardless of the keys/values themselves.
>> (Similarly if you are using regular objects as maps, btw.)
>>
>> There are also lots of other things that cause allocation/deallocation
>> under the hood of a JavaScript engine, e.g. compilation, optimisation,
>> deoptimisation, etc. Some of that predominantly happens at start-up. If you
>> want to reduce random noise from your experiments, try to warm up the code
>> first. But even then, don't read too much into micro-benchmarks -- JS VMs
>> are far too complicated, dynamic, and heuristics-based to draw useful
>> conclusions from tiny tests (that's e.g. why JSPerf tests are often
>> bollocks).
>>
>> In general, there is very little you can do in JavaScript that does not
>> potentially cause allocation and thus GC. Certainly nothing involving
>> dynamic data structures.
>>
>> /Andreas
>>
>>
>> On 5 May 2016 at 07:48, /#!/JoePea  wrote:
>>
>>> > The only v8 shell I have lying around is too old (3.14.5.10) to have
>>> Set, so I can't tell you what it would do.
>>>
>>> On my first attempt, I noticed 8 Major GCs:
>>> https://cloud.githubusercontent.com/assets/297678/15036715/f41ea4d4-1247-11e6-8823-f153c3c1b7bb.png
>>>
>>> On second attempt, no Major GCs:
>>> https://cloud.githubusercontent.com/assets/297678/15036788/c066483a-1248-11e6-970b-3f9d20710bbc.png
>>>
>>> I wonder why. I'm in Chrome 50.
>>>
>>> So, the second attempt looks good. I'm not sure why the first is so
>>> different. I tried it a few times, but I only got that Major GC zig-zag the
>>> first time.
>>>
>>> Thanks for pointing out Set!
>>>
>>> On Wed, May 4, 2016 at 7:30 PM, Boris Zbarsky  wrote:
>>>
 On 5/4/16 5:03 PM, Steve Fink wrote:

> The only v8 shell I have lying around is too old (3.14.5.10) to have
> Set, so I can't tell you what it would do.
>

 I have v8 "4.8.0 (candidate)" (meaning whatever rev I checked out), and
 it does 1163 minor ("Scavenge") GCs on your testcase.  It also does 1163
 minor GCs if I take out the add() calls.  It does none if I remove the
 clear() calls, no matter whether the add() calls are there or not.

 -Boris
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 

Re: Promise based Observable proposal

2016-05-09 Thread Isiah Meadows
Probably best to first see how people react here:
https://github.com/zenparsing/es-observable

You also might appreciate the async generator/iterator proposal here:
https://github.com/tc39/proposal-async-iteration

(Note: observables push directly to iterators and are event based, while
async iterators are effectively iterators of promises, and they are
functionally equivalent, but they are two different ways of looking at the
same problem. Observables are better with single events, while async
iterators are like normal iterators. They are both heavily promise-based.)

On Mon, May 9, 2016, 03:48 Yad Smood  wrote:

> Hi everyone,
>
> I've been working on implementing a Promise based Observable proposal.
>
> The main goal is to make the Observable composable, every subscribe will
> return a new Observable, and every listener will try to resolve the
> returned value as a Promise. Promise can't resolve multiple times, this
> class makes it possible, so that you can easily map, filter and even back
> pressure events in a promise way.
>
> For live example: Double Click Demo
> .
>
> The implementation is here:
> https://github.com/ysmood/yaku#observableexecutor
>
> Code example:
>
> ```js
> var Observable = require("yaku/lib/Observable");
> var linear = new Observable();
>
> var x = 0;
> setInterval(linear.next, 1000, x++);
>
> // Wait for 2 sec then emit the next value.
> var quad = linear.subscribe(async x => {
> await sleep(2000);
> return x * x;
> });
>
> var another = linear.subscribe(x => -x);
>
> quad.subscribe(
> value => { console.log(value); },
> reason => { console.error(reason); }
> );
>
> // Emit error
> linear.error(new Error("reason"));
>
> // Unsubscribe an observable.
> quad.unsubscribe();
>
> // Unsubscribe all subscribers.
> linear.subscribers = [];
> ```
>
> The lib itself is on a very early stage, please leave a comment if you
> have any idea on 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: Better way to maintain this reference on event listener functions

2016-05-09 Thread Bob Myers
You don't need to rewrite such utilities for every class by any means.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Is `undefined` garabage collectable?

2016-05-09 Thread /#!/JoePea
Thanks Andreas, that's helpful to know. In general, is there some way to
keep a list (adding removing things over time) while avoiding GC?

For example, I thought I could place and remove items into a list (f.e. Set
or Map, while having my own references to all the items and the list and
outside of the list as well as to the list itself), but as you pointed out
that still can have need for GC.

I know you said

> In general, there is very little you can do in JavaScript that does not
potentially cause allocation and thus GC

But, I would at least want to know that I minimized GC as much as possible.
My first hunch (for my case) would be to make a linked list out of the
items I need to have a "list" of, where each item's link (reference) to the
next item is also one of the references that I already hold outside of the
list?

It seems that with Arrays (and Sets and Maps) that deleting an item from
the list also deletes the placeholder that was used for that item (in the
case of Array, the placeholders would be the numerical keys that are
deleted when an item is popped for example), and I'm guessing (with my
still expanding VM knowledge) that those placeholders are GCed separately
from the thing that was referenced to by the placeholder (so even if the
placeholder contained `null` there would still be GC). Is that a good guess?

I'll be experimenting...

On Mon, May 9, 2016 at 2:28 AM, Andreas Rossberg 
wrote:

> The `undefined` value is represented in exactly the same way as `true`,
> `false`, and `null` in V8. They're so called "oddballs" internally, global
> values that are neither allocated nor freed.
>
> Either way, the key/values of a (regular) map do not keep anything alive
> about the map. Adding or removing entries from a set or map can of course
> cause allocation/deallocation, regardless of the keys/values themselves.
> (Similarly if you are using regular objects as maps, btw.)
>
> There are also lots of other things that cause allocation/deallocation
> under the hood of a JavaScript engine, e.g. compilation, optimisation,
> deoptimisation, etc. Some of that predominantly happens at start-up. If you
> want to reduce random noise from your experiments, try to warm up the code
> first. But even then, don't read too much into micro-benchmarks -- JS VMs
> are far too complicated, dynamic, and heuristics-based to draw useful
> conclusions from tiny tests (that's e.g. why JSPerf tests are often
> bollocks).
>
> In general, there is very little you can do in JavaScript that does not
> potentially cause allocation and thus GC. Certainly nothing involving
> dynamic data structures.
>
> /Andreas
>
>
> On 5 May 2016 at 07:48, /#!/JoePea  wrote:
>
>> > The only v8 shell I have lying around is too old (3.14.5.10) to have
>> Set, so I can't tell you what it would do.
>>
>> On my first attempt, I noticed 8 Major GCs:
>> https://cloud.githubusercontent.com/assets/297678/15036715/f41ea4d4-1247-11e6-8823-f153c3c1b7bb.png
>>
>> On second attempt, no Major GCs:
>> https://cloud.githubusercontent.com/assets/297678/15036788/c066483a-1248-11e6-970b-3f9d20710bbc.png
>>
>> I wonder why. I'm in Chrome 50.
>>
>> So, the second attempt looks good. I'm not sure why the first is so
>> different. I tried it a few times, but I only got that Major GC zig-zag the
>> first time.
>>
>> Thanks for pointing out Set!
>>
>> On Wed, May 4, 2016 at 7:30 PM, Boris Zbarsky  wrote:
>>
>>> On 5/4/16 5:03 PM, Steve Fink wrote:
>>>
 The only v8 shell I have lying around is too old (3.14.5.10) to have
 Set, so I can't tell you what it would do.

>>>
>>> I have v8 "4.8.0 (candidate)" (meaning whatever rev I checked out), and
>>> it does 1163 minor ("Scavenge") GCs on your testcase.  It also does 1163
>>> minor GCs if I take out the add() calls.  It does none if I remove the
>>> clear() calls, no matter whether the add() calls are there or not.
>>>
>>> -Boris
>>> ___
>>> 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: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
I do still feel your examples are still storing a reference to the intended
handler function and having this sort of glue is unnecessary to have to
write for every class that is created. It would be nice if this would
handled by the language automatically.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Oh yeah my apologies, handler is a variable that gets passed to
removeEventListener when invoked.
-- 

mark

Sent while riding a hoverboard...
heyimmark.com :)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Bob Myers
Yes, you are missing something. This code will absolutely remove it the
handler, because the handler being passed to both `addEventListener` and
`removeEventListener is identical (in the `===` sense).

On Mon, May 9, 2016 at 10:50 PM, Mark Kennedy  wrote:

> Thanks, Bob. Unless I'm missing something, this code you wrote will not
> remove the event listener when `unlisten` is called. Check out [this
> answer](http://stackoverflow.com/a/30448329/2810742) on stackoverflow.
>
> ```js
> function listen(element, type, handler) {
>   element.addEventListener(type, handler);
>   return function() {
> element.removeEventListener(type, handler);
>   };
> }
>
> var unlisten = listen(myElement, 'click', e => this.handler(e));
>
> unlisten();
> ```
> --
>
> mark
>
> Sent while riding a hoverboard...
> heyimmark.com :)
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Thanks, Bob. Unless I'm missing something, this code you wrote will not
remove the event listener when `unlisten` is called. Check out [this
answer](http://stackoverflow.com/a/30448329/2810742) on stackoverflow.

```js
function listen(element, type, handler) {
  element.addEventListener(type, handler);
  return function() {
element.removeEventListener(type, handler);
  };
}

var unlisten = listen(myElement, 'click', e => this.handler(e));

unlisten();
```
-- 

mark

Sent while riding a hoverboard...
heyimmark.com :)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Bob Myers
I'm confused by this whole thread. There is nothing here that cannot be
handled easily by a minimal amount of user glue code, to give just one
example:

```js
function listen(element, type, handler) {
  element.addEventListener(type, handler);
  return function() {
element.removeEventListener(type, handler);
  };
}

var unlisten = listen(myElement, 'click', e => this.handler(e));
unlisten();
```

To remove after one call:

```js
function listenOnce(element, type, handler) {
  function _handler(e) {
handler(e);
element.removeEventListener(type, _handler);
  }
  element.addEventListener(type, _handler);
}
```

If you want to more easily use the same handler on multiple elements:

```
function makeHandler(type, handler) {
  return {
listen(elt) { elt.addEventListener(type, handler) },
unlisten(elt) { elt.removeEventListener(type, handler); }
  };
}

var handler = makeHandler('click', e => handleIt(e));
handler.listen(elt);
handler.unlisten(elt);
```

There are other useful possibilities opened up by using the `EventListener`
interface. None of this requires any change to `addEventListener` signature
as far as I can tell.

And so on.

Bob

On Mon, May 9, 2016 at 10:26 PM, Mark Kennedy  wrote:

> Haha, no problem, Andrea. I think I may have not explained the scenario as
> clearly in my original post so I apologize for that. But like Boris
> mentioned, removing the event listeners in a much easier way is also a part
> of my goal here.
>
> I do like passing context in an argument and if using the third argument
> is a possibility, that would be nice. I would vote for:
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Haha, no problem, Andrea. I think I may have not explained the scenario as
clearly in my original post so I apologize for that. But like Boris
mentioned, removing the event listeners in a much easier way is also a part
of my goal here.

I do like passing context in an argument and if using the third argument is
a possibility, that would be nice. I would vote for:

```js
el.addEventListener('click', this.onClick, {context: this});
```

which would decrease the amount of code necessary imo.
-- 

mark

Sent while riding a hoverboard...
heyimmark.com :)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Andrea Giammarchi
Oh well, if removing after first click is the use-case,
`el.addEventListener('click',
this.onClick, {once: true})` is already in the standard pipeline (and
polyfilled in dom4)

Best Regards

On Mon, May 9, 2016 at 5:41 PM, Boris Zbarsky  wrote:

> On 5/9/16 12:37 PM, Mark Kennedy wrote:
>
>> and also REMOVING the event listeners manually.
>>
>
> I think this is the key part.  What is the precise use case for removing
> here?  I think that affects how this would best be designed.
>
> The obvious case is when you want to remove the listener at the point when
> it fires.  This would be most easily addressed by providing a way to get at
> the listener from inside itself somehow.  Are there other uses?
>
> -Boris
>
> ___
> 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: Better way to maintain this reference on event listener functions

2016-05-09 Thread Boris Zbarsky

On 5/9/16 12:37 PM, Mark Kennedy wrote:

and also REMOVING the event listeners manually.


I think this is the key part.  What is the precise use case for removing 
here?  I think that affects how this would best be designed.


The obvious case is when you want to remove the listener at the point 
when it fires.  This would be most easily addressed by providing a way 
to get at the listener from inside itself somehow.  Are there other uses?


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


Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Sorry maybe I'm not explaining this the right way. My original intent is to
lessen the code that I would have to write to achieve multiple event
handlers which do different things on multiple DOM elements when
constructing a class and also REMOVING the event listeners manually. I am
assuming this is a scenario where the DOM elements are outliving their
event listeners (for single page web applications for instance) so they
must be removed manually. Let's say I have five buttons on a page and I
want them all to do something different when they are clicked.

```html
button 1
button 2
button 3
```

With your approach, I would have to do this, right?

```js
class SomeClass {
  constructor() {
let button1 = document.getElementById('button1');
button1.addEventListener('click', this);
let button2 = document.getElementById('button2');
button2.addEventListener('click', this);
let button3 = document.getElementById('button3');
button3.addEventListener('mouseover', this);
  },

  onclick(e) {
   // if e.target is button1,
  // show modal
   // if e.target is button2,
  // navigate backwards
   // i f e.target is button 3,
  // do something else
  },

onmouseover (e) {
  // if e.target is button 3
  // do something else different from the above
}

  handleEvent(e) {
this['on' + e.type](e);
}
```
It may just be me confused here, but the above code is much more
overwhelming and much less intuitive than the solutions I've proposed above.

Hopefully this helps clarify a few things.


On Mon, May 9, 2016 at 12:20 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Hi Mark, not sure I understand. What you are doing is exactly the same,
> there is no difference whatsoever with what I've shown to you.
>
> > Yes but what happens when you have multiple event targets using the
> same `type` of event? You're going to require a lot of extra conditionals
> in `onclick` method. Again this approach is cumbersome and, imo, not the
> most efficient.
>
> conditionals what? the onclick is called only when the node where you
> attached the listener as instance gets invoked. It never triggers in any
> other cases.
> Or better, it is exactly the same as `someNode.addEventListener('click',
> (e) => this.onClick(e))` ... really, PRECISELY the same.
>
> Whenever your `click` gets triggered, the `handleEvent` would behave
> **exactly** the same. Not sure I've stressed the *exactly* part enough so
> nothing is cumbersome, maybe you don't understand or you've never used this
> approach before.
>
> Otherwise, please show me a single example where adding a listener as
> callback, or bound callback, would be triggered differently from adding an
> instance with an inherited, or own, handleEvent.
>
> Going on ...
>
> > 1. When an arrow function is used as the second parameter to
> `addEventListener`, the language can evaluate and use its scoped context
>  ...
>
> This is not going to happen. It's an exception to the arrow that would
> confuse even more about its context.
>
> > 2. Another solution would be if we could maybe pass a method string as
> the second parameter and then an optional context as the fourth parameter
> ...
>
> This is DOM land, since it's about `addEventListener` signature, and I
> would personally vote -1 to that variant.
>
>
> You should really try to understand how `handleEvent` works, IMO. It's the
> sugar you're looking for already since it makes you set any listener you
> want *without* needing to store upfront the bound method: fast, clean,
> simple.
>
> To remove a listener at any time, you don't need to store upfront a bound
> version of the method.
>
> Best Regards
>
>
>
>
> On Mon, May 9, 2016 at 5:05 PM, Mark Kennedy  wrote:
>
>> Yes but what happens when you have multiple event targets using the same
>> `type` of event? You're going to require a lot of extra conditionals in
>> `onclick` method. Again this approach is cumbersome and, imo, not the most
>> efficient.
>>
>> These may not be the best solutions but here are a few options I've
>> thought of:
>>
>> 1. When an arrow function is used as the second parameter to
>> `addEventListener`, the language can evaluate and use its scoped context
>> when the same function is used with a subsequent `removeEventListener call,
>> so essentially the following code would work when calling destroy.
>>
>>
>> ```js
>> class MyClass {
>> constructor () {
>> someNode.addEventListener('click', (e) => this.onClick(e))
>> }
>>
>> onClick (e) {
>> // do something here
>> }
>>
>> destroy () {
>> someNode.removeEventListener('click', (e) => this.onClick(e))
>> }
>> }
>>
>> ```
>>
>> 2. Another solution would be if we could maybe pass a method string as
>> the second parameter and then an optional context as the fourth parameter
>> to addEventListener and removeEventListener as follows:
>>
>>
>> ```js
>> class MyClass {
>> constructor () {
>> someNode.addEventListener('click', 'onClick', 

Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Andrea Giammarchi
Hi Mark, not sure I understand. What you are doing is exactly the same,
there is no difference whatsoever with what I've shown to you.

> Yes but what happens when you have multiple event targets using the same
`type` of event? You're going to require a lot of extra conditionals in
`onclick` method. Again this approach is cumbersome and, imo, not the most
efficient.

conditionals what? the onclick is called only when the node where you
attached the listener as instance gets invoked. It never triggers in any
other cases.
Or better, it is exactly the same as `someNode.addEventListener('click',
(e) => this.onClick(e))` ... really, PRECISELY the same.

Whenever your `click` gets triggered, the `handleEvent` would behave
**exactly** the same. Not sure I've stressed the *exactly* part enough so
nothing is cumbersome, maybe you don't understand or you've never used this
approach before.

Otherwise, please show me a single example where adding a listener as
callback, or bound callback, would be triggered differently from adding an
instance with an inherited, or own, handleEvent.

Going on ...

> 1. When an arrow function is used as the second parameter to
`addEventListener`, the language can evaluate and use its scoped context ...

This is not going to happen. It's an exception to the arrow that would
confuse even more about its context.

> 2. Another solution would be if we could maybe pass a method string as
the second parameter and then an optional context as the fourth parameter
...

This is DOM land, since it's about `addEventListener` signature, and I
would personally vote -1 to that variant.


You should really try to understand how `handleEvent` works, IMO. It's the
sugar you're looking for already since it makes you set any listener you
want *without* needing to store upfront the bound method: fast, clean,
simple.

To remove a listener at any time, you don't need to store upfront a bound
version of the method.

Best Regards




On Mon, May 9, 2016 at 5:05 PM, Mark Kennedy  wrote:

> Yes but what happens when you have multiple event targets using the same
> `type` of event? You're going to require a lot of extra conditionals in
> `onclick` method. Again this approach is cumbersome and, imo, not the most
> efficient.
>
> These may not be the best solutions but here are a few options I've
> thought of:
>
> 1. When an arrow function is used as the second parameter to
> `addEventListener`, the language can evaluate and use its scoped context
> when the same function is used with a subsequent `removeEventListener call,
> so essentially the following code would work when calling destroy.
>
>
> ```js
> class MyClass {
> constructor () {
> someNode.addEventListener('click', (e) => this.onClick(e))
> }
>
> onClick (e) {
> // do something here
> }
>
> destroy () {
> someNode.removeEventListener('click', (e) => this.onClick(e))
> }
> }
>
> ```
>
> 2. Another solution would be if we could maybe pass a method string as the
> second parameter and then an optional context as the fourth parameter to
> addEventListener and removeEventListener as follows:
>
>
> ```js
> class MyClass {
> constructor () {
> someNode.addEventListener('click', 'onClick', {}, this)
> }
>
> onClick (e) {
> // do something here
> }
>
> destroy () {
> someNode.removeEventListener('click', 'onClick', {}, this)
> }
> }
>
> ```
>
>
> On Mon, May 9, 2016 at 9:52 AM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> uhm, I've used commas ... anyway, the sugar is desugaring to old methods,
>> this is working example:
>>
>> ```js
>> class SomeClass {
>>   constructor(someNode) {
>> someNode.addEventListener('click', this);
>>   }
>>   onclick(e) {
>> alert(this.constructor.name); // SomeClass
>>   }
>>   handleEvent(e) {
>> this['on' + e.type](e);
>>   }
>> }
>>
>> new SomeClass(document.documentElement);
>> ```
>>
>> The difference with your example is that you will always be able to
>> remove the instance without needing to store upfront every bound listener.
>>
>> To know where the `addEventListener` was set you always have the
>> `e.currentTarget` so basically you have a weakmap between a node and an
>> object where you can always retrieve the initial node that used the object
>> through the event, keeping the node clean from "expando" links.
>>
>> More sugar than this, I'm not sure what would be.
>>
>> You could also have a simple naming convention where every method that
>> starts with `on` will be set as listener using the current instance, and do
>> the same, if necessary, on teardown/destroy.
>>
>> What kind of sugar would you use otherwise?
>>
>> The only proposal discussed so far is `el.addEventListener('click', ::
>> this.onClick)`, unfortunately that doesn't solve anything because AFAIK
>> they don't see any advantage in having `::this.onClick === ::this.onClick`
>> which is what I've raised already as "that's what developers would expect"
>> but apparently it's too costy or complicated or ... 

RE: Subject=Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Domenic Denicola
To give some clarity to "whose concern is it", the idea of it being an ES 
concern is that this is a concern for all APIs that accept a callback. 
addEventListener is a simple example.

I think ES has already given an answer to this question: 
`Function.prototype.bind`. I'm not sure what the OP was hoping to accomplish 
that could not already be accomplished with bind. Any possible mechanism (e.g. 
syntactic sugar for a (thisArg, function) pair) would essentially duplicate 
what bind does under the hood.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Andrea Giammarchi
uhm, I've used commas ... anyway, the sugar is desugaring to old methods,
this is working example:

```js
class SomeClass {
  constructor(someNode) {
someNode.addEventListener('click', this);
  }
  onclick(e) {
alert(this.constructor.name); // SomeClass
  }
  handleEvent(e) {
this['on' + e.type](e);
  }
}

new SomeClass(document.documentElement);
```

The difference with your example is that you will always be able to remove
the instance without needing to store upfront every bound listener.

To know where the `addEventListener` was set you always have the
`e.currentTarget` so basically you have a weakmap between a node and an
object where you can always retrieve the initial node that used the object
through the event, keeping the node clean from "expando" links.

More sugar than this, I'm not sure what would be.

You could also have a simple naming convention where every method that
starts with `on` will be set as listener using the current instance, and do
the same, if necessary, on teardown/destroy.

What kind of sugar would you use otherwise?

The only proposal discussed so far is `el.addEventListener('click', ::
this.onClick)`, unfortunately that doesn't solve anything because AFAIK
they don't see any advantage in having `::this.onClick === ::this.onClick`
which is what I've raised already as "that's what developers would expect"
but apparently it's too costy or complicated or ... dunno.

¯\_(ツ)_/¯

Best Regards










On Mon, May 9, 2016 at 2:41 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Raising a concern about `addEventListener` and its context probably made
> me think it was rather a WHATWG concern.
>
> Anyway, I don't know why you had to point out the `class` keyword ... I
> mean 
>
> ```js
> class SomeClass {
>   constructor(someNode) {
> someNode.addEventListener('click', this);
>   },
>   onclick(e) {
> alert(this.constructor.name); // SomeClass
>   },
>   handleEvent(e) {
> this['on' + e.type](e);
>   }
> }
> ```
>
> There you go
>
> Best Regards
>
>
> On Mon, May 9, 2016 at 2:38 PM, Mark Kennedy  wrote:
>
>> Wow that's so ironic because [I posted this same idea](
>> https://github.com/whatwg/dom/issues/245#issuecomment-217816301)
>> (literally
>> copied and pasted) in WHATWG's "DOM land" and they told me this was an
>> es-discuss issue. So which is it?
>> Oh and thanks for the code sample but it uses the old prototypical method
>> of replicating a class by creating a function which is now not the most
>> efficient way (there's the `class` keyword). And I don't see how what
>> you're doing isn't any different from a roundabout way of what I did. I
>> already know about the `handleEvent()` stuff, I like that it's available
>> and its polyfills. They are great, but my original question is to
>> implement
>> sugar so that you don't have to use polyfills or the `handleEvent()`.
>> --
>>
>> mark
>>
>> Sent while riding a hoverboard...
>> heyimmark.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: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Andrea Giammarchi
Raising a concern about `addEventListener` and its context probably made me
think it was rather a WHATWG concern.

Anyway, I don't know why you had to point out the `class` keyword ... I
mean 

```js
class SomeClass {
  constructor(someNode) {
someNode.addEventListener('click', this);
  },
  onclick(e) {
alert(this.constructor.name); // SomeClass
  },
  handleEvent(e) {
this['on' + e.type](e);
  }
}
```

There you go

Best Regards


On Mon, May 9, 2016 at 2:38 PM, Mark Kennedy  wrote:

> Wow that's so ironic because [I posted this same idea](
> https://github.com/whatwg/dom/issues/245#issuecomment-217816301)
> (literally
> copied and pasted) in WHATWG's "DOM land" and they told me this was an
> es-discuss issue. So which is it?
> Oh and thanks for the code sample but it uses the old prototypical method
> of replicating a class by creating a function which is now not the most
> efficient way (there's the `class` keyword). And I don't see how what
> you're doing isn't any different from a roundabout way of what I did. I
> already know about the `handleEvent()` stuff, I like that it's available
> and its polyfills. They are great, but my original question is to implement
> sugar so that you don't have to use polyfills or the `handleEvent()`.
> --
>
> mark
>
> Sent while riding a hoverboard...
> heyimmark.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: Subject=Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Andrea Giammarchi
Raising a concern about `addEventListener` and its context probably made me
think it was rather a WHATWG concern.

Anyway, I don't know why you had to point out the `class` keyword ... I
mean 

```js
class SomeClass {
  constructor(someNode) {
someNode.addEventListener('click', this);
  },
  onclick(e) {
alert(this.constructor.name); // SomeClass
  },
  handleEvent(e) {
this['on' + e.type](e);
  }
}
```

There you go

Best Regards



On Mon, May 9, 2016 at 2:28 PM, Mark Kennedy  wrote:

> Wow that's so ironic because [I posted this same idea](
> https://github.com/whatwg/dom/issues/245#issuecomment-217816301)
> (literally copied and pasted) in WHATWG's "DOM land" and they told me this
> was an es-discuss issue. So which is it?
> Oh and thanks for the code sample but it uses the old prototypical method
> of replicating a class by creating a function which is now not the most
> efficient way (there's the `class` keyword). And I don't see how what
> you're doing isn't any different from a roundabout way of what I did. I
> already know about the `handleEvent()` stuff, I like that it's available
> and its polyfills. They are great, but my original question is to implement
> sugar so that you don't have to use polyfills or the `handleEvent()`.
>
>
> ___
> 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: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Wow that's so ironic because [I posted this same idea](
https://github.com/whatwg/dom/issues/245#issuecomment-217816301) (literally
copied and pasted) in WHATWG's "DOM land" and they told me this was an
es-discuss issue. So which is it?
Oh and thanks for the code sample but it uses the old prototypical method
of replicating a class by creating a function which is now not the most
efficient way (there's the `class` keyword). And I don't see how what
you're doing isn't any different from a roundabout way of what I did. I
already know about the `handleEvent()` stuff, I like that it's available
and its polyfills. They are great, but my original question is to implement
sugar so that you don't have to use polyfills or the `handleEvent()`.
-- 

mark

Sent while riding a hoverboard...
heyimmark.com :)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Subject=Re: Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Wow that's so ironic because [I posted this same idea](
https://github.com/whatwg/dom/issues/245#issuecomment-217816301) (literally
copied and pasted) in WHATWG's "DOM land" and they told me this was an
es-discuss issue. So which is it?
Oh and thanks for the code sample but it uses the old prototypical method
of replicating a class by creating a function which is now not the most
efficient way (there's the `class` keyword). And I don't see how what
you're doing isn't any different from a roundabout way of what I did. I
already know about the `handleEvent()` stuff, I like that it's available
and its polyfills. They are great, but my original question is to implement
sugar so that you don't have to use polyfills or the `handleEvent()`.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Better way to maintain this reference on event listener functions

2016-05-09 Thread Andrea Giammarchi
This is rather about DOM land, nothing to do with EcmaScript standard.

I'll quickly answer but please bear in mind this mailing list is about ES,
not about WHATWG or W3C, thanks.

Since DOM Level 3 has been available (every browser compatible with
addEventListener, polyfilled for IE8 too if necessary [1] )

```js
// generic handler: any class, any object
function handleEvent(e) {
  this['on' + e.type](e);
};

// as class
function SomeClass(someNode) {
  someNode.addEventListener('click', this);
}
SomeClass.prototype.onclick = function () {
  alert('clicked');
};
SomeClass.prototype.handleEvent = handleEvent;

// as object
document.body.addEventListener('click', {
  name: 'runtime',
  onclick: function () {
alert(this.name);
  },
  handleEvent: handleEvent
});


// as utility [2]
Handler.add('body', {
  name: 'utility',
  click: function () { alert('clicked ' + this.name); }
});
```

The advantage is that not only you don't need to store a reference and
create a bound version of each method,
you can also always remove the listener later on whenever is needed.

```js
// class example
someNode.removeEventListener('click', this);
```

As long as you have a listener able to drop the handler [3]

Best Regards

[1] https://github.com/WebReflection/ie8
[2] https://github.com/WebReflection/dom-handler
[3]
https://www.webreflection.co.uk/blog/2015/10/22/how-to-add-dom-events-listeners#-and-about-that-this-reference-


On Mon, May 9, 2016 at 10:29 AM, Mark Kennedy  wrote:

> Sorry if I've missed any previous requests for this feature, but is there
> any goal to allow callbacks passed to event listeners to keep their `this`
> context without having to store a reference to the this-binded event
> listener first?
>
> I frequently find myself doing this in my class methods:
>
> ```javascript
> this.el = document.createElement('div');
> this.listener = this.onClick.bind(this); // store a reference just to bind
> the `this`
> this.el.addEventListener('click', this.listener)
> ```
>
> only to ensure the correct listener mapping gets removed later on in a
> `destroy`-like function with this code:
>
> ```javascript
> this.el.removeEventListener('click', this.listener);
> ```
>
> A few years ago I would've never thought of a good reason to add such
> sugar, but now that JS is moving forward with class declarations, it seems
> more warranted now.
>
> ___
> 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


Better way to maintain this reference on event listener functions

2016-05-09 Thread Mark Kennedy
Sorry if I've missed any previous requests for this feature, but is there
any goal to allow callbacks passed to event listeners to keep their `this`
context without having to store a reference to the this-binded event
listener first?

I frequently find myself doing this in my class methods:

```javascript
this.el = document.createElement('div');
this.listener = this.onClick.bind(this); // store a reference just to bind
the `this`
this.el.addEventListener('click', this.listener)
```

only to ensure the correct listener mapping gets removed later on in a
`destroy`-like function with this code:

```javascript
this.el.removeEventListener('click', this.listener);
```

A few years ago I would've never thought of a good reason to add such
sugar, but now that JS is moving forward with class declarations, it seems
more warranted now.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Is `undefined` garabage collectable?

2016-05-09 Thread Andreas Rossberg
The `undefined` value is represented in exactly the same way as `true`,
`false`, and `null` in V8. They're so called "oddballs" internally, global
values that are neither allocated nor freed.

Either way, the key/values of a (regular) map do not keep anything alive
about the map. Adding or removing entries from a set or map can of course
cause allocation/deallocation, regardless of the keys/values themselves.
(Similarly if you are using regular objects as maps, btw.)

There are also lots of other things that cause allocation/deallocation
under the hood of a JavaScript engine, e.g. compilation, optimisation,
deoptimisation, etc. Some of that predominantly happens at start-up. If you
want to reduce random noise from your experiments, try to warm up the code
first. But even then, don't read too much into micro-benchmarks -- JS VMs
are far too complicated, dynamic, and heuristics-based to draw useful
conclusions from tiny tests (that's e.g. why JSPerf tests are often
bollocks).

In general, there is very little you can do in JavaScript that does not
potentially cause allocation and thus GC. Certainly nothing involving
dynamic data structures.

/Andreas


On 5 May 2016 at 07:48, /#!/JoePea  wrote:

> > The only v8 shell I have lying around is too old (3.14.5.10) to have
> Set, so I can't tell you what it would do.
>
> On my first attempt, I noticed 8 Major GCs:
> https://cloud.githubusercontent.com/assets/297678/15036715/f41ea4d4-1247-11e6-8823-f153c3c1b7bb.png
>
> On second attempt, no Major GCs:
> https://cloud.githubusercontent.com/assets/297678/15036788/c066483a-1248-11e6-970b-3f9d20710bbc.png
>
> I wonder why. I'm in Chrome 50.
>
> So, the second attempt looks good. I'm not sure why the first is so
> different. I tried it a few times, but I only got that Major GC zig-zag the
> first time.
>
> Thanks for pointing out Set!
>
> On Wed, May 4, 2016 at 7:30 PM, Boris Zbarsky  wrote:
>
>> On 5/4/16 5:03 PM, Steve Fink wrote:
>>
>>> The only v8 shell I have lying around is too old (3.14.5.10) to have
>>> Set, so I can't tell you what it would do.
>>>
>>
>> I have v8 "4.8.0 (candidate)" (meaning whatever rev I checked out), and
>> it does 1163 minor ("Scavenge") GCs on your testcase.  It also does 1163
>> minor GCs if I take out the add() calls.  It does none if I remove the
>> clear() calls, no matter whether the add() calls are there or not.
>>
>> -Boris
>> ___
>> 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


Promise based Observable proposal

2016-05-09 Thread Yad Smood
Hi everyone,

I've been working on implementing a Promise based Observable proposal.

The main goal is to make the Observable composable, every subscribe will
return a new Observable, and every listener will try to resolve the
returned value as a Promise. Promise can't resolve multiple times, this
class makes it possible, so that you can easily map, filter and even back
pressure events in a promise way.

For live example: Double Click Demo
.

The implementation is here:
https://github.com/ysmood/yaku#observableexecutor

Code example:

```js
var Observable = require("yaku/lib/Observable");
var linear = new Observable();

var x = 0;
setInterval(linear.next, 1000, x++);

// Wait for 2 sec then emit the next value.
var quad = linear.subscribe(async x => {
await sleep(2000);
return x * x;
});

var another = linear.subscribe(x => -x);

quad.subscribe(
value => { console.log(value); },
reason => { console.error(reason); }
);

// Emit error
linear.error(new Error("reason"));

// Unsubscribe an observable.
quad.unsubscribe();

// Unsubscribe all subscribers.
linear.subscribers = [];
```

The lib itself is on a very early stage, please leave a comment if you have
any idea on it.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss