Re: Object#extra hazard
I didn't suggest that strings as event type would block anyone, strings work fine. I asked for some consideration to be given to also being able to use a unique object as the type key. I gave some reasons, copied below. So in a modern IDE you could click on MY_EVENTS.PERMISSION_UPDATE and it would display the object which could contain the arguments the callback is provided with and a place to document the event. It might also improve minifying/refactoring and searching for occurrences of the event much easier then if it where a simple string. None of which are critical but could be handy when dealing with larger code bases and your event is simply called click. I'm not too wedded to the idea, but I can imagine that if you are building applications with hundreds of packages and modules it might be a safer/easier way to identify instances of your specific event listeners. On Thu, Jul 11, 2013 at 11:04 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: trivial like ... 2 weak maps + a set for a single event ? ```javascript obj.on(evt, handler); ``` .. internals ... ```javascript // wm as private internal generic WeakMap if (!wm.has(obj)) { // creates related WeakMap wm.set(obj, new WeakMap); } if (!wm.get(obj).has(evt)) { wm.get(obj).set(evt, new Set); } wm.get(obj).get(evt).add(handler); ``` I have the feeling it's very true in JS world nobody ever thinks about RAM and GC ^_^ That said, it becomes over complicated for non concrete reason/use case if we have strings since AFAIK WeakMap does not accept strings as key. For all this time the event type as string has blocked like ... nobody ever ? I wonder again what's the benefit then to instantly over complicate an API at this stage instead of looking around what worked already for everyone. Maybe it's me not seeing the power of objects as events. br On Thu, Jul 11, 2013 at 2:32 PM, Rick Waldron waldron.r...@gmail.com wrote: On Thu, Jul 11, 2013 at 4:45 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I would simplify saying that symbols can be used as well as strings ? I don't see any usefulness into using an object as event type and I think if we start olready over-engineered/complicated this will never see the light in any spec which is a lost/lost if you ask me It's trivial if an Emitter uses something like [[MapData]] or [[WeakMapData]] as it's internal data property for event storage. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
With the availability of constants and Symbols you could easily create what SHOULD be a memory efficient event library. On Thu, Jul 11, 2013 at 3:04 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: trivial like ... 2 weak maps + a set for a single event ? ```javascript obj.on(evt, handler); ``` .. internals ... ```javascript // wm as private internal generic WeakMap if (!wm.has(obj)) { // creates related WeakMap wm.set(obj, new WeakMap); } if (!wm.get(obj).has(evt)) { wm.get(obj).set(evt, new Set); } wm.get(obj).get(evt).add(handler); ``` I have the feeling it's very true in JS world nobody ever thinks about RAM and GC ^_^ That said, it becomes over complicated for non concrete reason/use case if we have strings since AFAIK WeakMap does not accept strings as key. For all this time the event type as string has blocked like ... nobody ever ? I wonder again what's the benefit then to instantly over complicate an API at this stage instead of looking around what worked already for everyone. Maybe it's me not seeing the power of objects as events. br On Thu, Jul 11, 2013 at 2:32 PM, Rick Waldron waldron.r...@gmail.comwrote: On Thu, Jul 11, 2013 at 4:45 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I would simplify saying that symbols can be used as well as strings ? I don't see any usefulness into using an object as event type and I think if we start olready over-engineered/complicated this will never see the light in any spec which is a lost/lost if you ask me It's trivial if an Emitter uses something like [[MapData]] or [[WeakMapData]] as it's internal data property for event storage. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
I'm in favour of this standard class approach. I just hope that when discussing this people would also entertain a non-string event type. emitter.addListener( MY_EVENTS.PERMISSION_UPDATE, callback ); So in a modern IDE you could click on MY_EVENTS.PERMISSION_UPDATE and it would display the object which could contain the arguments the callback is provided with and a place to document the event. It might also improve minifying/refactoring and searching for occurrences of the event much easier then if it where a simple string. On Thu, Jul 11, 2013 at 2:37 AM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Jul 10, 2013 at 9:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: On Wed, Jul 10, 2013 at 6:16 PM, Rick Waldron waldron.r...@gmail.com wrote: I absolutely stand by championing such a standard module. then I stop here waiting for other opinions about championing an Emitter mixin/module/constructor in core. best regards I feel like we've made progress https://github.com/tc39/agendas/pull/6 Rick ___ 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: Object#extra hazard
I would simplify saying that symbols can be used as well as strings ? I don't see any usefulness into using an object as event type and I think if we start olready over-engineered/complicated this will never see the light in any spec which is a lost/lost if you ask me On Thu, Jul 11, 2013 at 5:53 AM, Brian Di Palma off...@gmail.com wrote: I'm in favour of this standard class approach. I just hope that when discussing this people would also entertain a non-string event type. emitter.addListener( MY_EVENTS.PERMISSION_UPDATE, callback ); So in a modern IDE you could click on MY_EVENTS.PERMISSION_UPDATE and it would display the object which could contain the arguments the callback is provided with and a place to document the event. It might also improve minifying/refactoring and searching for occurrences of the event much easier then if it where a simple string. On Thu, Jul 11, 2013 at 2:37 AM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Jul 10, 2013 at 9:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: On Wed, Jul 10, 2013 at 6:16 PM, Rick Waldron waldron.r...@gmail.com wrote: I absolutely stand by championing such a standard module. then I stop here waiting for other opinions about championing an Emitter mixin/module/constructor in core. best regards I feel like we've made progress https://github.com/tc39/agendas/pull/6 Rick ___ 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: Object#extra hazard
On Thu, Jul 11, 2013 at 4:45 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I would simplify saying that symbols can be used as well as strings ? I don't see any usefulness into using an object as event type and I think if we start olready over-engineered/complicated this will never see the light in any spec which is a lost/lost if you ask me It's trivial if an Emitter uses something like [[MapData]] or [[WeakMapData]] as it's internal data property for event storage. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
trivial like ... 2 weak maps + a set for a single event ? ```javascript obj.on(evt, handler); ``` .. internals ... ```javascript // wm as private internal generic WeakMap if (!wm.has(obj)) { // creates related WeakMap wm.set(obj, new WeakMap); } if (!wm.get(obj).has(evt)) { wm.get(obj).set(evt, new Set); } wm.get(obj).get(evt).add(handler); ``` I have the feeling it's very true in JS world nobody ever thinks about RAM and GC ^_^ That said, it becomes over complicated for non concrete reason/use case if we have strings since AFAIK WeakMap does not accept strings as key. For all this time the event type as string has blocked like ... nobody ever ? I wonder again what's the benefit then to instantly over complicate an API at this stage instead of looking around what worked already for everyone. Maybe it's me not seeing the power of objects as events. br On Thu, Jul 11, 2013 at 2:32 PM, Rick Waldron waldron.r...@gmail.comwrote: On Thu, Jul 11, 2013 at 4:45 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I would simplify saying that symbols can be used as well as strings ? I don't see any usefulness into using an object as event type and I think if we start olready over-engineered/complicated this will never see the light in any spec which is a lost/lost if you ask me It's trivial if an Emitter uses something like [[MapData]] or [[WeakMapData]] as it's internal data property for event storage. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
Le 10/07/2013 16:53, Andrea Giammarchi a écrit : Just a humble attempt to propose some addiction to the `Object.prototype` I already know many will kill me for even trying to ... **tl;dr** - everything proposed can be already tested through this utility called [eddy.js](https://github.com/WebReflection/eddy#event-driven-js) ### Event Target All The Things One of the most widely adopted API in JavaScript world is based on a combination of these methods: * `.on(type, handler[, capture])` used as equivalent of `addEventListener` in the DOM namespace, also used in every library that would like to be event driven. Smart enough to avoid duplicated entries for the same handler over the same event type. * `.once(type, handler[, capture])` used to simplify `.on()` within an `.off()` at the top of the invocation to ensure a one shot only event * `.off(type, handler[, capture])` to remove a previously set event handler or silently failif not present * `.emit(type[, arg1][, argN])` directly from node.js world where almost every object is an EventTarget and EventEmitter anyhow since it's needed and has been proven it's a highly appreciated/welcome approach. * `.trigger(type[, data])` similar to `.emit()` except it triggers/fires an event object with some extra method such `evt.stopImmediatePropagation()` or others DOM related when the event comes from DOM The proposed implementation lazily assign internal listeners event handlers only once these methods are invoked for the very first time. This makes every object ... inheriting from Object.prototype... able to be promoted at runtime as event emitter: ```javascript var o = {}; // o is just an object o.on('event-name', console.log.bind(console)); // now o has internals able to work with handlers o.trigger('event-name'); // will log an Event object ``` I believe events should be part of the object MOP interface (regardless of the [[Prototype]] value). Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. Also, Object properties now have their events (Object.observe), following DOM mutation-related events (DOM Observers API). It won't take long before someone asks for mutation events in ES6 Maps and Sets... Anyway, I agree with the intent, but I would put the tool at a lower-level if given the choice. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. I don't think that Node.js is a relevant example here. Events are only exposed on instances (or subclasses) of EventEmitter. This happens to include a lot of the core objects, but it is nonetheless implemented via the [[Prototype]] and object-level properties (rather than anything resembling a MOP). I'm less familiar with FirefoxOS WebAPIs, but the same appears to be true here as well, unless I'm missing something. On Wed, Jul 10, 2013 at 1:33 PM, David Bruant bruan...@gmail.com wrote: Le 10/07/2013 16:53, Andrea Giammarchi a écrit : Just a humble attempt to propose some addiction to the `Object.prototype` I already know many will kill me for even trying to ... **tl;dr** - everything proposed can be already tested through this utility called [eddy.js](https://github.com/**WebReflection/eddy#event-** driven-js https://github.com/WebReflection/eddy#event-driven-js) ### Event Target All The Things One of the most widely adopted API in JavaScript world is based on a combination of these methods: * `.on(type, handler[, capture])` used as equivalent of `addEventListener` in the DOM namespace, also used in every library that would like to be event driven. Smart enough to avoid duplicated entries for the same handler over the same event type. * `.once(type, handler[, capture])` used to simplify `.on()` within an `.off()` at the top of the invocation to ensure a one shot only event * `.off(type, handler[, capture])` to remove a previously set event handler or silently failif not present * `.emit(type[, arg1][, argN])` directly from node.js world where almost every object is an EventTarget and EventEmitter anyhow since it's needed and has been proven it's a highly appreciated/welcome approach. * `.trigger(type[, data])` similar to `.emit()` except it triggers/fires an event object with some extra method such `evt.stopImmediatePropagation( **)` or others DOM related when the event comes from DOM The proposed implementation lazily assign internal listeners event handlers only once these methods are invoked for the very first time. This makes every object ... inheriting from Object.prototype... able to be promoted at runtime as event emitter: ```javascript var o = {}; // o is just an object o.on('event-name', console.log.bind(console)); // now o has internals able to work with handlers o.trigger('event-name'); // will log an Event object ``` I believe events should be part of the object MOP interface (regardless of the [[Prototype]] value). Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. Also, Object properties now have their events (Object.observe), following DOM mutation-related events (DOM Observers API). It won't take long before someone asks for mutation events in ES6 Maps and Sets... Anyway, I agree with the intent, but I would put the tool at a lower-level if given the choice. David __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss -- Jeremy Martin 661.312.3853 http://devsmash.com @jmar777 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
I'd rather do something like: Object.addEventListener(obj, eventName, function(){}); I think this matches very closely the way you do property descriptors and I'd love to see var obj = { on eventName() {} } On Wed, Jul 10, 2013 at 10:33 AM, David Bruant bruan...@gmail.com wrote: Le 10/07/2013 16:53, Andrea Giammarchi a écrit : Just a humble attempt to propose some addiction to the `Object.prototype` I already know many will kill me for even trying to ... **tl;dr** - everything proposed can be already tested through this utility called [eddy.js](https://github.com/**WebReflection/eddy#event-** driven-js https://github.com/WebReflection/eddy#event-driven-js) ### Event Target All The Things One of the most widely adopted API in JavaScript world is based on a combination of these methods: * `.on(type, handler[, capture])` used as equivalent of `addEventListener` in the DOM namespace, also used in every library that would like to be event driven. Smart enough to avoid duplicated entries for the same handler over the same event type. * `.once(type, handler[, capture])` used to simplify `.on()` within an `.off()` at the top of the invocation to ensure a one shot only event * `.off(type, handler[, capture])` to remove a previously set event handler or silently failif not present * `.emit(type[, arg1][, argN])` directly from node.js world where almost every object is an EventTarget and EventEmitter anyhow since it's needed and has been proven it's a highly appreciated/welcome approach. * `.trigger(type[, data])` similar to `.emit()` except it triggers/fires an event object with some extra method such `evt.stopImmediatePropagation( **)` or others DOM related when the event comes from DOM The proposed implementation lazily assign internal listeners event handlers only once these methods are invoked for the very first time. This makes every object ... inheriting from Object.prototype... able to be promoted at runtime as event emitter: ```javascript var o = {}; // o is just an object o.on('event-name', console.log.bind(console)); // now o has internals able to work with handlers o.trigger('event-name'); // will log an Event object ``` I believe events should be part of the object MOP interface (regardless of the [[Prototype]] value). Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. Also, Object properties now have their events (Object.observe), following DOM mutation-related events (DOM Observers API). It won't take long before someone asks for mutation events in ES6 Maps and Sets... Anyway, I agree with the intent, but I would put the tool at a lower-level if given the choice. David __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
Le 10/07/2013 19:57, Jeremy Martin a écrit : Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. I don't think that Node.js is a relevant example here. Events are only exposed on instances (or subclasses) of EventEmitter. This happens to include a lot of the core objects, but it is nonetheless implemented via the [[Prototype]] and object-level properties (rather than anything resembling a MOP). I'm less familiar with FirefoxOS WebAPIs, but the same appears to be true here as well, unless I'm missing something. That's not my point. I was explaining that people consider events as part of the object interface (regardless of how the event system is implemented). Currently, to express events in JavaScript, one has to go through a specific [[Prototype]] or extending with a mixin which feels awkward to me. Do we need a mixin to add properties to an object? or a specific [[Prototype]] to add methods? In the DOM, having to inherit from EventTarget creates this weird situation where events can't be part of WebIDL. It is even rarely possible to be able to list all events supported by a given object (which in turns makes documenting event quite of a nightmare). Supported events have to be aliased via on* properties to be feature-detectable. This madness really has to stop. We need first class events (and I'm praying for a way to retrofit them into the DOM if possible) David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
Le 10/07/2013 20:00, Matthew Robb a écrit : I'd rather do something like: Object.addEventListener(obj, eventName, function(){}); I think this matches very closely the way you do property descriptors and I'd love to see var obj = { on eventName() {} } That's the spirit. I don't care for particular syntax, but that's what I had in mind too. A while ago, I started a library to have first-class events as object properties in specialized proxies [1]. It has some inherent limitations but is a start in one direction. David [1] https://github.com/DavidBruant/HarmonyProxyLab/tree/EventedObjectsOnDirectProxies/EventedObject On Wed, Jul 10, 2013 at 10:33 AM, David Bruant bruan...@gmail.com mailto:bruan...@gmail.com wrote: Le 10/07/2013 16:53, Andrea Giammarchi a écrit : Just a humble attempt to propose some addiction to the `Object.prototype` I already know many will kill me for even trying to ... **tl;dr** - everything proposed can be already tested through this utility called [eddy.js](https://github.com/WebReflection/eddy#event-driven-js) ### Event Target All The Things One of the most widely adopted API in JavaScript world is based on a combination of these methods: * `.on(type, handler[, capture])` used as equivalent of `addEventListener` in the DOM namespace, also used in every library that would like to be event driven. Smart enough to avoid duplicated entries for the same handler over the same event type. * `.once(type, handler[, capture])` used to simplify `.on()` within an `.off()` at the top of the invocation to ensure a one shot only event * `.off(type, handler[, capture])` to remove a previously set event handler or silently failif not present * `.emit(type[, arg1][, argN])` directly from node.js world where almost every object is an EventTarget and EventEmitter anyhow since it's needed and has been proven it's a highly appreciated/welcome approach. * `.trigger(type[, data])` similar to `.emit()` except it triggers/fires an event object with some extra method such `evt.stopImmediatePropagation()` or others DOM related when the event comes from DOM The proposed implementation lazily assign internal listeners event handlers only once these methods are invoked for the very first time. This makes every object ... inheriting from Object.prototype... able to be promoted at runtime as event emitter: ```javascript var o = {}; // o is just an object o.on('event-name', console.log.bind(console)); // now o has internals able to work with handlers o.trigger('event-name'); // will log an Event object ``` I believe events should be part of the object MOP interface (regardless of the [[Prototype]] value). Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. Also, Object properties now have their events (Object.observe), following DOM mutation-related events (DOM Observers API). It won't take long before someone asks for mutation events in ES6 Maps and Sets... Anyway, I agree with the intent, but I would put the tool at a lower-level if given the choice. David ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
On Wed, Jul 10, 2013 at 2:19 PM, David Bruant bruan...@gmail.com wrote: This madness really has to stop. We need first class events (and I'm praying for a way to retrofit them into the DOM if possible) If you don't do the latter, I wonder how you'll achieve the former. -- http://annevankesteren.nl/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
On further thought I think doing something like: Object.defineEventListener(obj, eventName, { handler: function(){}, phase: before // , after, defaults to `on` }); AND var obj = { on eventName(){}, after eventName(){}, before eventName(){} } On Wed, Jul 10, 2013 at 11:22 AM, David Bruant bruan...@gmail.com wrote: Le 10/07/2013 20:00, Matthew Robb a écrit : I'd rather do something like: Object.addEventListener(obj, eventName, function(){}); I think this matches very closely the way you do property descriptors and I'd love to see var obj = { on eventName() {} } That's the spirit. I don't care for particular syntax, but that's what I had in mind too. A while ago, I started a library to have first-class events as object properties in specialized proxies [1]. It has some inherent limitations but is a start in one direction. David [1] https://github.com/DavidBruant/HarmonyProxyLab/tree/EventedObjectsOnDirectProxies/EventedObject On Wed, Jul 10, 2013 at 10:33 AM, David Bruant bruan...@gmail.com wrote: Le 10/07/2013 16:53, Andrea Giammarchi a écrit : Just a humble attempt to propose some addiction to the `Object.prototype` I already know many will kill me for even trying to ... **tl;dr** - everything proposed can be already tested through this utility called [eddy.js]( https://github.com/WebReflection/eddy#event-driven-js) ### Event Target All The Things One of the most widely adopted API in JavaScript world is based on a combination of these methods: * `.on(type, handler[, capture])` used as equivalent of `addEventListener` in the DOM namespace, also used in every library that would like to be event driven. Smart enough to avoid duplicated entries for the same handler over the same event type. * `.once(type, handler[, capture])` used to simplify `.on()` within an `.off()` at the top of the invocation to ensure a one shot only event * `.off(type, handler[, capture])` to remove a previously set event handler or silently failif not present * `.emit(type[, arg1][, argN])` directly from node.js world where almost every object is an EventTarget and EventEmitter anyhow since it's needed and has been proven it's a highly appreciated/welcome approach. * `.trigger(type[, data])` similar to `.emit()` except it triggers/fires an event object with some extra method such `evt.stopImmediatePropagation()` or others DOM related when the event comes from DOM The proposed implementation lazily assign internal listeners event handlers only once these methods are invoked for the very first time. This makes every object ... inheriting from Object.prototype... able to be promoted at runtime as event emitter: ```javascript var o = {}; // o is just an object o.on('event-name', console.log.bind(console)); // now o has internals able to work with handlers o.trigger('event-name'); // will log an Event object ``` I believe events should be part of the object MOP interface (regardless of the [[Prototype]] value). Events are already part of the interface of objects as people use them: * in Node.js, events are documented at the same level than properties and methods. * In new FirefoxOS WebAPIs, pretty much every new object inherits from EventTarget. Also, Object properties now have their events (Object.observe), following DOM mutation-related events (DOM Observers API). It won't take long before someone asks for mutation events in ES6 Maps and Sets... Anyway, I agree with the intent, but I would put the tool at a lower-level if given the choice. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
Le 10/07/2013 20:27, Anne van Kesteren a écrit : On Wed, Jul 10, 2013 at 2:19 PM, David Bruant bruan...@gmail.com wrote: This madness really has to stop. We need first class events (and I'm praying for a way to retrofit them into the DOM if possible) If you don't do the latter, I wonder how you'll achieve the former. The former can be achieved independently of anything else. It only requires for the ECMA 262 spec to say now, objects have events! (like, say, the way Jeremy Martin proposed). Whether that event system works well and intelligently with the current event systems (DOM especially since it has lots of quirks) is a different matter. But I agree it would be wise to do both at the same time. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
Yeah, so what I meant was how you'd stop the madness if you don't do them in a way that works with DOM (as DOM works today). My bad. -- http://annevankesteren.nl/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
(like, say, the way Jeremy Martin proposed) FTR, I haven't proposed anything just yet :) Although if I did, I think I would be more fond of something like: Object.mixin({ foo: 'bar' }, EventEmitter); ... that is, I can see the value of events as an object-level API that doesn't imply actual inheritance from something else. The use of `mixin` is probably a distraction here, but the main point is that it's opt-in. Events inherently have semantics around them, and they're certainly not universal semantics for objects. In fact, event semantics aren't even universal for events (e.g., bubbling). It seems better to me to have some sort of explicit contract before those semantics kick in. On Wed, Jul 10, 2013 at 2:31 PM, David Bruant bruan...@gmail.com wrote: Le 10/07/2013 20:27, Anne van Kesteren a écrit : On Wed, Jul 10, 2013 at 2:19 PM, David Bruant bruan...@gmail.com wrote: This madness really has to stop. We need first class events (and I'm praying for a way to retrofit them into the DOM if possible) If you don't do the latter, I wonder how you'll achieve the former. The former can be achieved independently of anything else. It only requires for the ECMA 262 spec to say now, objects have events! (like, say, the way Jeremy Martin proposed). Whether that event system works well and intelligently with the current event systems (DOM especially since it has lots of quirks) is a different matter. But I agree it would be wise to do both at the same time. David -- Jeremy Martin 661.312.3853 http://devsmash.com @jmar777 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
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. 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. ```javascript // current eddy.js status var obj = {} .on(type1, handler1) .on(type2, handler2) .on(type3, handler3) ; ``` This allows multiple operations with the same object, something not possible with the `Object.publicStatic` alternative if not repeating same thing many times. The chainability won here in both jQuery and node.js world, together with many other libraries. I know it's hard to even think about polluting the `Object.prototype` but indeed FirefoxOS uses events all over the place, node.js is basically 90% event driven, so is the DOM, and every observable object is firing indirectly events for third parts. What else do we need to understand that maybe we could simplify this in core and make event driven development **way easier** and finally more standard? Even keeping the double firing approach, both `trigger` and `emit` since these two do different things (slightly, but still...) Last wonder, nobody said a word about the `.boundTo(method)` solution for a very very common/frequent problem. Thanks for all other thoughts though, best regards. On Wed, Jul 10, 2013 at 11:42 AM, Anne van Kesteren ann...@annevk.nlwrote: Yeah, so what I meant was how you'd stop the madness if you don't do them in a way that works with DOM (as DOM works today). My bad. -- http://annevankesteren.nl/ ___ 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: Object#extra hazard
You can do chainability at object define time with the sugar form: var obj = { on type1(){}, on type2(){}, on type3(){} } 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.giammar...@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. 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. ```javascript // current eddy.js status var obj = {} .on(type1, handler1) .on(type2, handler2) .on(type3, handler3) ; ``` This allows multiple operations with the same object, something not possible with the `Object.publicStatic` alternative if not repeating same thing many times. The chainability won here in both jQuery and node.js world, together with many other libraries. I know it's hard to even think about polluting the `Object.prototype` but indeed FirefoxOS uses events all over the place, node.js is basically 90% event driven, so is the DOM, and every observable object is firing indirectly events for third parts. What else do we need to understand that maybe we could simplify this in core and make event driven development **way easier** and finally more standard? Even keeping the double firing approach, both `trigger` and `emit` since these two do different things (slightly, but still...) Last wonder, nobody said a word about the `.boundTo(method)` solution for a very very common/frequent problem. Thanks for all other thoughts though, best regards. On Wed, Jul 10, 2013 at 11:42 AM, Anne van Kesteren ann...@annevk.nlwrote: Yeah, so what I meant was how you'd stop the madness if you don't do them in a way that works with DOM (as DOM works today). My bad. -- http://annevankesteren.nl/ ___ 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 -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
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 matthewwr...@gmail.comwrote: You can do chainability at object define time with the sugar form: var obj = { on type1(){}, on type2(){}, on type3(){} } 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.giammar...@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. 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. ```javascript // current eddy.js status var obj = {} .on(type1, handler1) .on(type2, handler2) .on(type3, handler3) ; ``` This allows multiple operations with the same object, something not possible with the `Object.publicStatic` alternative if not repeating same thing many times. The chainability won here in both jQuery and node.js world, together with many other libraries. I know it's hard to even think about polluting the `Object.prototype` but indeed FirefoxOS uses events all over the place, node.js is basically 90% event driven, so is the DOM, and every observable object is firing indirectly events for third parts. What else do we need to understand that maybe we could simplify this in core and make event driven development **way easier** and finally more standard? Even keeping the double firing approach, both `trigger` and `emit` since these two do different things (slightly, but still...) Last wonder, nobody said a word about the `.boundTo(method)` solution for a very very common/frequent problem. Thanks for all other thoughts though, best regards. On Wed, Jul 10, 2013 at 11:42 AM, Anne van Kesteren ann...@annevk.nlwrote: Yeah, so what I meant was how you'd stop the madness if you don't do them in a way that works with DOM (as DOM works today). My bad. -- http://annevankesteren.nl/ ___ 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 -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
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.giammar...@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 matthewwr...@gmail.comwrote: 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.giammar...@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@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
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.r...@gmail.comwrote: 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.giammar...@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 matthewwr...@gmail.comwrote: 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.giammar...@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@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___
Re: Object#extra hazard
inline ... On Wed, Jul 10, 2013 at 3:57 PM, Rick Waldron waldron.r...@gmail.comwrote: 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 } } tis works same way you can define toString during class definition ... so what happens, nothing unexpected. boundTo methods that are actually useless now. I think you didn't understand what is boundTo ... completely a part from events. You can bind any method or function, borrowed or not, and only once, I don't see how you can do the same with current proposal in ES6 genericObject.boundTo(genericMethod) returns always the same bound object. This is actually trivial enough as utility since chainability is not even an option. 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? Because in 10 years I haven't seen such standard Emitter so it's about the time to agree on an event based mechanism, IMO, since we all talk about events in every asynchronous world. Object.observer ain't good for all cases but only for few of them. We all know how powerful are events. var obj = { on type1(){}, on type2(){}, on type3(){} } This is the dark days of DOM element properties as event handlers: elem.onclick... it's also more semantic than `node.addEventListener('load')` since you say and write and mean `node.on('load');` What's less semantic is `.off()` if you want, but it works as counter part. And back to the light, I would rather use `switch(onOrOff) {}` as method Assigning to this paves over the previous assignment, leaving no way to have multiple handlers registered for the same event type. You are right, in that inline version this is correct. I didn't propose that indeed and you can use more than a handler without problems. 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. it works in the meaning that in node you give for granted that basically every object is an EventEmitter. If there was a mechanism to have that simplified today I believe it would have been used. 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. agreed ```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. So are you willing to talk about that standard EventEmitter and put it in ASAP as native constructor every object could inherit from ? 'cause this would be already a lot for me and everyone else out there, a native way to have emitters in core (hopefully able to work with DOM nodes too) Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
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 k...@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.r...@gmail.comwrote: 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.giammar...@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 matthewwr...@gmail.comwrote: 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.giammar...@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
Re: Object#extra hazard
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.giammar...@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 k...@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.r...@gmail.comwrote: 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.giammar...@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
Re: Object#extra hazard
node.js allows same listener type with same handler multiple times ... but it has `maxListeners` number which is kinda pointless if events are not even tracked and can be duplicated. node also has this thing that you can drop everything from an emitter even if you don't own registered events which is, in my opinion, undesired, specially when you pass around your own modules expecting them to react in certain cases. That said, node.js folks had to quickly define/decide what was needed and that's what they came up with ... it worked until now but I think I've never seen a module that really needed all that API (there are too many out there though so I might be wrong) Not having this in core means every implementation will differ somehow and this is the annoying part ... there's no way to write code that is compatible with both worlds or all libraries without sniffing the surrounding environment. Let's say my module would like to intercept some generic event and react ... no standard way to even know which was the fired event in node, since no type is passed, no easy way to check for errors in DOM world. Keep telling devs to create their own Emitter because of this and that weird case that should probably not exist in first place, and here I believe that DOM and DOM based libraries have more experience than node.js, cannot benefit anyone in both worlds for something needed since the very beginning in every organized asynchronous situation. As example, I do like the `{handleEvent:function(evt){}}` concept and used that a lot without needing to bind anything because the context is always the expected one (unless handleEvent has been bound differently, of course) ... in node I need to be careful that no extra listeners are added but the amount of garbage created per each Emitter usage and bound objects is not considered a problem? This is just weird, as weird is the decision that since it's hard to make it right we rather prefer anarchy around the topic per each slightly different, who knows why, behavior ... node.js could have simply followed DOM logic passing Event or instanceof Error as single argument, there is massive fragmentation there already but here there was my attempt to bring more harmony around events. node.js guys are OK with that, I can cope with that too, but having 2 different models without any win in both environment does not look like the right approach to me. Anyway, I started saying I was not even expecting people considering a change ... so it's OK. Best Regards On Wed, Jul 10, 2013 at 5:12 PM, Jeremy Martin jmar...@gmail.com wrote: 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.giammar...@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,
Re: Object#extra hazard
inline... On Wed, Jul 10, 2013 at 7:22 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: inline ... On Wed, Jul 10, 2013 at 3:57 PM, Rick Waldron waldron.r...@gmail.comwrote: 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 } } tis works same way you can define toString during class definition ... so what happens, nothing unexpected. This response completely dodges the point I've made and toString is a poor comparison. toString is only one method and it's expected that a class (or previously Constructor.prototype.toString) would define it's own toString with an appropriate return value. boundTo methods that are actually useless now. I think you didn't understand what is boundTo ... completely a part from events. No, I understood it just fine. I was just listing out every method listed here https://github.com/WebReflection/eddy#event-driven-js but you snipped the rest of the sentence, so now it's out of context. You can bind any method or function, borrowed or not, and only once, I don't see how you can do the same with current proposal in ES6 genericObject.boundTo(genericMethod) returns always the same bound object. This is actually trivial enough as utility since chainability is not even an option. 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? Because in 10 years I haven't seen such standard Emitter so it's about the time to agree on an event based mechanism, IMO, since we all talk about events in every asynchronous world. What I'm saying is: let's agree to an Emitter and make it a standard library module. Object.observer ain't good for all cases but only for few of them. We all know how powerful are events. var obj = { on type1(){}, on type2(){}, on type3(){} } This is the dark days of DOM element properties as event handlers: elem.onclick... it's also more semantic than `node.addEventListener('load')` since you say and write and mean `node.on('load');` What are you talking about? Look again at the example I'm commenting on and explain to me how to register two different handlers for an event named type1. Yes, addEventListener sucks. Yes, on(foo, handler) is great. What's less semantic is `.off()` if you want, but it works as counter part. And back to the light, I would rather use `switch(onOrOff) {}` as method Assigning to this paves over the previous assignment, leaving no way to have multiple handlers registered for the same event type. You are right, in that inline version this is correct. I didn't propose that indeed and you can use more than a handler without problems. Of course, I was referring to the syntactic form that Matthew proposed: var obj = { on foo() {} } (this is still part of my point above, re: registering multiple handlers for the same named event) 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. it works in the meaning that in node you give for granted that basically every object is an EventEmitter. If there was a mechanism to have that simplified today I believe it would have been used. It may not be simple by your definition (it isn't simple by mine), but it's the most common practice... var Emitter = require(events).EventEmitter; function Foo() { Emitter.call(this); } Foo.prototype = Object.create(Emitter.prototype); Foo.prototype.constructor = Foo; Which corresponds to: class Foo extends Emitter { constructor() { super() } } Maybe I'm missing something in your argument here? If so, I apologize. 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. agreed ```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. So are you willing to talk about that standard EventEmitter and put it in ASAP as native constructor every object could inherit from ? I absolutely stand by
Re: Object#extra hazard
On Wed, Jul 10, 2013 at 7:27 PM, Andrea Giammarchi andrea.giammar...@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 ;-) But they're different things entirely. Object.observe is an implicit invocation, observer pattern (some may accuse me of being redundant there, I forgive them) that announces the relevant states and state changes in the life of an object. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
On Wed, Jul 10, 2013 at 6:16 PM, Rick Waldron waldron.r...@gmail.comwrote: I absolutely stand by championing such a standard module. then I stop here waiting for other opinions about championing an Emitter mixin/module/constructor in core. best regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object#extra hazard
On Wed, Jul 10, 2013 at 9:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: On Wed, Jul 10, 2013 at 6:16 PM, Rick Waldron waldron.r...@gmail.comwrote: I absolutely stand by championing such a standard module. then I stop here waiting for other opinions about championing an Emitter mixin/module/constructor in core. best regards I feel like we've made progress https://github.com/tc39/agendas/pull/6 Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss