Jeremy Martin (2013-07-11T00:12:41.000Z)
Once again, this problem goes beyond simply polluting the prototype (which
is enough of an issue by itself). The semantics for Emitters are somewhat
of an 80/20 thing: 80% of all emitters need some common behavior, but the
remaining 20% is custom.

Going back to Node.js, for instance: everything would be great with
`emitter.on(...)`, `emitter.once(...)`, `emitter.off(...)`,
`emitter.emit(...)`, etc.

But now we need `emitter.listeners(event)`, `emitter.setMaxListeners(n)`,
etc.  So, we still end up with a custom EventEmitter that implements the
additional node-specific stuff, but we have a new problem: how do we
implement `emitter.listeners(event)`? Without an exposed
`emitter._listeners` (or similar) mapping, we're hosed.  So do we
monkey-patch the listener (de)registration methods? Yada yada, you get the
point.

The same problem exists with DOM events and most likely in any other
non-trivial Emitter scenario.  As I see it, it simply isn't practical at
this level.  The pollution issue goes far beyond 4 or 5 or even 10 new
properties/methods if it's going to be robust enough to handle the
already-common use cases, and if anything is missed developers will still
be forced to sub-class it anyway (which is the only hassle that might've
been worth avoiding in the first place).

Alternatively, as Rick said, we could simply have:

class Foo extends Emitter {}
// or
class Foo extends EventEmitter {}
// or
class Foo extends EddyEmitter {}
// etc.

This, IMO, is *far* more favorable and *far* less obtrusive (and already in
the works).

On Wed, Jul 10, 2013 at 7:27 PM, Andrea Giammarchi <
andrea.giammarchi at gmail.com> wrote:

