Re: ES6 doesn't need opt-in
On Sat, Jan 7, 2012 at 11:05 PM, Brendan Eich bren...@mozilla.com wrote: [...] so are we really just arguing about names or labels? If so, great -- those are important to get right. [...] While I agree it's important to get labels right, if that is indeed the only remaining issue here, that's wonderful. I'm mellow about labels others find attractive, as long as we agree on observables. I think there is an observable difference between what I'm advocating and what Allen is. Not as sure about your position. But it is possible I'm misunderstanding something and there is no observable difference. At this point, we've narrowed the issue enough that we should probably postpone this final step till we can engage verbally with lower latency -- at the upcoming meeting. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 doesn't need opt-in
On Sun, Jan 8, 2012 at 8:15 AM, Brendan Eich bren...@mozilla.com wrote: On Jan 8, 2012, at 8:10 AM, Mark S. Miller wrote: On Sat, Jan 7, 2012 at 11:05 PM, Brendan Eich bren...@mozilla.com wrote: [...] so are we really just arguing about names or labels? If so, great -- those are important to get right. [...] While I agree it's important to get labels right, if that is indeed the only remaining issue here, that's wonderful. I'm mellow about labels others find attractive, as long as we agree on observables. I think there is an observable difference between what I'm advocating and what Allen is. Not as sure about your position. I think the only open issue is whether use strict; opts into completion reform and any other semantic change that does not have a syntactic trigger. I'm ok with trying completion reform as an extension to use strict; in ES5+ implementations, ASAP -- more than ok, really. It would help prove completion reform is non-breaking. That is an example of the kind of issue I am concerned about -- and it is much more than a terminology difference. Any other cleanups we do in ES6 --- that we believe to be practically backward compatible with ES5-strict practice but not with the normative spec nor with test262 --- would fall into the same category as completion reform. So the status of things like we imagine completion reform to be, whether or not completion reform itself is one of those, is something we need to resolve. The other change I hope fits into the same bucket is http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake. Right now, because of pressure from test262, we are in danger of having all browsers conform to this mistake, at which point it may be too late to fix it. Today, the diversity of actual browser behaviors means it is still possible to fix this mistake, much as the diversity of ways ES3 implementations were broken made it possible for ES5 to fix many mistakes. And there is one further issue I think is worth clearing up in email here. What do we expect to be the normative status of the state machine itself and of the ES5 spec, after ES6 becomes official, for a browser that claims to be standards compliant, including ES6 compliant? AFAICT, no one has commented on this specifically, and we may be reading different assumptions into Allen's proposal. What I am assuming Allen's proposal means is that the state machine would also be normative, and therefore those parts of the ES5 spec that are reachable from this state machine would remain normative as well. As I understand ECMA rules, it would be at least unusual for the earlier edition of the spec to remain normative even for systems claiming conformance to the later edition of the same spec. (same by spec number, i.e., 262). -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 doesn't need opt-in
On Jan 7, 2012, at 11:41 PM, Axel Rauschmayer wrote: Isn’t ES5.nonstrict the union of ES5.nonstrict-ES6-intersection and ES5.nonstrict-differs-from-ES6? If yes then ES5.nonstrict disappears and we might have a venn diagram intersecting ES5.nonstrict and ES6: ES5.nonstrict-only (=ES5.nonstrict-differs-from-ES6) ES5.nonstrict-ES6-intersection ES6-only (=ES6-differs-from-ES5.nonstrict) As Mark just wrote this depends on how we resolve some fine points (completion reform among them). This might be about to the question as to whether there should be a mode that combines ES6-differs-from-ES5.strict constructs with ES5.nonstrict. I don’t think there should be. Oh no, that's right out. We can't have 'let' be reserved conditionally without more complexity (we could just reserve it and see what breaks, but then that's not ES5-nonstrict is it :-P). /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 doesn't need opt-in
On Jan 8, 2012, at 8:28 AM, Mark S. Miller wrote: I'm ok with trying completion reform as an extension to use strict; in ES5+ implementations, ASAP -- more than ok, really. It would help prove completion reform is non-breaking. That is an example of the kind of issue I am concerned about -- and it is much more than a terminology difference. Any other cleanups we do in ES6 --- that we believe to be practically backward compatible with ES5-strict practice but not with the normative spec nor with test262 --- would fall into the same category as completion reform. So the status of things like we imagine completion reform to be, whether or not completion reform itself is one of those, is something we need to resolve. Yes. This is not easy to resolve by a-prior reasoning, though. We might just do nothing incompatible, but we could also probably get away with completion reform and your fixing-override-mistake change. Some experimentation in nightly and even longer-lived/used builds is required. The other change I hope fits into the same bucket is http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake. Right now, because of pressure from test262, we are in danger of having all browsers conform to this mistake, at which point it may be too late to fix it. Today, the diversity of actual browser behaviors means it is still possible to fix this mistake, much as the diversity of ways ES3 implementations were broken made it possible for ES5 to fix many mistakes. The [[CanPut]] check goes back to ES1, though. Recent-ish deviations in JSC and (because V8 was drafting off JSC) V8 don't nullify all that history. On the other hand, JSC and V8 are doing fine AFAIK. It's hard to make a real-world case where this matters, even with Object.create. And I see the ocap (not just SES) appeal of the fix. And there is one further issue I think is worth clearing up in email here. What do we expect to be the normative status of the state machine itself and of the ES5 spec, after ES6 becomes official, for a browser that claims to be standards compliant, including ES6 compliant? AFAICT, no one has commented on this specifically, and we may be reading different assumptions into Allen's proposal. What I am assuming Allen's proposal means is that the state machine would also be normative, and therefore those parts of the ES5 spec that are reachable from this state machine would remain normative as well. As I understand ECMA rules, it would be at least unusual for the earlier edition of the spec to remain normative even for systems claiming conformance to the later edition of the same spec. (same by spec number, i.e., 262). I wrote in a previous reply that we aren't preserving ES5 as a spec referenced from ES6. ES6 will be self-contained. So I still don't grok your concern here. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
On Thu, Jan 5, 2012 at 11:47 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: ... P.S. is it really just me that see the problem with current bind ? On Fri, Jan 6, 2012 at 2:22 AM, Brendan Eich bren...@mozilla.com wrote: On Jan 5, 2012, at 4:47 PM, Andrea Giammarchi wrote: Right now the lack of memoization is not a burning issue, from what I hear. You've raised it, I think for the first time on es-discuss. /be Since I agree with Andrea that the .bind() is a problem and since Brendan does not, I want to restate Andrea's case based on my experience. The ingredients for this problem are exactly the ones around when bind() was invented: DOM event registration and JS methods. The event registration 1) accepts a function, 2) requires explicit cleanup: window.addEventListener('load', boundOnLoad, false); ... window.removeEventListener('load', boundOnLoad, false); The JS method 1) must be bound to the correct object 2) be reference-able for the removeEventListener. This combination prevents simple inline functions so commonly used by JS devs from being applied to DOM event registration, a very common use of inline functions. If you use an inline function without bind(), then it will not have the correct object binding; if you use an inline function with bind(), then it will not be reference-able for the remove. Therefore you must use a reference to a bound function as the handler and it must be a property of an object or a scope you close over. That is why our code is now littered with: baz.boundOnLoad = baz.onLoad.bind(baz); // bah, JS voodoo In my code I now have a function _bindListeners() called from initialize() where I list all of this goop. The tedium is similar to reference counting. Note also my recent thread about anonymous methods, ie replacing boundOnLoad with imaginary this.function(event) {...}; I was prompted to float this idea because it is another approach to the above problem. Yet another approach would mark methods as bound at declaration: this.onLoad = function(event) {...}.bind(this); This approach (and other postfix solutions) are hard to follow since the ... pushes the salient info far from the name. (Plus this is a trap, you have to be careful not to use it in literals). I don't know if Andrea's solution is good or not, but I want to put another vote for |this| is a problem. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
On Jan 8, 2012, at 10:47 AM, John J Barton wrote: That is why our code is now littered with: BTW, which our code? baz.boundOnLoad = baz.onLoad.bind(baz); // bah, JS voodoo In my code I now have a function _bindListeners() called from initialize() where I list all of this goop. The tedium is similar to reference counting. The reference-counting tedium lies in the manual remove requirement. Reference counting has AddRef and Release (canonical COM names). It does not have a bind analogue. Indeed the bind requirement is more akin to requiring explicit handles or JNI-style roots for an exact GC. But we digress :-P. Yet another approach would mark methods as bound at declaration: this.onLoad = function(event) {...}.bind(this); This approach (and other postfix solutions) are hard to follow since the ... pushes the salient info far from the name. (Plus this is a trap, you have to be careful not to use it in literals). Another way out is |this|-free code, which is trivial to arrange with single-window, window-level event handling. For multi-window or deeper-DOM receivers, you'll need var self = this in a closure that is memoized for removal. Others on this thread say they use the var that = this; style, so it's not as if everyone must use .bind. I don't know if Andrea's solution is good or not, but I want to put another vote for |this| is a problem. Mark made the case for avoiding a capability leak channel in .bind, and that's what is specified by ES5. That ship sailed. In generating a fresh function each time, it mirrored the de-facto standard based on PrototypeJS, which uses closures (also fresh for each evaluation and opaque to reflection). David Bruant keeps pointing out how ES5 library code can be used to polyfill a memoziing bind, and Mark observes surprising lack of leaks with a strong pre-ES6 emulation of WeakMap. These do not prove there is no problem to solve, on the contrary they allow a solution to be developed without serializing design through TC39 and pushing for premature standardization. When I replied that lack of memoization is not a burning issue, I was not pooh-poohing anyone's pain, simply noting that this issue (AFAICR) has not come up till now on es-discuss. In conjunction with the library solution that will be required in the field anyway (for all browsers until some future edition is widely implementend), this says to me that developers who need memoizing bind should build and popularize it, as Sam et al. did with PrototypeJS. Rather than push for incompatible or premature changes to the standard. If such a de-facto-standard better-bind is built, we can easily de-jure standardize it. If it isn't, that says something too: that not everyone solves the problems for which you rely on bind in the same way. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
On Sun, Jan 8, 2012 at 11:39 AM, Brendan Eich bren...@mozilla.com wrote: On Jan 8, 2012, at 10:47 AM, John J Barton wrote: That is why our code is now littered with: BTW, which our code? Mine, Andrea's, Hewitt's Firebug at least. I believe we have already lamented our limited ability to analyze JS code patterns statistically. ... Yet another approach would mark methods as bound at declaration: this.onLoad = function(event) {...}.bind(this); This approach (and other postfix solutions) are hard to follow since the ... pushes the salient info far from the name. (Plus this is a trap, you have to be careful not to use it in literals). Another way out is |this|-free code, which is trivial to arrange with single-window, window-level event handling. For multi-window or deeper-DOM receivers, you'll need var self = this in a closure that is memoized for removal. Others on this thread say they use the var that = this; style, so it's not as if everyone must use .bind. I've used var self and var that quite a lot. It's a hack, contributes to right marching, stutters reading, but anyway the topic is bind() and how it might be better. More important, I want my reply to highlight a different meta-issue you raise: the role of libraries in testing ideas. I don't know if Andrea's solution is good or not, but I want to put another vote for |this| is a problem. Mark made the case for avoiding a capability leak channel in .bind, (Mark's case relies on believing that secure JS is a goal that trumps usability; I hope too be converted to this belief soon). and that's what is specified by ES5. That ship sailed. In generating a fresh function each time, it mirrored the de-facto standard based on PrototypeJS, which uses closures (also fresh for each evaluation and opaque to reflection). David Bruant keeps pointing out how ES5 library code can be used to polyfill a memoziing bind, and Mark observes surprising lack of leaks with a strong pre-ES6 emulation of WeakMap. These do not prove there is no problem to solve, on the contrary they allow a solution to be developed without serializing design through TC39 and pushing for premature standardization. When I replied that lack of memoization is not a burning issue, I was not pooh-poohing anyone's pain, simply noting that this issue (AFAICR) has not come up till now on es-discuss. In conjunction with the library solution that will be required in the field anyway (for all browsers until some future edition is widely implementend), this says to me that developers who need memoizing bind should build and popularize it, as Sam et al. did with PrototypeJS. Rather than push for incompatible or premature changes to the standard. If such a de-facto-standard better-bind is built, we can easily de-jure standardize it. If it isn't, that says something too: that not everyone solves the problems for which you rely on bind in the same way. Standardizing library uses make sense, except here is an example of a failure. The library version of bind() have exactly the problem we are discussing here! Why did we end up in this (hmm) bind? Somehow the standardization process did not anticipate this issue even though it was known? Firebug uses a library bind a lot, and we continually struggled with the memoization problem; we did not try to solve it in part because we hated Firebug's bind: it made debugging even more painful since it messes up the call stack. Using the ES bind() ends up not being a win, since I now have exactly the same problems. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
On Jan 8, 2012, at 12:29 PM, John J Barton wrote: On Sun, Jan 8, 2012 at 11:39 AM, Brendan Eich bren...@mozilla.com wrote: On Jan 8, 2012, at 10:47 AM, John J Barton wrote: That is why our code is now littered with: BTW, which our code? Mine, Andrea's, Hewitt's Firebug at least. Thanks, I see what you mean in Firebug. I believe we have already lamented our limited ability to analyze JS code patterns statistically. What does that have to do with betterBind? Any purely library (API) solution would be equally refractory to analysis. I've used var self and var that quite a lot. It's a hack, contributes to right marching, stutters reading, but anyway the topic is bind() and how it might be better. I'm not selling you on var self = this;, just pointing out the alternative used by enough people that standardizing a memoizing bind has not risen to TC39's agenda. Could be it should have, but the signal is not strong and well-tuned yet -- guess we're tuning now. More important, I want my reply to highlight a different meta-issue you raise: the role of libraries in testing ideas. Ok. I don't know if Andrea's solution is good or not, but I want to put another vote for |this| is a problem. Mark made the case for avoiding a capability leak channel in .bind, (Mark's case relies on believing that secure JS is a goal that trumps usability; I hope too be converted to this belief soon). Mark could remove any memoizingBind from SES, no doubt. For ES5, we were paving a cowpath as I noted (PrototypeJS etc.). Standardizing library uses make sense, except here is an example of a failure. The library version of bind() have exactly the problem we are discussing here! It wasn't considered a failure by many. Where were the requests in the ES3.1/4/5 era for memoizing bind? I may have missed one, so please point it out. Why did we end up in this (hmm) bind? Somehow the standardization process did not anticipate this issue even though it was known? Did you read what I wrote about Prototype? None of the bind/hitch/etc. library solutions memoize, if my memory serves. Sure, you could say lack of WeakMap or equivalent practically ensured that outcome, to avoid leaks. That's not totally clear now in light of Mark's emulated WeakMap not leaking in practice. Anyway, this is all water under the bridge. What about the future? My position is still do the library work and popularize. Even if you really need a fast-track ES.next solution, the library work must come first. Firebug uses a library bind a lot, and we continually struggled with the memoization problem; we did not try to solve it in part because we hated Firebug's bind: it made debugging even more painful since it messes up the call stack. Using the ES bind() ends up not being a win, since I now have exactly the same problems. I have a question: why is bind used so much in Firebug for event listeners, when the DOM guarantees to dispatch them with the event target bound to |this|? Way back in '95, I created event handlers but did not add bind (it had to be discovered later). But dynamic |this| binding combined with DOM event target-based listening and handling kept this properly bound. What has changed? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 doesn't need opt-in
On Sun, Jan 8, 2012 at 10:32 AM, Brendan Eich bren...@mozilla.com wrote: [...] All cool with the above. Thanks. I wrote in a previous reply that we aren't preserving ES5 as a spec referenced from ES6. ES6 will be self-contained. So I still don't grok your concern here. Sorry, I missed that. In that case, I still don't understand what your plan for ES6 is. Does the ES6 spec include the state machine and an updated form of the ES5-non-strict portions of the ES5 spec, as referenced by that state machine? If not, what standards document governs how a future standards compliant browser is supposed to handle code which has non opted into anything, neither implicitly-explicitly nor explicitly? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
On Sun, Jan 8, 2012 at 3:35 PM, Brendan Eich bren...@mozilla.com wrote: [...] That's not totally clear now in light of Mark's emulated WeakMap not leaking in practice. [...] That's a much stronger claim than I would be willing to make. My emulated WeakMaps leak much less that one would expect, and indeed less than I thought possible when I began the exercise. But the remaining extra leak is still significant for real uses. From http://code.google.com/p/es-lab/source/browse/trunk/src/ses/WeakMap.js : /** * This {@code WeakMap} emulation is observably equivalent to the * ES-Harmony WeakMap, but with leakier garbage collection properties. * * pAs with true WeakMaps, in this emulation, a key does not * retain maps indexed by that key and (crucially) a map does not * retain the keys it indexes. A map by itself also does not retain * the values associated with that map. * * pHowever, the values associated with a key in some map are * retained so long as that key is retained and those associations are * not overridden. For example, when used to support membranes, all * values exported from a given membrane will live for the lifetime * they would have had in the absence of an interposed membrane. Even * when the membrane is revoked, all objects that would have been * reachable in the absence of revocation will still be reachable, as * far as the GC can tell, even though they will no longer be relevant * to ongoing computation. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Fwd: Improving Function.prototype.bind
Sorry about the format mangling. Resending with simpler formatting which hopefully won't get mangled in transmission. -- Forwarded message -- From: Mark S. Miller erig...@google.com Date: Sun, Jan 8, 2012 at 5:05 PM Subject: Re: Improving Function.prototype.bind To: Brendan Eich bren...@mozilla.com Cc: John J Barton johnjbar...@johnjbarton.com, es-discuss es-discuss@mozilla.org On Sun, Jan 8, 2012 at 3:35 PM, Brendan Eich bren...@mozilla.com wrote: [...] That's not totally clear now in light of Mark's emulated WeakMap not leaking in practice. [...] That's a much stronger claim than I would be willing to make. My emulated WeakMaps leak much less that one would expect, and indeed less than I thought possible when I began the exercise. But the remaining extra leak is still significant for real uses. From http://code.google.com/p/es-lab/source/browse/trunk/src/ses/WeakMap.js : /** * This {@code WeakMap} emulation is observably equivalent to the * ES-Harmony WeakMap, but with leakier garbage collection properties. * * pAs with true WeakMaps, in this emulation, a key does not * retain maps indexed by that key and (crucially) a map does not * retain the keys it indexes. A map by itself also does not retain * the values associated with that map. * * pHowever, the values associated with a key in some map are * retained so long as that key is retained and those associations are * not overridden. For example, when used to support membranes, all * values exported from a given membrane will live for the lifetime * they would have had in the absence of an interposed membrane. Even * when the membrane is revoked, all objects that would have been * reachable in the absence of revocation will still be reachable, as * far as the GC can tell, even though they will no longer be relevant * to ongoing computation. -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
On Sun, Jan 8, 2012 at 3:35 PM, Brendan Eich bren...@mozilla.com wrote: Anyway, this is all water under the bridge. What about the future? My position is still do the library work and popularize. Even if you really need a fast-track ES.next solution, the library work must come first. I'm not asking for any fast-track; I think library-first makes a lot of sense. I am also asking What about the future?. Library work provides evidence of need and an example of progress. But every solution has trade-offs. Adopting a library solution is easy: it will have champions and evidence. Somehow we need to go around the loop (quickly) to find evidence of the downsides and more input to finding improvements. I think today ES has a lot of good contributors that can help. So a concrete suggestions: modify your stance on library first to ask for evidence of revision. Perhaps we can create a world where Master student projects build the pro/con cases for these smaller but critical language features. Make the goal less standardize libraries and more learn/revise/retry from libraries. Some how the bind()-like functions so critical to daily use need more attention. Firebug uses a library bind a lot, and we continually struggled with the memoization problem; we did not try to solve it in part because we hated Firebug's bind: it made debugging even more painful since it messes up the call stack. Using the ES bind() ends up not being a win, since I now have exactly the same problems. I have a question: why is bind used so much in Firebug for event listeners, when the DOM guarantees to dispatch them with the event target bound to |this|? Way back in '95, I created event handlers but did not add bind (it had to be discovered later). But dynamic |this| binding combined with DOM event target-based listening and handling kept this properly bound. What has changed? Sorry I don't know what you mean here. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Improving Function.prototype.bind
Just a bit of back story on Function#bind because I think it's good to know. Prototype's Function#bind was based on the 2004 post Object-Oriented Event Listening through Partial Application in JavaScript by Daniel Brockman: http://web.archive.org/web/20100901172230/http://brockman.se/2004/method-references/ There was no de-facto standard of Function#bind. ExtJS, PrototypeJS, MooTools, Dojo, and jQuery each had their own implementations. MooTools Function#bind used to be implemented like: function fn() { console.log([].slice.call(arguments)); } var f = fn.bind({}, ['a', 'b']); // notice an array of arguments f('c'); // ['a', 'b'] // ignored arguments passed to the bound function Ext's implementation is completely different: http://www.sencha.com/learn/legacy/Manual:Utilities:Function#createDelegate Even though Dojo and jQuery implementations don't extend Function.prototype they follow Prototype's implementation with the exception that they also allow passing a string instead of a function and jQuery adds a `guid` property to the bound function. http://dojotoolkit.org/api/dojo.hitch http://api.jquery.com/jQuery.proxy/#example-1 Prototype 1.7's Function#bind (which overwrites native bind too) isn't as ES5 compliant as it could be because its bound function doesn't behave correctly when called as part of a new expression. function Foo(a,b,c) { this.a = a; this.b = b; this.c = c; } var Bound = Foo.bind({}, 1, 2); var b = new Bound(3); console.log(Object.keys(b)); // [], but should be ['a', 'b', 'c'] console.log(b.c) // undefined, but should be 3 - JDD ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss