thisArg in Array#find and Array#findIndex
Hi, I was wondering whether it was any useful to have the thisArg argument in Array#find and Array#findIndex. As of ES6, the language has Function.prototype.bind and arrow functions and I would imagine these to be enough to cover any use case where thisArg would be used. I know that in the majority of cases I have experienced, there is no need for a specific 'this' at all. In the majority of the remaining cases arrow functions would have been enough. I guess .bind can do the job find for the remaining 0.1% after that... David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
Le 10 juil. 2013 à 11:26, David Bruant bruan...@gmail.com a écrit : Hi, I was wondering whether it was any useful to have the thisArg argument in Array#find and Array#findIndex. As of ES6, the language has Function.prototype.bind and arrow functions and I would imagine these to be enough to cover any use case where thisArg would be used. I know that in the majority of cases I have experienced, there is no need for a specific 'this' at all. In the majority of the remaining cases arrow functions would have been enough. I guess .bind can do the job find for the remaining 0.1% after that... David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss * Consistency with every other Array methods that takes a predicate as first argument, and thisArg as second argument (map, filter, every, etc.). * You can use Array#find (and Array#filter, Array#every, ...) now (with a polyfill), but you have to wait, say, six years until you can use arrow functions on the web (until non-ES6 browsers are dead). Meanwhile, using this as second argument is the most concise and most elegant way to simulate arrow functions. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Object#extra hazard
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 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 ``` ### An Extra Should Have Utility We talk a lot about GC these days and performance impact this has on slower device (or embedded ARM boards such R-PI or Cubieboard, hardware used in production and as server too in some crazy case!). There is a common **anti pattern** in JS code since some library introduced `Function#bind()` and ES decided to adopt it: it creates N new objects per each call. This makes it impossible to remove listeners so we are forced to address every single object. As example, back to a similar previous code example: ```javascript window.addEventListener('load', console.log.bind(console)); // now how to drop that ? ``` There is no way to remove that listener after that and developers keep passing functions, instead of objects with `handleEvent()` methods, and more complex code becomes easily messed up. `Object.prototype.boundTo(method)` would be able to solve this in a very simple way: creates, if not created already, a bound version of that method so that any further call to the same method will result in the same bound object. ```javascript window.addEventListener('load', console.boundTo(console.log)); // whenever we want to ... window.removeEventListener('load', console.boundTo(console.log)); ``` In my `eddy.js` proposal this method has a shortcut too, shortcut that might break if some obtrusive minifier as Closure Compiler with ADVANCED option is taking care of the build process. This is why I am not expecting much consensus about the overload of this `boundTo()` method but here what I've done: ```javascript window.addEventListener('load', console.boundTo('log')); // whenever we want to ... window.removeEventListener('load', console.boundTo('log')); // same as window.removeEventListener('load', console.boundTo(console.log)); ``` The method can accept either a function or a string, where in latter case, the `context[methodName]` is used to check if the bound object has been created already. `.boundTo(method)` should not accept extra arguments since in that case advantages are less than a generic bind due very exponential nature of the possible check over all arguments. In that case developers can use bind and address it if really needed but I've seen this is not the majority of the cases. **Thank You** for listening, reading, sharing thoughts, or proposing any change ... I know I'm going to be probably the only one in this planet that will pollute in a non enumerable way the `Object.prototype` with the stuff I need the most in every single piece of JS software I've written but hey ... maybe it was worth it to try to propose here too :-) Best Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Creating your own errors
Hi all, What is the current expected way for an author to throw a custom errors? You obviously could do something like: throw { reason: TimeoutError }; or throw TimeoutError; However that makes it very hard for anyone receiving an exception to inspect what it is. I.e. you'd first have to check what type of value it is, i.e. if it's a string, something that's instanceof Error, or something with just custom properties. Instead you can do throw new Error; However, as I understand it, that doesn't let you pass machine-readable information in the error. You can only pass a message which is intended for human consumption. I.e. something like: throw new Error(operation took too long and timed out.); Yet another alternative is to do let e = new Error; e.name = TimeoutError; throw e; This is a little bit more code than expected though. A shorter alternative that is somewhat compatible with Error is throw { name: TimeoutError }; However this means that 'instanceof Error' returns false, which could mean that code is forced to check which properties are set. The reason I'm asking is that the DOM has invented a completely new interface, DOMError. This seems pretty heavy-handed and yet another instance of the DOM doing it in its own way rather than using existing ES functionality. I'd like for the DOM to mimic what we expect authors to do. It's just not obvious to me what authors are expected to do if they want to throw a machine readable error. I.e. one that allows code to catch the error and handle it. / Jonas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Creating your own errors
In some browsers, using the native Error class enables cool features like automatic stack trace. Just in case you need special kind of Error (ie: subclasses), I recommend doing it that way: function SomeError(message) { // the real instance should be an Error: var self = new Error(message); // but the prototype could be updated if(self.__proto__) { self.__proto__ = SomeError.protoype } else { copyProperties(SomeError.prototype, self); } // do some more custom things // ... // return the instance return self; } SomeError.prototype = Object.create(Error.prototype); throw new SomeError('abc'); From: jo...@sicking.cc Date: Wed, 10 Jul 2013 12:23:54 -0400 Subject: Creating your own errors To: es-discuss@mozilla.org Hi all, What is the current expected way for an author to throw a custom errors? You obviously could do something like: throw { reason: TimeoutError }; or throw TimeoutError; However that makes it very hard for anyone receiving an exception to inspect what it is. I.e. you'd first have to check what type of value it is, i.e. if it's a string, something that's instanceof Error, or something with just custom properties. Instead you can do throw new Error; However, as I understand it, that doesn't let you pass machine-readable information in the error. You can only pass a message which is intended for human consumption. I.e. something like: throw new Error(operation took too long and timed out.); Yet another alternative is to do let e = new Error; e.name = TimeoutError; throw e; This is a little bit more code than expected though. A shorter alternative that is somewhat compatible with Error is throw { name: TimeoutError }; However this means that 'instanceof Error' returns false, which could mean that code is forced to check which properties are set. The reason I'm asking is that the DOM has invented a completely new interface, DOMError. This seems pretty heavy-handed and yet another instance of the DOM doing it in its own way rather than using existing ES functionality. I'd like for the DOM to mimic what we expect authors to do. It's just not obvious to me what authors are expected to do if they want to throw a machine readable error. I.e. one that allows code to catch the error and handle it. / Jonas ___ 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: Creating your own errors
Woah, François, that seems pretty overcomplicated; why not replace everything inside the constructor with `this.message = message`? It has the same effect in the browsers I've seen. (Also don't forget `SomeError.prototype.constructor = SomeError`.) Anyway, to Jonas's point: I think `DOMError` is actually pretty OK. One thing I noticed is that the ES5 spec (and presumably ES6, although I haven't checked) is careful to never throw simple `Error` objects, but instead `TypeError`s or `RangeError`s or so on. I infer that they are leaving bare `Error` for user cases. I think the platform should generally follow this lead; that is, the DOM should leave bare `Error`s to the user, and throw `DOMError`s or `TypeError`s or `RangeError`s for its own errors. To answer your more general question, authors are strongly discouraged from ever throwing anything that is not `instanceof Error`, see e.g. Guillermo Rauch's [A String is not an Error](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/). Also, the `name` property is generally the same across all instances of a particular error type, i.e. ```js errInstance.name === errInstance.constructor.name === errInstance.constructor.prototype.name === Object.getPrototypeOf(errInstance).name ``` (You can verify this for all the built-in ES5 errors.) Usually a `code` property is used for more specific information, from what I've seen. But yes, that has to be added manually with a bit of awkwardness, i.e. ```js const e = new DOMError(The message); e.code = TimeoutError; throw e; ``` ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
Le 10/07/2013 14:48, Claude Pache a écrit : Le 10 juil. 2013 à 11:26, David Bruant bruan...@gmail.com a écrit : Hi, I was wondering whether it was any useful to have the thisArg argument in Array#find and Array#findIndex. As of ES6, the language has Function.prototype.bind and arrow functions and I would imagine these to be enough to cover any use case where thisArg would be used. I know that in the majority of cases I have experienced, there is no need for a specific 'this' at all. In the majority of the remaining cases arrow functions would have been enough. I guess .bind can do the job find for the remaining 0.1% after that... David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss * Consistency with every other Array methods that takes a predicate as first argument, and thisArg as second argument (map, filter, every, etc.). I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway? * You can use Array#find (and Array#filter, Array#every, ...) now (with a polyfill), but you have to wait, say, six years until you can use arrow functions on the web (until non-ES6 browsers are dead). I've been using arrow functions for the last 2 weeks with TypeScript. True story :-) Note that even if you don't want to use the whole type infrastructure, you can always use TypeScript to get most of ES6 sugar (if the compiler raises type errors, you can ignore them: js files are outputted anyways) Meanwhile, using this as second argument is the most concise and most elegant way to simulate arrow functions. .bind(this) is barely less concise. I have no opinion on elegancy in this case. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
David Bruant wrote: I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway? Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight. The perf savings is an allocation, but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking. /be ___ 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: Creating your own errors
Hi Jonas, As an example from the field, here is how we extend our own error types: https://github.com/imvu/imvujs/blob/master/src/error.js You can either switch on e.name or use e instanceof ErrorType in your catch handler. Like Francois's approach, it also preserves the 'stack' property if the browser supports it. Hope that helps, Chad On Wed, Jul 10, 2013 at 9:23 AM, Jonas Sicking jo...@sicking.cc wrote: Hi all, What is the current expected way for an author to throw a custom errors? You obviously could do something like: throw { reason: TimeoutError }; or throw TimeoutError; However that makes it very hard for anyone receiving an exception to inspect what it is. I.e. you'd first have to check what type of value it is, i.e. if it's a string, something that's instanceof Error, or something with just custom properties. Instead you can do throw new Error; However, as I understand it, that doesn't let you pass machine-readable information in the error. You can only pass a message which is intended for human consumption. I.e. something like: throw new Error(operation took too long and timed out.); Yet another alternative is to do let e = new Error; e.name = TimeoutError; throw e; This is a little bit more code than expected though. A shorter alternative that is somewhat compatible with Error is throw { name: TimeoutError }; However this means that 'instanceof Error' returns false, which could mean that code is forced to check which properties are set. The reason I'm asking is that the DOM has invented a completely new interface, DOMError. This seems pretty heavy-handed and yet another instance of the DOM doing it in its own way rather than using existing ES functionality. I'd like for the DOM to mimic what we expect authors to do. It's just not obvious to me what authors are expected to do if they want to throw a machine readable error. I.e. one that allows code to catch the error and handle it. / Jonas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Chad Austin Technical Director, IMVU http://www.imvu.com/members/Chad/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
In addition to the perf savings from not having to allocate (to call bind) not needing to use bind() for cases like .find() can have beneficial effects for JITs as well. It's my understanding that at a recent point in time (maybe even still today?) functions created by bind() had the ability to deoptimize call sites in V8 and Spidermonkey in certain scenarios. If the existing design lets developers use free functions without having to use bind(), that makes it easier for them to end up in the performance sweet spot we know about when it comes to crunching data. The longer they can stay in that sweet spot and still use built-ins like find/findIndex, the better. On Wed, Jul 10, 2013 at 10:28 AM, Brendan Eich bren...@mozilla.com wrote: David Bruant wrote: I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway? Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight. The perf savings is an allocation, but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking. /be __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://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
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: thisArg in Array#find and Array#findIndex
Le 10/07/2013 19:28, Brendan Eich a écrit : David Bruant wrote: I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway? Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight. People seem to have survived reduce/reduceRight. The perf savings is an allocation Do engines allocate each time when a function expression is used as first argument? If so, .bind doesn't cost more than a function expression. but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking. I guess... Are reduce/reduceRight acquiring a thisArg, then? David ___ 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: Creating your own errors
On Wed, Jul 10, 2013 at 12:52 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Woah, François, that seems pretty overcomplicated; why not replace everything inside the constructor with `this.message = message`? It has the same effect in the browsers I've seen. (Also don't forget `SomeError.prototype.constructor = SomeError`.) Anyway, to Jonas's point: I think `DOMError` is actually pretty OK. One thing I noticed is that the ES5 spec (and presumably ES6, although I haven't checked) is careful to never throw simple `Error` objects, but instead `TypeError`s or `RangeError`s or so on. I infer that they are leaving bare `Error` for user cases. I think the platform should generally follow this lead; that is, the DOM should leave bare `Error`s to the user, and throw `DOMError`s or `TypeError`s or `RangeError`s for its own errors. To answer your more general question, authors are strongly discouraged from ever throwing anything that is not `instanceof Error`, see e.g. Guillermo Rauch's [A String is not an Error](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/). Also, the `name` property is generally the same across all instances of a particular error type, i.e. ```js errInstance.name === errInstance.constructor.name === errInstance.constructor.prototype.name === Object.getPrototypeOf(errInstance).name ``` (You can verify this for all the built-in ES5 errors.) Usually a `code` property is used for more specific information, from what I've seen. But yes, that has to be added manually with a bit of awkwardness, i.e. ```js const e = new DOMError(The message); e.code = TimeoutError; throw e; ``` Note that (new DOMError) instanceof Error; returns false. So the DOM does do the strongly discouraged thing. Is this ok or bad? Also, the DOM does not create a new class for each different value of .name. I.e. you can get a DOMError whose .name is NetworkError or AbortError. DOMError even has a constructor which allows setting .name to anything: new DOMError(name, message); In fact, there are no defined situations where the DOM creates DOMError objects whose .name is DOMError. Again, is this ok or is it bad practice? / Jonas ___ 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: thisArg in Array#find and Array#findIndex
David Bruant wrote: Le 10/07/2013 19:28, Brendan Eich a écrit : David Bruant wrote: I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway? Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight. People seem to have survived reduce/reduceRight. This isn't about survival as you yourself pointed out, since bind (polyfillable) is an option. This is about best API ergonomics/consistency/cognitive-load. Play fair now! The perf savings is an allocation Do engines allocate each time when a function expression is used as first argument? If so, .bind doesn't cost more than a function expression. So? My main point was not perf. but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking. I guess... Are reduce/reduceRight acquiring a thisArg, then? No, it's too late for those two, and thisArg didn't fit consistently in the parameter list anyway, as we have discussed here in the past. It's not too late for find and findIndex, and they do fit the pattern. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Creating your own errors
Jonas, DOM never throws DOMError. DOMErrors are used for other error mechanisms, such as callbacks. [1] The DOM spec does however throw DOMException objects [2]. These are instanceof Error (see WebIDL [3]) var ex; try { document.appendChild(document); } catch (e) { ex = e; } assert(ex instanceof Error); assert(ex.contructor === DOMException); assert(ex.name === 'HierarchyRequestError'); In Blink DOMException also have a stack property assert(stack in ex); [1] http://dom.spec.whatwg.org/#interface-domerror [2] http://dom.spec.whatwg.org/#exception-domexception [3] http://dev.w3.org/2006/webapi/WebIDL/#es-exception-interface-prototype-object On Wed, Jul 10, 2013 at 3:02 PM, Jonas Sicking jo...@sicking.cc wrote: On Wed, Jul 10, 2013 at 12:52 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Woah, François, that seems pretty overcomplicated; why not replace everything inside the constructor with `this.message = message`? It has the same effect in the browsers I've seen. (Also don't forget `SomeError.prototype.constructor = SomeError`.) Anyway, to Jonas's point: I think `DOMError` is actually pretty OK. One thing I noticed is that the ES5 spec (and presumably ES6, although I haven't checked) is careful to never throw simple `Error` objects, but instead `TypeError`s or `RangeError`s or so on. I infer that they are leaving bare `Error` for user cases. I think the platform should generally follow this lead; that is, the DOM should leave bare `Error`s to the user, and throw `DOMError`s or `TypeError`s or `RangeError`s for its own errors. To answer your more general question, authors are strongly discouraged from ever throwing anything that is not `instanceof Error`, see e.g. Guillermo Rauch's [A String is not an Error](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/). Also, the `name` property is generally the same across all instances of a particular error type, i.e. ```js errInstance.name === errInstance.constructor.name === errInstance.constructor.prototype.name === Object.getPrototypeOf(errInstance).name ``` (You can verify this for all the built-in ES5 errors.) Usually a `code` property is used for more specific information, from what I've seen. But yes, that has to be added manually with a bit of awkwardness, i.e. ```js const e = new DOMError(The message); e.code = TimeoutError; throw e; ``` Note that (new DOMError) instanceof Error; returns false. So the DOM does do the strongly discouraged thing. Is this ok or bad? Also, the DOM does not create a new class for each different value of .name. I.e. you can get a DOMError whose .name is NetworkError or AbortError. DOMError even has a constructor which allows setting .name to anything: new DOMError(name, message); In fact, there are no defined situations where the DOM creates DOMError objects whose .name is DOMError. Again, is this ok or is it bad practice? / Jonas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Creating your own errors
On Wed, Jul 10, 2013 at 3:49 PM, Erik Arvidsson erik.arvids...@gmail.com wrote: In Blink DOMException also have a stack property assert(stack in ex); Since they are just Error objects -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Creating your own errors
From: Jonas Sicking [jo...@sicking.cc] Note that ```js (new DOMError) instanceof Error; ``` returns false. So the DOM does do the strongly discouraged thing. Is this ok or bad? This is horrible! I had no idea! It should definitely derive from `Error`. Also, the DOM does not create a new class for each different value of .name. I.e. you can get a DOMError whose .name is NetworkError or AbortError. In fact, there are no defined situations where the DOM creates DOMError objects whose .name is DOMError. Again, is this ok or is it bad practice? This seems bad, although in practice not nearly as bad as the broken inheritance. (I guess because getting `name` correct is subtle; many user-space custom errors do not do so, so you can't always rely on it.) In an ideal world, I think you could do a few things: - A hierarchy, where e.g. `NetworkError` derives from `DOMError` derives from `Error`, and all have the correct `name` properties. - A reform, where `DOMError` derives from `Error` and both have the correct `name` properties; but, specific `DOMError` instances thrown by certain APIs can have a `code` property containing strings like `NetworkError`. DOMError even has a constructor which allows setting .name to anything: new DOMError(name, message); This seems quite bad: error constructors always (in ES)/almost always (in user space) take `message` as their first parameter, with other parameters beyond that being introduced by various user-space errors. ___ 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: thisArg in Array#find and Array#findIndex
It's not too late for find and findIndex, and they do fit the pattern. Is an options object as the last parameter out of the question? For find(), I’d love to have the option to specify a result other than `undefined` if the value isn’t found. Such a result would be an option, as would be `thisValue`. -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
Also, who needs to find undefined? It's a good notFound default value but I go further: it is the only notFound you're gonna need. IOW, YAGNI. /be Brendan Eich wrote: Axel Rauschmayer wrote: It's not too late for find and findIndex, and they do fit the pattern. Is an options object as the last parameter out of the question? For find(), I’d love to have the option to specify a result other than `undefined` if the value isn’t found. Such a result would be an option, as would be `thisValue`. If there's a pigeon-hole problem where thisArg and notFound fight, then maybe -- but there's another object allocation, and we're not really following any existing pattern at this point. Option objects are common but not in built-in APIs, esp. not in the Array generic methods. /be ___ 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: Creating your own errors
I am not sure where this conversation ended up so I hope I am not repeating already said stuff but you can always create constructors that inherits from Error and set the name. ```javascript function CustomError(message) { this.message = message || ''; } CustomError.prototype = new Error; CustomError.prototype.name = CustomError.name; CustomError.prototype.constructor = CustomError; // whenever you need throw new CustomError; ``` That will be highlighted in most consoles as red **CustomError** instance you can inspect to read the message. Hope this helped anyhow. Best Regards On Wed, Jul 10, 2013 at 9:23 AM, Jonas Sicking jo...@sicking.cc wrote: Hi all, What is the current expected way for an author to throw a custom errors? You obviously could do something like: throw { reason: TimeoutError }; or throw TimeoutError; However that makes it very hard for anyone receiving an exception to inspect what it is. I.e. you'd first have to check what type of value it is, i.e. if it's a string, something that's instanceof Error, or something with just custom properties. Instead you can do throw new Error; However, as I understand it, that doesn't let you pass machine-readable information in the error. You can only pass a message which is intended for human consumption. I.e. something like: throw new Error(operation took too long and timed out.); Yet another alternative is to do let e = new Error; e.name = TimeoutError; throw e; This is a little bit more code than expected though. A shorter alternative that is somewhat compatible with Error is throw { name: TimeoutError }; However this means that 'instanceof Error' returns false, which could mean that code is forced to check which properties are set. The reason I'm asking is that the DOM has invented a completely new interface, DOMError. This seems pretty heavy-handed and yet another instance of the DOM doing it in its own way rather than using existing ES functionality. I'd like for the DOM to mimic what we expect authors to do. It's just not obvious to me what authors are expected to do if they want to throw a machine readable error. I.e. one that allows code to catch the error and handle it. / Jonas ___ 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: Creating your own errors
```javascript function CustomError(message) { this.message = message || ''; } CustomError.prototype = new Error; // whenever you need throw new CustomError; ``` At best, this will not preserve the stack trace property, at worse this will lead to a bad one. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Creating your own errors
```javascript function CustomError(message) { this.message = message || ''; } CustomError.prototype = new Error; // whenever you need throw new CustomError; ``` At best, this will not preserve the stack trace property, at worse this will lead to a bad one. Because the location info will be that of the new Error? One could try this instead, which seems to work for me: throw { __proto__ : new Error(), reason: Monday } Claus ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
Le 10 juil. 2013 à 19:05, David Bruant bruan...@gmail.com a écrit : Who needs this particular consistency anyway? IMO, when designing an API, the right question is not: Why would I be consistent in that particular case?, but: Why would I be inconsistent in that particular case? You didn't give a good reason for breaking consistency. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: thisArg in Array#find and Array#findIndex
On Wed, Jul 10, 2013 at 3:13 PM, Claude Pache claude.pa...@gmail.com wrote: Le 10 juil. 2013 à 19:05, David Bruant bruan...@gmail.com a écrit : Who needs this particular consistency anyway? IMO, when designing an API, the right question is not: Why would I be consistent in that particular case?, but: Why would I be inconsistent in that particular case? You didn't give a good reason for breaking consistency. +1. Anyone who's had to suffer through PHP knows the pain of APIs that didn't care about being consistent. There are sometimes good reasons to not be consistent, but there's always a strong mental-tax reason for maintaining it. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Creating your own errors
Because the location info will be that of the new Error? One could try this instead, which seems to work for me: throw { __proto__ : new Error(), reason: Monday } That one seems to be working (except in IE11 since IE didn't support __proto__ prior to that). That somehow surprises me that browser unwrap the prototype chain but they seem to do in this case. ___ 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: Creating your own errors
yep, I thought it was about having meaningful red errors with a proper name in console. The stack can be addressed passing the `new CustomError (new Error('message'))` using error as argument, not big deal ... abusing __proto__ for this seems like the wrong answer to a concrete problem On Wed, Jul 10, 2013 at 2:53 PM, François REMY francois.remy@outlook.com wrote: ```javascript function CustomError(message) { this.message = message || ''; } CustomError.prototype = new Error; // whenever you need throw new CustomError; ``` At best, this will not preserve the stack trace property, at worse this will lead to a bad one. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: more numeric constants please (especially EPSILON)
On Jul 9, 2013, at 6:09 PM, Mark S. Miller wrote: FWIW, we include 2**53 as in the contiguous range of exactly representable natural numbers. https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#492 What you want is: the continuous range of exactly and unambiguously representable natural numbers Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
[module] dynaimic namespace/scope
Consider this simple construct: module test { export function setVar() { gvar = GVAR; // note 'gvar' is not defined in the module } export function getVar() { return gvar; } } module Test from test; Having this in place I am calling Test.setVar(); Question: where is that 'gvar' created? Possible case: a. {{globalns}}.gvar == GVAR // so in global namespace or b. {{globalns}}.Test.gvar == GVAR // in module namepspace In other words does the module establish its own dynaimic namespace/scope? If that behavior is spec'ed already I'll appreciate for the link. -- Andrew Fedoniouk. http://terrainformatica.com ___ 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: Creating your own errors
What's wrong with: ```javascript throw new CustomError('message') function CustomError(message /* accept any custom arguments here */) { Error.call(this, message) this.name = 'CustomError' /** * add any custom error info here */ } CustomError.prototype = Object.create(Error) CustomError.prototype.constructor = CustomError ``` In ES6 land this becomes: ```javascript throw new CustomError('message') class CustomError extends Error { constructor (message /* accept any custom arguments here */) { super(message) this.name = 'CustomError' /** * add any custom error info here */ } } ``` Doesn't that seem like an obvious enough solution? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 7:15 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: Consider this simple construct: module test { export function setVar() { gvar = GVAR; // note 'gvar' is not defined in the module } export function getVar() { return gvar; } } module Test from test; Having this in place I am calling Test.setVar(); Question: where is that 'gvar' created? Possible case: a. {{globalns}}.gvar == GVAR // so in global namespace or b. {{globalns}}.Test.gvar == GVAR // in module namepspace In other words does the module establish its own dynaimic namespace/scope? If that behavior is spec'ed already I'll appreciate for the link. It gets created nowhere, because the body of a module is implicitly strict, so the above code produces a Reference Error. Rick ___ 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: Creating your own errors
wrong at least two things for the non ES6 version 1. `Error.call(this, message)` does not do what you think it should do 2. `CustomError.prototype = Object.create(Error)` has a typo, you meant ` Object.create(Error.prototype)` In the ES6 version, I am not sure about constructors and classes, but name should be inherited or the console won't even look for it as own property so it should be ```javascript class CustomError extends Error { name = 'CustomError' constructor (message /* accept any custom arguments here */) { super(message) } } ``` only in case CustomError won't have already a `name` property as it is for ES3=ES5 constructors. :-) On Wed, Jul 10, 2013 at 4:22 PM, Forbes Lindesay for...@lindesay.co.ukwrote: What's wrong with: ```javascript throw new CustomError('message') function CustomError(message /* accept any custom arguments here */) { Error.call(this, message) this.name = 'CustomError' /** * add any custom error info here */ } CustomError.prototype = Object.create(Error) CustomError.prototype.constructor = CustomError ``` In ES6 land this becomes: ```javascript throw new CustomError('message') class CustomError extends Error { constructor (message /* accept any custom arguments here */) { super(message) this.name = 'CustomError' /** * add any custom error info here */ } } ``` Doesn't that seem like an obvious enough solution? ___ 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: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Sam ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 4:24 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Jul 10, 2013 at 7:15 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: Consider this simple construct: module test { export function setVar() { gvar = GVAR; // note 'gvar' is not defined in the module } export function getVar() { return gvar; } } module Test from test; Having this in place I am calling Test.setVar(); Question: where is that 'gvar' created? Possible case: a. {{globalns}}.gvar == GVAR // so in global namespace or b. {{globalns}}.Test.gvar == GVAR // in module namepspace In other words does the module establish its own dynaimic namespace/scope? If that behavior is spec'ed already I'll appreciate for the link. It gets created nowhere, because the body of a module is implicitly strict, so the above code produces a Reference Error. Rick Thanks Rick. And I suspect there is no way to reclaim that strictness, right? Asking because it could be useful in cases like this : module Safe { not use strict; export function eval(str) { return std.eval(str); } } And so if I will call: Safe.eval(gvar=666) ; it will not pollute global namespace. -- Andrew Fedoniouk. http://terrainformatica.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 4:40 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Sam Sam, I don't think that generation of static check/error is possible in this case. {{globalns}}.gvar can be created after the module gets loaded/compiled but before Test.setVar() invocation. -- Andrew Fedoniouk. http://terrainformatica.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Creating your own errors
On Jul 10, 2013, at 4:32 PM, Andrea Giammarchi wrote: wrong at least two things for the non ES6 version 1. `Error.call(this, message)` does not do what you think it should do 2. `CustomError.prototype = Object.create(Error)` has a typo, you meant `Object.create(Error.prototype)` In the ES6 version, I am not sure about constructors and classes, but name should be inherited or the console won't even look for it as own property so it should be ```javascript class CustomError extends Error { name = 'CustomError' constructor (message /* accept any custom arguments here */) { super(message) } } ``` only in case CustomError won't have already a `name` property as it is for ES3=ES5 constructors. You need to say: class CustomError extends Error { get name() {return 'CustomError'} constructor (message /* accept any custom arguments here */) { super(message) } } or alternatively: class CustomError extends Error { constructor (message /* accept any custom arguments here */) { super(message) } } CustomError.prototype.name = 'CustomError'; This is one of the rare places where it is inconvenient that class declarations don't provide syntax for defining data properties on the prototype. Forbes class version should be fine if you don't mind each CustomError instance having an own 'name' data property. Allen :-) On Wed, Jul 10, 2013 at 4:22 PM, Forbes Lindesay for...@lindesay.co.uk wrote: What's wrong with: ```javascript throw new CustomError('message') function CustomError(message /* accept any custom arguments here */) { Error.call(this, message) this.name = 'CustomError' /** * add any custom error info here */ } CustomError.prototype = Object.create(Error) CustomError.prototype.constructor = CustomError ``` In ES6 land this becomes: ```javascript throw new CustomError('message') class CustomError extends Error { constructor (message /* accept any custom arguments here */) { super(message) this.name = 'CustomError' /** * add any custom error info here */ } } ``` Doesn't that seem like an obvious enough solution? ___ 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: [module] dynaimic namespace/scope
On Jul 10, 2013, at 4:40 PM, Sam Tobin-Hochstadt wrote: On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Ah, do you mean this is a link time check? It isn't a regular early error situations because gvar could be a dynamically added property on the global object. Not sure what your current semantics are, but I thought it was established a long time ago that modules needed free references in order to deal with global object properties. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
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: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 7:40 PM, Sam Tobin-Hochstadt sa...@ccs.neu.eduwrote: On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Thanks for the correction, I based my response on Appendix C of ES5.1, which of course doesn't know anything about module bodies ;) Rick Sam ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 7:49 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: On Wed, Jul 10, 2013 at 4:24 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Jul 10, 2013 at 7:15 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: Consider this simple construct: module test { export function setVar() { gvar = GVAR; // note 'gvar' is not defined in the module } export function getVar() { return gvar; } } module Test from test; Having this in place I am calling Test.setVar(); Question: where is that 'gvar' created? Possible case: a. {{globalns}}.gvar == GVAR // so in global namespace or b. {{globalns}}.Test.gvar == GVAR // in module namepspace In other words does the module establish its own dynaimic namespace/scope? If that behavior is spec'ed already I'll appreciate for the link. It gets created nowhere, because the body of a module is implicitly strict, so the above code produces a Reference Error. Rick Thanks Rick. And I suspect there is no way to reclaim that strictness, right? One of the goals of ES6 (and all future versions) is to promote strict mode to become the only or at least preferred mode. Wherever reasonably possible new syntactic forms, such as class and module, will be designed as strict by default, with no opt out. Rick Asking because it could be useful in cases like this : module Safe { not use strict; export function eval(str) { return std.eval(str); } } And so if I will call: Safe.eval(gvar=666) ; it will not pollute global namespace. -- Andrew Fedoniouk. http://terrainformatica.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
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: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 8:02 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jul 10, 2013, at 4:40 PM, Sam Tobin-Hochstadt wrote: On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Ah, do you mean this is a link time check? It isn't a regular early error situations because gvar could be a dynamically added property on the global object. Not sure what your current semantics are, but I thought it was established a long time ago that modules needed free references in order to deal with global object properties. No, that's not what I mean. The semantics we've discussed multiple times are that modules are compiled with respect to the global object at compilation time, and free variables at that point (ie, compilation time) are a static error. This is implicit in the discussion here: http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders (see the global objects section) and explicit in some of the notes, I'm sure. Sam ___ 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 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: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 9:14 PM, Mark S. Miller erig...@google.com wrote: On Wed, Jul 10, 2013 at 6:06 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: No, that's not what I mean. The semantics we've discussed multiple times are that modules are compiled with respect to the global object at compilation time, and free variables at that point (ie, compilation time) are a static error. This is implicit in the discussion here: http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders (see the global objects section) and explicit in some of the notes, I'm sure. Yes, that is what I remember. A case I no longer remember though: What if a property is deleted from the global object after the module is compiled? This is still a dynamic error (a reference error, like Rick said), which I'm not really happy about. The only alternative I've thought of is changing such properties to non-configurable at compilation time of the module that references them. But that's a weirdly non-local effect, and is probably worse than the disease. Sam ___ 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 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
Re: [module] dynaimic namespace/scope
On Jul 10, 2013, at 6:06 PM, Sam Tobin-Hochstadt wrote: On Wed, Jul 10, 2013 at 8:02 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jul 10, 2013, at 4:40 PM, Sam Tobin-Hochstadt wrote: On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Ah, do you mean this is a link time check? It isn't a regular early error situations because gvar could be a dynamically added property on the global object. Not sure what your current semantics are, but I thought it was established a long time ago that modules needed free references in order to deal with global object properties. No, that's not what I mean. The semantics we've discussed multiple times are that modules are compiled with respect to the global object at compilation time, and free variables at that point (ie, compilation time) are a static error. This is implicit in the discussion here: http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders (see the global objects section) and explicit in some of the notes, I'm sure. Hmm..has this been thought about in light of the decision to structure the global scope into to environment records (a object ER for the global object (and var/function declarations) and a declarative ER for let/consts, etc.) Also, aren't free references (to globals) quite similar to imports that can't be satisfied at link time. I can imagine that such free variables could be treated as implicit imports from the global scope and resolved at the same time and in a similar manner to explicit imports. There is something that seems more satisfying about all linking errors occurring at the same time rather than some occurring as early errors and others occurring as linking errors. Finally, are there races between an async script block that define modules and subsequent html elements with id attributes. If such a module uses a free global reference to access the DOM node with the matching id won't the occurrence of the compile time error depend upon whether or not the the async script loader gets around to compiler the the script before the html parser gets to the element with the id? Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [module] dynaimic namespace/scope
On Wed, Jul 10, 2013 at 10:12 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jul 10, 2013, at 6:06 PM, Sam Tobin-Hochstadt wrote: On Wed, Jul 10, 2013 at 8:02 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jul 10, 2013, at 4:40 PM, Sam Tobin-Hochstadt wrote: On Wed, Jul 10, 2013 at 7:24 PM, Rick Waldron waldron.r...@gmail.com wrote: It gets created nowhere, This is right. because the body of a module is implicitly strict, And this is right. so the above code produces a Reference Error. But this is incorrect, because modules check that their bodies don't have free variables, so the above code has a _static_ error. Ah, do you mean this is a link time check? It isn't a regular early error situations because gvar could be a dynamically added property on the global object. Not sure what your current semantics are, but I thought it was established a long time ago that modules needed free references in order to deal with global object properties. No, that's not what I mean. The semantics we've discussed multiple times are that modules are compiled with respect to the global object at compilation time, and free variables at that point (ie, compilation time) are a static error. This is implicit in the discussion here: http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders (see the global objects section) and explicit in some of the notes, I'm sure. Hmm..has this been thought about in light of the decision to structure the global scope into to environment records (a object ER for the global object (and var/function declarations) and a declarative ER for let/consts, etc.) Yes, we've thought about this. I don't think it changes much, other than to make the case Mark worried about less prevalent. Also, aren't free references (to globals) quite similar to imports that can't be satisfied at link time. I can imagine that such free variables could be treated as implicit imports from the global scope and resolved at the same time and in a similar manner to explicit imports. There is something that seems more satisfying about all linking errors occurring at the same time rather than some occurring as early errors and others occurring as linking errors. I believe that this may end up being a distinction without a difference. When a module is compiled, the names it imports from other modules must be present, or there's a static error. There's no case where a module is compiled-but-not-linked, and thus I don't think the difference would be observable. Finally, are there races between an async script block that define modules and subsequent html elements with id attributes. If such a module uses a free global reference to access the DOM node with the matching id won't the occurrence of the compile time error depend upon whether or not the the async script loader gets around to compiler the the script before the html parser gets to the element with the id? There are certainly races here, just the way that: script async x /script races with such dynamic DOM insertions. Sam ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Creating your own errors
On Jul 10, 2013 3:49 PM, Erik Arvidsson erik.arvids...@gmail.com wrote: Jonas, DOM never throws DOMError. DOMErrors are used for other error mechanisms, such as callbacks. [1] Indeed. But this is one of the things I'm trying to fix. It seems very silly that the DOM defines two classes of error objects. Neither of which are following the patterns used by ES. / Jonas The DOM spec does however throw DOMException objects [2]. These are instanceof Error (see WebIDL [3]) var ex; try { document.appendChild(document); } catch (e) { ex = e; } assert(ex instanceof Error); assert(ex.contructor === DOMException); assert(ex.name === 'HierarchyRequestError'); In Blink DOMException also have a stack property assert(stack in ex); [1] http://dom.spec.whatwg.org/#interface-domerror [2] http://dom.spec.whatwg.org/#exception-domexception [3] http://dev.w3.org/2006/webapi/WebIDL/#es-exception-interface-prototype-object On Wed, Jul 10, 2013 at 3:02 PM, Jonas Sicking jo...@sicking.cc wrote: On Wed, Jul 10, 2013 at 12:52 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Woah, François, that seems pretty overcomplicated; why not replace everything inside the constructor with `this.message = message`? It has the same effect in the browsers I've seen. (Also don't forget `SomeError.prototype.constructor = SomeError`.) Anyway, to Jonas's point: I think `DOMError` is actually pretty OK. One thing I noticed is that the ES5 spec (and presumably ES6, although I haven't checked) is careful to never throw simple `Error` objects, but instead `TypeError`s or `RangeError`s or so on. I infer that they are leaving bare `Error` for user cases. I think the platform should generally follow this lead; that is, the DOM should leave bare `Error`s to the user, and throw `DOMError`s or `TypeError`s or `RangeError`s for its own errors. To answer your more general question, authors are strongly discouraged from ever throwing anything that is not `instanceof Error`, see e.g. Guillermo Rauch's [A String is not an Error]( http://www.devthought.com/2011/12/22/a-string-is-not-an-error/). Also, the `name` property is generally the same across all instances of a particular error type, i.e. ```js errInstance.name === errInstance.constructor.name === errInstance.constructor.prototype.name === Object.getPrototypeOf(errInstance).name ``` (You can verify this for all the built-in ES5 errors.) Usually a `code` property is used for more specific information, from what I've seen. But yes, that has to be added manually with a bit of awkwardness, i.e. ```js const e = new DOMError(The message); e.code = TimeoutError; throw e; ``` Note that (new DOMError) instanceof Error; returns false. So the DOM does do the strongly discouraged thing. Is this ok or bad? Also, the DOM does not create a new class for each different value of .name. I.e. you can get a DOMError whose .name is NetworkError or AbortError. DOMError even has a constructor which allows setting .name to anything: new DOMError(name, message); In fact, there are no defined situations where the DOM creates DOMError objects whose .name is DOMError. Again, is this ok or is it bad practice? / Jonas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Creating your own errors
oh well ... I've missed the part when you guys decided that inherited defaults are useless as properties ... :-/ as you said, inconvenient, and not only this case ... also good to know ^_^ On Wed, Jul 10, 2013 at 4:56 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Jul 10, 2013, at 4:32 PM, Andrea Giammarchi wrote: wrong at least two things for the non ES6 version 1. `Error.call(this, message)` does not do what you think it should do 2. `CustomError.prototype = Object.create(Error)` has a typo, you meant ` Object.create(Error.prototype)` In the ES6 version, I am not sure about constructors and classes, but name should be inherited or the console won't even look for it as own property so it should be ```javascript class CustomError extends Error { name = 'CustomError' constructor (message /* accept any custom arguments here */) { super(message) } } ``` only in case CustomError won't have already a `name` property as it is for ES3=ES5 constructors. You need to say: class CustomError extends Error { get name() {return 'CustomError'} constructor (message /* accept any custom arguments here */) { super(message) } } or alternatively: class CustomError extends Error { constructor (message /* accept any custom arguments here */) { super(message) } } CustomError.prototype.name = 'CustomError'; This is one of the rare places where it is inconvenient that class declarations don't provide syntax for defining data properties on the prototype. Forbes class version should be fine if you don't mind each CustomError instance having an own 'name' data property. Allen :-) On Wed, Jul 10, 2013 at 4:22 PM, Forbes Lindesay for...@lindesay.co.ukwrote: What's wrong with: ```javascript throw new CustomError('message') function CustomError(message /* accept any custom arguments here */) { Error.call(this, message) this.name = 'CustomError' /** * add any custom error info here */ } CustomError.prototype = Object.create(Error) CustomError.prototype.constructor = CustomError ``` In ES6 land this becomes: ```javascript throw new CustomError('message') class CustomError extends Error { constructor (message /* accept any custom arguments here */) { super(message) this.name = 'CustomError' /** * add any custom error info here */ } } ``` Doesn't that seem like an obvious enough solution? ___ 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
[syntax] arrow function notation is too greedy
I see [1] that arrow function syntax got specification state. The problem with this construction: it's the only feature in ES syntax so far that requires compiler to use full AST implementation at compilation phase. Consider this: var val1 = 1; var val2 = 2; var sum1 = (val1, val2) + 1; // integer var sum2 = (val1, val2) = val1 + val2 ; // function var sum3 = (val1, true) ; // true As comma is a valid operator in ES than to generate code for the expression (val1, val2) is only possible when next token past ')' is seen. That requires as I said full blown AST analysis - list in '(' ')' parenthesis shall be parsed and stored. Only next token triggers how that list will be interpreted. So far almost all other syntax features in ES can be parsed with single token look ahead. That makes possible quite fast source- bytecode translation schema that makes great sense for the embeddable languages like ES. Is that arrow syntax still debatable? Asking because Ruby-ish syntax [2] is significantly better in this respect. And in TIScript [3] I am using similar approach but with ':' symbol: ':' param-list ':' expresion ':' param-list '{' statement-list '}' Example, descending sorting: arr.sort( :a,b: a - b ); Too late? [1] http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax [2] http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival [3] http://www.codeproject.com/Articles/33662/TIScript-language-a-gentle-extension-of-JavaScript -- Andrew Fedoniouk. http://terrainformatica.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [syntax] arrow function notation is too greedy
On Jul 10, 2013, at 9:39 PM, Andrew Fedoniouk wrote: I see [1] that arrow function syntax got specification state. so, you should probably look at the relevant parts of the draft specification http://people.mozilla.org/~jorendorff/es6-draft.html#sec-5.1.4 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-11.1 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-13.2 The problem with this construction: it's the only feature in ES syntax so far that no, it also occurs between object literals and destructuring assignment object patterns. requires compiler to use full AST implementation at compilation phase. you don't necessarily have to built a full AST. In some cases you will need to at least do multiple parses of the same text. Consider this: var val1 = 1; var val2 = 2; var sum1 = (val1, val2) + 1; // integer var sum2 = (val1, val2) = val1 + val2 ; // function var sum3 = (val1, true) ; // true As comma is a valid operator in ES than to generate code for the expression (val1, val2) is only possible when next token past ')' is seen. That requires as I said full blown AST analysis - list in '(' ')' parenthesis shall be parsed and stored. Only next token triggers how that list will be interpreted. So far almost all other syntax features in ES can be parsed with single token look ahead. That makes possible quite fast source- bytecode translation schema that makes great sense for the embeddable languages like ES. Is that arrow syntax still debatable? No really. This was known when the arrow syntax was choses. Asking because Ruby-ish syntax [2] is significantly better in this respect. And in TIScript [3] I am using similar approach but with ':' symbol: ':' param-list ':' expresion ':' param-list '{' statement-list '}' Example, descending sorting: arr.sort( :a,b: a - b ); Too late? Yes, but primarily in the sense that such issues were already considered. Allen [1] http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax [2] http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival [3] http://www.codeproject.com/Articles/33662/TIScript-language-a-gentle-extension-of-JavaScript -- Andrew Fedoniouk. http://terrainformatica.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