> false.hasOwnProperty('whatever');
> 1.0.isPrototypeOf({whate:'ver'});
> 'string'.propertyIsEnumerable('whatever')
>
> these are already examples of an over-polluted prototype with methods
> nobody uses ... I thought 4 extra methods everyone is using same way except
> for Rick that honorees Tesla in this day would not hurt much but once
> again, my point is that it's really about the time to put some standard
> mechanism to deal with events in ES code.
>
> The fact Object.observe is already accepting a handler with an argument
> which is fired as an event smells to me ... I'd rather define upfront a
> common definition of handlers then propose any extra method based on them
> ;-)
>
> Best Regards
>
>
>
> On Wed, Jul 10, 2013 at 4:04 PM, K. Gadd <kg at luminance.org> wrote:
>
>> I think at this point we have a long history of language designs where
>> random stuff has been tacked onto the core base class (i.e. Object) that
>> really shouldn't have gone there - hashCode/toString in Java/C#, etc - such
>> that any proposal to put something on Object instances deserves extreme
>> skepticism. Static methods on Object aren't nearly so bad.
>>
>> In this case, the problem being solved can almost certainly be solved
>> through composition or some other design mechanism. Bolting it onto every
>> instance of Object, even if the only universally paid cost is a reserved
>> name on the prototype, is simply not the right solution unless the
>> downsides of other approaches are intolerable. Which they aren't.
>>
>> In practice a lot of these use cases call for event subscription and
>> broadcasting to occur through a separate coordinator ('event bus') object
>> and not through the object in question, anyway. This addresses a bunch of
>> reference cycle problems that are caused when you subscribe directly to an
>> object. You don't need to look much further than the DOM for examples...
>>
>>
>> On Wed, Jul 10, 2013 at 3:57 PM, Rick Waldron <waldron.rick at gmail.com>wrote:
>>
>>> I don't want any of this on my Object objects. Not all objects represent
>>> something that can or should emit/publish/trigger/broadcast.
>>>
>>> For example...
>>>
>>> class Light {
>>>   constructor() {
>>>     // initialize Light control instance
>>>   }
>>>   on() {
>>>     // send bits to turn Light on
>>>    }
>>>   off() {
>>>     // send bits to turn Light off
>>>   }
>>> }
>>>
>>>
>>> So what happens now? All of my Led instances have emit, trigger, once
>>> and boundTo methods that are actually useless now. No thanks. I also don't
>>> want Object.prototype.* and Object.* to suffer the same way that the
>>> [[Global]] (window) object in browsers has suffered. Give a hoot, don't
>>> pollute.
>>>
>>> Post ES6 world makes creating emitter objects trivial—so why not a
>>> blessed standard lib module that can be imported and used to extend a class
>>> declaration?
>>>
>>>
>>> import { Emitter } from "@event";
>>>
>>> class Foo extends Emitter {}
>>>
>>> Easy.
>>>
>>> More inline...
>>>
>>>
>>>
>>> On Wed, Jul 10, 2013 at 3:58 PM, Andrea Giammarchi <
>>> andrea.giammarchi at gmail.com> wrote:
>>>
>>>> I know but people use prefixes and unique ids for events too and I am
>>>> not sure if that would work so well.
>>>>
>>>> Also, this is not backward compatible, or better, this is impossible to
>>>> polyfill so it won't bring benefits to the current scenario.
>>>>
>>>> If only I could already `Object.mixin(Object.mixin({}, EventEmitter),
>>>> EventTarget)` and alias those prolix names as `on()` and `off()` it would
>>>> be already great but this is too much in between the DOM, behind WebIDL,
>>>> and ECMAScript ... something I know already historically incompatible,
>>>> that's why I've proposed new names hopefully one day (and hopefully soon)
>>>> in core, something that will be inherited in current implementation in any
>>>> case, as it was in my case simply polluting the `Object.prototype` with
>>>> those non enumerable properties luckily inherited in hosted DOM objects too.
>>>>
>>>> best regards
>>>>
>>>>
>>>> On Wed, Jul 10, 2013 at 12:46 PM, Matthew Robb <matthewwrobb at gmail.com>wrote:
>>>>
>>>>> You can do chainability at object define time with the sugar form:
>>>>>
>>>>> var obj = {
>>>>> on type1(){},
>>>>> on type2(){},
>>>>> on type3(){}
>>>>> }
>>>>>
>>>>
>>> This is the dark days of DOM element properties as event handlers:
>>>
>>>   elem.onclick...
>>>
>>> Assigning to this paves over the previous assignment, leaving no way to
>>> have multiple handlers registered for the same event type.
>>>
>>>
>>>
>>>
>>>>
>>>>> OR add to it using one of the following options:
>>>>>
>>>>> Object.mixin(obj, {
>>>>> on type1(){},
>>>>> on type2(){},
>>>>> on type3(){}
>>>>> })
>>>>>
>>>>> obj.{
>>>>> on type1(){},
>>>>> on type2(){},
>>>>> on type3(){}
>>>>> }
>>>>>
>>>>> obj := {
>>>>> on type1(){},
>>>>> on type2(){},
>>>>> on type3(){}
>>>>> }
>>>>>
>>>>>
>>>>> On Wed, Jul 10, 2013 at 12:41 PM, Andrea Giammarchi <
>>>>> andrea.giammarchi at gmail.com> wrote:
>>>>>
>>>>>> my implementation works already with `DOM` nodes and browser
>>>>>> environment, including `window`.
>>>>>>
>>>>>> I've also already written an `EventTarget` mixin object but in my
>>>>>> case I'd use that via `Object.mixin(Object.prototype, EventTarget);` 'cause
>>>>>> almost every object I use in my logic should be observed or should emit
>>>>>> something to some other object.
>>>>>>
>>>>>
>>> Standard lib approach (a la node) works today and tomorrow.
>>>
>>>
>>>>
>>>>>> Of course Dictionaries are out of the game but that's OK, as long as
>>>>>> it's possible to promote them later on via `Object.setPrototypeOf(dict,
>>>>>> Object.proottype)`
>>>>>>
>>>>>> I find the `Object.addEventListener(obj, "type", handler)` approach
>>>>>> very boring for the simple reason that it does not make sense to use
>>>>>> chainability there, another de-facto thing when it comes to events.
>>>>>>
>>>>>
>>> It's also (subjectively) hideous.
>>>
>>>
>>>
>>>>
>>>>>> ```javascript
>>>>>> // current eddy.js status
>>>>>> var obj = {}
>>>>>>   .on(type1, handler1)
>>>>>>   .on(type2, handler2)
>>>>>>   .on(type3, handler3)
>>>>>> ;
>>>>>> ```
>>>>>>
>>>>>
>>> That's great for your use case, but I would never want this by default.
>>>
>>>
>>> Rick
>>>
>>> (snip)
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
Jeremy Martin
661.312.3853
http://devsmash.com
@jmar777
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130710/2cb29d0d/attachment-0001.html>
domenic at domenicdenicola.com (2013-07-16T14:32:39.062Z)
Once again, this problem goes beyond simply polluting the prototype (which
is enough of an issue by itself). The semantics for Emitters are somewhat
of an 80/20 thing: 80% of all emitters need some common behavior, but the
remaining 20% is custom.

Going back to Node.js, for instance: everything would be great with
`emitter.on(...)`, `emitter.once(...)`, `emitter.off(...)`,
`emitter.emit(...)`, etc.

But now we need `emitter.listeners(event)`, `emitter.setMaxListeners(n)`,
etc.  So, we still end up with a custom EventEmitter that implements the
additional node-specific stuff, but we have a new problem: how do we
implement `emitter.listeners(event)`? Without an exposed
`emitter._listeners` (or similar) mapping, we're hosed.  So do we
monkey-patch the listener (de)registration methods? Yada yada, you get the
point.

The same problem exists with DOM events and most likely in any other
non-trivial Emitter scenario.  As I see it, it simply isn't practical at
this level.  The pollution issue goes far beyond 4 or 5 or even 10 new
properties/methods if it's going to be robust enough to handle the
already-common use cases, and if anything is missed developers will still
be forced to sub-class it anyway (which is the only hassle that might've
been worth avoiding in the first place).

Alternatively, as Rick said, we could simply have:

```js
class Foo extends Emitter {}
// or
class Foo extends EventEmitter {}
// or
class Foo extends EddyEmitter {}
// etc.
```

This, IMO, is *far* more favorable and *far* less obtrusive (and already in
the works).