Re: [Proxies] Refactoring prototype climbing in the spec
2011/11/8 Allen Wirfs-Brock al...@wirfs-brock.com I don't think that [[GetP]] and [[PutP]] need to be internal methods In spec'ing this I think I would make them be abstract operations. Internal methods are extensions points that can be over-ridden on a per object basis. That is what [[Get]] and [[Put]] provides. GetP and SetP define fixed operations. I proposed [[GetP]] and [[SetP]] as internal methods because Proxies would inherit the built-in behavior for [[Get]] and [[Put]], but override the [[GetP]] and [[SetP]] operations. If [[GetP]] and [[SetP]] become abstract operations, won't they need to explicitly dispatch? Proxies could override [[Get]] and [[Put]], but that would require them to duplicate the Object [[Get]] and [[Put]] code. More generally, I think there should be a 1::1 correspondence between the internal methods in listed in ES5 Table 8 and fundamental proxy traps. I absolutely agree we should strive to achieve this. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
Le 09/11/2011 02:26, Andrew Paprocki a écrit : On Tue, Nov 8, 2011 at 6:36 PM, Brendan Eichbren...@mozilla.com wrote: Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study. I was curious so I did some grok-ing across my code sample and Object.keys() is barely used. The usage of the |for in| construct is 2 orders of magnitude larger than the usage of hasOwnProperty(), supporting the thought that no one really does it the right way. The MDN page for Object.keys does not talk about |this| being wrong in certain situations. If you could elaborate on that, it would be helpful to know. The |this| differs between the body of a for-in and the argument callback in the .forEach. Nothing to do with Object.keys. .forEach has a second optional argument which is the value to be used as |this| so that you don't have to do a .bind. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On 9 November 2011 00:16, Mark S. Miller erig...@google.com wrote: On Tue, Nov 8, 2011 at 12:50 PM, Andreas Rossberg rossb...@google.com wrote: On 8 November 2011 20:46, Mark S. Miller erig...@google.com wrote: Nevertheless, I see your point. Many defensive ES5 abstractions will be less defensive than this. If I understand you correctly, your point is specifically about the [[Call]] and [[Construct]] traps. Yes. Existing code has no reason to bother making functions non-extensible if all it does is calling them. Proxy.attach fundamentally breaks that (so far correct, AFAICT) assumption. I think we're agreeing on the operational point -- that much defensive code won't bother to freeze such functions. But for clarity, I must correct your no reason. The reason is one of the oldest software engineering best practices: Say What You Mean. Perhaps a clearer statement is Mean Only What You Say. The it in your above sentence presumes a non-local whole program analysis which violates this rule, and is in any case inapplicable to libraries. To keep what the program means in sync with what it seems to mean, we need to avoid introducing unexpressed communication channels. Or, put another way, unexpressed shared mutable locations. If Alice provides object C to both B and D, the only ways in which this should enable further communication between B and D (beyond that which they may have already had) should be according to the expressed behavior of C. For example, if the expressed behavior of C is completely stateless, then the fact that B and D both share a reference to C should not enable any additional communications/interaction/influence between B and D. These constraints are useful for much beyond security. If you wish to program in a mostly functional style, you'd like the deviations from functional style to only be where you've made a purposeful choice. When debugging, you need to figure out: How did the bad symptom happen? If you can bound the possible causes, by reasoning in terms of the program's intended behavior, your detective work is much easier. Agreed with everything you say. But I suppose there are two levels of concern: protecting your own abstractions, and not providing security loopholes that others can exploit to harm third parties. Given how hostile JS is towards encouraging the latter, I would expect that a significant amount of code exists that only cares about the former, which I think is a valid concern on its own. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [Proxies] Refactoring prototype climbing in the spec
2011/11/8 Allen Wirfs-Brock al...@wirfs-brock.com On Nov 8, 2011, at 7:33 AM, Andreas Rossberg wrote: But I have a follow-up request. :) Regarding redundant trap calls with proxies there is another, more pervasive problem with the current spec: in lots of places it first calls [[HasProperty]] and then [[Get]]. With proxies, this always implies two trap calls, which seems wasteful. Would it be possible to refactor that, too? Seems more difficult, because we would need to enable [[Get]] (and hence the get trap) to signal lookup failure. (Too bad that we cannot reuse `undefined' for it.) But I think the current situation isn't satisfactory. I agree, the current specification style is fine when we are dealing with side-effectly free internal operations but as soon as they are reified they become problematic and a performance issue. Is the situation really that problematic? Skimming the ES5.1 spec for [[HasProperty]], I encounter calls in the following places: - ToPropertyDescriptor conversion (only triggers proxy code via Object.defineProperty(obj, name, aProxyAsDescriptor) and Object.defineProperties). - lots of methods on Array.prototype (map, forEach, filter, some, reduce, reduceRight, reverse, splice, indexOf, lastIndexOf, every, shift, slice, sort, unshift): the only way in which these trigger proxy code is when |this| is a proxy, i.e. when they are called as Array.prototype.theMethod.call(aProxy). (calling aProxy.theMethod triggers the proxy's get trap) - Array.prototype.concat: [[HasProperty]] is called on a built-in Array only. - 10.2.1.2 Object environment records uses [[HasProperty]] in a number of places. Isn't this needed only for |with|, so only triggered by |with (aProxy) { ... }|? Since ES.next builds on ES5/strict, this doesn't seem to carry much weight. - The in operator: only calls [[HasProperty]], not followed by a call to [[Get]] (so it's not an instance of the conditional [[Get]] pattern). None of the conditional [[Get]] patterns on proxies seem particularly common operations, even if proxies would be widely used. Are they worth the complexity of changing one of the most critical and common operations in Javascript? Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On Tue, Nov 8, 2011 at 4:58 PM, Tom Van Cutsem tomvc...@gmail.com wrote: Perhaps we should be more conservative here, without necessarily backing away from the whole Proxy.attach idea? Disallowing attaching to functions with your own call/construct traps would be the minimal restriction, I think. But maybe there is something cleaner. I wonder if chaperones, as implemented in Racket, would be of help here. To my understanding, a chaperone is a proxy that is very restricted in its actions, specifically: when intercepting a function call, a chaperone is only allowed to throw an exception, return the original value, or a chaperone for the original value (racketeers on this list should correct me where needed). Chaperones would still be powerful enough to express data binding: firing an update event as a side-effect does not require changing the arguments or return values of wrapped functions. However, at this point I'm not yet sufficiently familiar with chaperones to see how they can be adapted into our Proxy framework. That's a very accurate summary. I agree with Andreas that this is a significant risk for Proxy.attach. ES in the wild has few enough invariants that we should be very wary of breaking the ones we've got. However, the direct proxy proposal is already enforcing some invariants -- the proxy must produce === values to the underlying object for frozen properties. Could we just reuse this mechanism for the [[Call]] and [[Construct]] behavior of functions in the cases Andreas brings up for Proxy.attach (if we decide that we want it)? The idea of chaperones would be then relaxing this invariant slightly, to allow frozen properties to produce proxies for the underlying property value, instead of just something === to it. This makes proxies more expressive in some cases, without reducing the invariants we can rely on. -- sam th sa...@ccs.neu.edu ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: making |this| an error (was Re: for own(...) loop)
On Wed, Nov 9, 2011 at 3:41 AM, David Bruant bruan...@gmail.com wrote: Le 09/11/2011 02:26, Andrew Paprocki a écrit : On Tue, Nov 8, 2011 at 6:36 PM, Brendan Eichbren...@mozilla.com wrote: Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study. I was curious so I did some grok-ing across my code sample and Object.keys() is barely used. The usage of the |for in| construct is 2 orders of magnitude larger than the usage of hasOwnProperty(), supporting the thought that no one really does it the right way. The MDN page for Object.keys does not talk about |this| being wrong in certain situations. If you could elaborate on that, it would be helpful to know. The |this| differs between the body of a for-in and the argument callback in the .forEach. Nothing to do with Object.keys. .forEach has a second optional argument which is the value to be used as |this| so that you don't have to do a .bind. I'm sure this has been discussed before, but isn't is possible and desirable to make |this| illegal in using strict; when it can be determined from the AST alone that |this| will bind to |window|? eg: Object.keys(foo).forEach(function(key) { // this is undefined- window }); This case kind of case is because, as others have noted, incorrect |this| binding most often occurs in two cases: 1) mixed OO and functional programming (as above) and 2) callback defn. Perhaps it is harder to detect than I think. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: making |this| an error (was Re: for own(...) loop)
The forEach method might not do what you expect it to. This can not be statically determined. - peter On 9 Nov 2011 16:10, John J Barton johnjbar...@johnjbarton.com wrote: On Wed, Nov 9, 2011 at 3:41 AM, David Bruant bruan...@gmail.com wrote: Le 09/11/2011 02:26, Andrew Paprocki a écrit : On Tue, Nov 8, 2011 at 6:36 PM, Brendan Eichbren...@mozilla.com wrote: Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study. I was curious so I did some grok-ing across my code sample and Object.keys() is barely used. The usage of the |for in| construct is 2 orders of magnitude larger than the usage of hasOwnProperty(), supporting the thought that no one really does it the right way. The MDN page for Object.keys does not talk about |this| being wrong in certain situations. If you could elaborate on that, it would be helpful to know. The |this| differs between the body of a for-in and the argument callback in the .forEach. Nothing to do with Object.keys. .forEach has a second optional argument which is the value to be used as |this| so that you don't have to do a .bind. I'm sure this has been discussed before, but isn't is possible and desirable to make |this| illegal in using strict; when it can be determined from the AST alone that |this| will bind to |window|? eg: Object.keys(foo).forEach(function(key) { // this is undefined- window }); This case kind of case is because, as others have noted, incorrect |this| binding most often occurs in two cases: 1) mixed OO and functional programming (as above) and 2) callback defn. Perhaps it is harder to detect than I think. jjb ___ 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: making |this| an error (was Re: for own(...) loop)
On Wed, Nov 9, 2011 at 7:22 AM, Peter van der Zee e...@qfox.nl wrote: The forEach method might not do what you expect it to. This can not be statically determined. And if forEach is not what you expect, that function may bind its argument: foo(function() { do something with |this| }); function foo(fn) { bar.fn()}; I suppose it's more of a lint thing then. jjb - peter On 9 Nov 2011 16:10, John J Barton johnjbar...@johnjbarton.com wrote: On Wed, Nov 9, 2011 at 3:41 AM, David Bruant bruan...@gmail.com wrote: Le 09/11/2011 02:26, Andrew Paprocki a écrit : On Tue, Nov 8, 2011 at 6:36 PM, Brendan Eichbren...@mozilla.com wrote: Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study. I was curious so I did some grok-ing across my code sample and Object.keys() is barely used. The usage of the |for in| construct is 2 orders of magnitude larger than the usage of hasOwnProperty(), supporting the thought that no one really does it the right way. The MDN page for Object.keys does not talk about |this| being wrong in certain situations. If you could elaborate on that, it would be helpful to know. The |this| differs between the body of a for-in and the argument callback in the .forEach. Nothing to do with Object.keys. .forEach has a second optional argument which is the value to be used as |this| so that you don't have to do a .bind. I'm sure this has been discussed before, but isn't is possible and desirable to make |this| illegal in using strict; when it can be determined from the AST alone that |this| will bind to |window|? eg: Object.keys(foo).forEach(function(key) { // this is undefined- window }); This case kind of case is because, as others have noted, incorrect |this| binding most often occurs in two cases: 1) mixed OO and functional programming (as above) and 2) callback defn. Perhaps it is harder to detect than I think. jjb ___ 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: making |this| an error (was Re: for own(...) loop)
2011/11/9 John J Barton johnjbar...@johnjbarton.com I'm sure this has been discussed before, but isn't is possible and desirable to make |this| illegal in using strict; when it can be determined from the AST alone that |this| will bind to |window|? eg: Object.keys(foo).forEach(function(key) { // this is undefined- window }); This case kind of case is because, as others have noted, incorrect |this| binding most often occurs in two cases: 1) mixed OO and functional programming (as above) and 2) callback defn. In `strict-mode', |this| would resolve to `undefined' inside that function anyways. I'm not a fan of making constructs illegal just because their semantics might be confusing, even more so when such disallowance would vary highly in context. It would be bound to make things more confusing, imho. Block lambdas are the best solution I can see right now. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: making |this| an error (was Re: for own(...) loop)
On 9 November 2011 16:10, John J Barton johnjbar...@johnjbarton.com wrote: I'm sure this has been discussed before, but isn't is possible and desirable to make |this| illegal in using strict; when it can be determined from the AST alone that |this| will bind to |window|? eg: Object.keys(foo).forEach(function(key) { // this is undefined- window }); How do you know statically that `this' would be undefined? Somebody might have modified forEach. In JavaScript, you generally don't know a whole lot of things statically. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [Proxies] Refactoring prototype climbing in the spec
On Nov 9, 2011, at 3:53 AM, Tom Van Cutsem wrote: 2011/11/8 Allen Wirfs-Brock al...@wirfs-brock.com On Nov 8, 2011, at 7:33 AM, Andreas Rossberg wrote: But I have a follow-up request. :) Regarding redundant trap calls with proxies there is another, more pervasive problem with the current spec: in lots of places it first calls [[HasProperty]] and then [[Get]]. With proxies, this always implies two trap calls, which seems wasteful. Would it be possible to refactor that, too? Seems more difficult, because we would need to enable [[Get]] (and hence the get trap) to signal lookup failure. (Too bad that we cannot reuse `undefined' for it.) But I think the current situation isn't satisfactory. I agree, the current specification style is fine when we are dealing with side-effectly free internal operations but as soon as they are reified they become problematic and a performance issue. Is the situation really that problematic? Skimming the ES5.1 spec for [[HasProperty]], I encounter calls in the following places: - ToPropertyDescriptor conversion (only triggers proxy code via Object.defineProperty(obj, name, aProxyAsDescriptor) and Object.defineProperties). - lots of methods on Array.prototype (map, forEach, filter, some, reduce, reduceRight, reverse, splice, indexOf, lastIndexOf, every, shift, slice, sort, unshift): the only way in which these trigger proxy code is when |this| is a proxy, i.e. when they are called as Array.prototype.theMethod.call(aProxy). (calling aProxy.theMethod triggers the proxy's get trap) - Array.prototype.concat: [[HasProperty]] is called on a built-in Array only. the array methods are my primary concern as the HasProperty/Get combination is used to preserve holes as the algorithms iterate over arrays. On large arrays, there can be lots of these calls. However, I'm not sure I understand your comments about theMethod.call(aProxy) vs. aProxy.theMethod(). In either case when theMethod is actually executed the this value must be aProxy and the internal calls to [[HasProperty]] and [[Get]] need to trap. - 10.2.1.2 Object environment records uses [[HasProperty]] in a number of places. Isn't this needed only for |with|, so only triggered by |with (aProxy) { ... }|? Since ES.next builds on ES5/strict, this doesn't seem to carry much weight. And for global object bindings. It still has to work, consider for example, a proxy based DOM object that is accessed from non-Harmony code. The global object, it self, might be a Proxy. - The in operator: only calls [[HasProperty]], not followed by a call to [[Get]] (so it's not an instance of the conditional [[Get]] pattern). None of the conditional [[Get]] patterns on proxies seem particularly common operations, even if proxies would be widely used. Are they worth the complexity of changing one of the most critical and common operations in Javascript? The array functions are my primary concern. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [Proxies] Refactoring prototype climbing in the spec
On Nov 9, 2011, at 3:17 AM, Tom Van Cutsem wrote: 2011/11/8 Allen Wirfs-Brock al...@wirfs-brock.com I don't think that [[GetP]] and [[PutP]] need to be internal methods In spec'ing this I think I would make them be abstract operations. Internal methods are extensions points that can be over-ridden on a per object basis. That is what [[Get]] and [[Put]] provides. GetP and SetP define fixed operations. I proposed [[GetP]] and [[SetP]] as internal methods because Proxies would inherit the built-in behavior for [[Get]] and [[Put]], but override the [[GetP]] and [[SetP]] operations. If [[GetP]] and [[SetP]] become abstract operations, won't they need to explicitly dispatch? Proxies could override [[Get]] and [[Put]], but that would require them to duplicate the Object [[Get]] and [[Put]] code. [[Get]] seems to do nothing but redispatch to [[GetP]] so its definition could be replaced with the body of [[GetP]]. [[Puit] does a redispatch to [[SetP]] followed by a mode based conditional throw depending upon the result of the [[SetP]]. I din't think the the throwing behavior needs (or even should) be over-ride able by a proxy (or even by an alternative internal implementation). I would factor the conditional throw code out of [[Put]] and make it the responsibility of the caller. In practice, this just means that I would define a new Abstraction Operation that is used in place of direct calls to [[Put]]. The abstraction operation wold essentially have the definition you provide for [[Put]] except that it would call [[Put]] instead of [[SetP]] and the definition of [[Put]] would be replaced with the body of [[SetP]] Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Wed, Nov 9, 2011 at 3:40 PM, Jorge jo...@jorgechamorro.com wrote: On 08/11/2011, at 22:17, John J Barton wrote: Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ? A goto? *Really*? Array.prototype.some is a good way to get forEach-like behavior where you can break out of. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Nov 9, 2011, at 12:40 PM, Jorge wrote: On 08/11/2011, at 22:17, John J Barton wrote: Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ? goto as in C, from body to a label in the outer function or script? Seriously? You could always use try/catch/throw, but who would? Escape continuations and call/cc are off the agenda. See http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival -- that's the only way you're going to get break as safer goto to work here. There: I closed on a positive note! :-P /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Wed, Nov 9, 2011 at 4:05 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 9, 2011, at 12:40 PM, Jorge wrote: On 08/11/2011, at 22:17, John J Barton wrote: Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ? goto as in C, from body to a label in the outer function or script? Seriously? You could always use try/catch/throw, but who would? Umm, es-next, right? In a way, isn't this what StopIteration is? :) Still, it's a whole lot nicer to just let the language do your try/catch wrapping where you can. And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job. Escape continuations and call/cc are off the agenda. See http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival-- that's the only way you're going to get break as safer goto to work here. There: I closed on a positive note! :-P ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Nov 9, 2011, at 1:15 PM, Dean Landolt wrote: On Wed, Nov 9, 2011 at 4:05 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 9, 2011, at 12:40 PM, Jorge wrote: On 08/11/2011, at 22:17, John J Barton wrote: Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ? goto as in C, from body to a label in the outer function or script? Seriously? You could always use try/catch/throw, but who would? Umm, es-next, right? In a way, isn't this what StopIteration is? :) No, that's almost entirely under the for/of hood. The number of users who have to manually catch in order to write schedulers is miniscule compared to the population who'll write loops, comprehensios, and generator expressions. Still, it's a whole lot nicer to just let the language do your try/catch wrapping where you can. Yes. And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job. Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Wed, Nov 9, 2011 at 4:20 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 9, 2011, at 1:15 PM, Dean Landolt wrote: On Wed, Nov 9, 2011 at 4:05 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 9, 2011, at 12:40 PM, Jorge wrote: On 08/11/2011, at 22:17, John J Barton wrote: Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ? goto as in C, from body to a label in the outer function or script? Seriously? You could always use try/catch/throw, but who would? Umm, es-next, right? In a way, isn't this what StopIteration is? :) No, that's almost entirely under the for/of hood. The number of users who have to manually catch in order to write schedulers is miniscule compared to the population who'll write loops, comprehensios, and generator expressions. Still, it's a whole lot nicer to just let the language do your try/catch wrapping where you can. Yes. And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job. Clearly people like the forEach array extra in conjunction with Object.keys. Aye, but I suspect that's because many people don't realize that `some` is a superset of forEach, and IIUC is for *exactly* this use case. I bet this lack of awareness of the rest of the array extras will be improved with time -- I don't think it lends much support to any argument for fancy new control flow semantics. With block-lambdas they could have their cake and break from it too That's what I'm afraid of :-/ (and the call would be paren-free to boot). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Nov 9, 2011, at 1:33 PM, Quildreen Motta wrote: On 09/11/11 19:20, Brendan Eich wrote: And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job. Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot). That sounds like something to look forward to. I agree! :) Though, did TC39 reach a consensus on having or not block-lambdas or just a shorter function syntax? It's still a topic of discussion, not on the ES6 plate but ongoing work. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Nov 9, 2011, at 1:33 PM, Dean Landolt wrote: And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job. Clearly people like the forEach array extra in conjunction with Object.keys. Aye, but I suspect that's because many people don't realize that `some` is a superset of forEach, and IIUC is for exactly this use case. I bet this lack of awareness of the rest of the array extras will be improved with time -- I don't think it lends much support to any argument for fancy new control flow semantics. Agreed, and I'm not the one making that argument! No goto, no block-lambda for only this case. The main argument for block-lambdas is shorter function syntax with value-added semantics. Some disagree on the -added. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
And if you need to break out of forEach, just, umm, don't use forEach. It's the wrong tool for the job. Clearly people like the forEach array extra in conjunction with Object.keys. With block-lambdas they could have their cake and break from it too (and the call would be paren-free to boot). +1 Do block-lamdbas count as a fix for the dynamic this problem? Or are there other plans to get it solved? I would still love to see that happen, it’s a remarkably subtle source of errors. Could functions adopt the block-lambda semantics of picking up the `this` of the surrounding scope when not invoked as methods? It seems like that could work in strict mode where no one expects `this` to have a value. -- 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: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Nov 9, 2011, at 2:43 PM, Axel Rauschmayer wrote: Do block-lamdbas count as a fix for the dynamic this problem? Definitely. Or are there other plans to get it solved? I would still love to see that happen, it’s a remarkably subtle source of errors. Could functions adopt the block-lambda semantics of picking up the `this` of the surrounding scope when not invoked as methods? It seems like that could work in strict mode where no one expects `this` to have a value. No, if you call such functions via object.method() references then this binds to object. You can't break such compatibility only at runtime, and only some of the time. /be -- 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: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
Should ES.next provide sugar for the recommended pattern? To make it compose with declarations and destructuring in the for head, it should use a contextual keyword immediately after 'for': for own (i in o) { body } This is a small thing but it might pay off in the long run. I was thinking of raising a similar suggestion, but I wasn't sure when to jump in and bring it up. However, I think it could be more useful to introduce another operator like `in` as syntactic sugar for `hasOwnProperty` and have it work in a `for` loop similar to how `for...in` works too. /* Desugared property check - */ o.hasOwnProperty(prop) /* Sweetened property check - */ prop on o /* Desugared loop - */ for (i in o) { if o.hasOwnProperty(i) { ... } /* Sweetened loop - */ for (i on o) { ... } I could see it being useful as an operator in situations where you might have an object map: var obj = { key1: val1, key2: val2 } if (key1 on obj) { // ... } I think Dr Rauschmayer mentioned Python's `on` and I think it fits in here quite nicely. `in` for anywhere in the chain, `on` for direct properties. If it's a little too close for comfort, you could stick with `own` or reverse the operands and call it `hasown`. Perhaps that would seem too inconsistent, though. Overall, I think it's a great idea. It's fairly common for developers to forget to do a `hasOwnProperty` check when enumerating. As for `Object.keys(o).forEach()`, the speed just doesn't compare and it doesn't look too great. Andy Earnshaw ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
`this`: methods versus functions
Or are there other plans to get it solved? I would still love to see that happen, it’s a remarkably subtle source of errors. Could functions adopt the block-lambda semantics of picking up the `this` of the surrounding scope when not invoked as methods? It seems like that could work in strict mode where no one expects `this` to have a value. No, if you call such functions via object.method() references then this binds to object. You can't break such compatibility only at runtime, and only some of the time. Got it. I’m assuming that’s a performance issue? In principle, one can envision: Bind this lexically by default, override with receiver when called as a function. var obj1 = { makeFunction: function() { return function () { return this; }; } } var func = obj1. makeFunction(); console.log(func() === obj1); // true, lexical `this` by default obj2 = { method: func } console.log(obj2.method() === obj2); // true, dynamic this overrides lexical `this` Sorry for bringing up this issue again, I’m still a bit hazy as to what the arguments against such a solution are, especially after having seen the semantics of block lambdas. -- 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: `this`: methods versus functions
On Nov 9, 2011, at 3:48 PM, Axel Rauschmayer wrote: Or are there other plans to get it solved? I would still love to see that happen, it’s a remarkably subtle source of errors. Could functions adopt the block-lambda semantics of picking up the `this` of the surrounding scope when not invoked as methods? It seems like that could work in strict mode where no one expects `this` to have a value. No, if you call such functions via object.method() references then this binds to object. You can't break such compatibility only at runtime, and only some of the time. Got it. I’m assuming that’s a performance issue? You could say that. If we inherit by default but it's a soft binding, then the inner function has to carry that reference with it, but in a way that can be overridden. We talked about lexical this for functions long ago (Jan. 2008? at Google anyway) and IIRC Mark found a subtler flaw. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: `this`: methods versus functions
On Wed, Nov 9, 2011 at 4:00 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 9, 2011, at 3:48 PM, Axel Rauschmayer wrote: We talked about lexical this for functions long ago (Jan. 2008? at Google anyway) and IIRC Mark found a subtler flaw. I think my original example was smaller and more elegant. But the following is adequate to demonstrate the problem: function Outer(secret) { use strict; this.v = secret; this.w = secret * 2; this.x = secret * 3; this.InnerPoint = function(x, y) { this.x = x; this.y = y; }; this.InnerPoint.prototype = { getX: function() { return this.x; }, getY: function() { return this.y; } }; } Alice does: var outer = new Outer(mySecret); var innerPoint = new outer.InnerPoint(3,5); bob(innerPoint); // passed innerPoint to Bob, who Alice does not trust. Today, Bob, receiving innerPoint, has no way to obtain Alice's secret. Given your proposal, Bob could do (1,innerPoint.getX)() / 3; Today, if Bob does that, the getX call fails when it tries to evaluate undefined.x. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: `this`: methods versus functions
Got it. I’m assuming that’s a performance issue? You could say that. If we inherit by default but it's a soft binding, then the inner function has to carry that reference with it, but in a way that can be overridden. We talked about lexical this for functions long ago (Jan. 2008? at Google anyway) and IIRC Mark found a subtler flaw. But again, it's a runtime incompatible change, even ignoring performance. Code today may count on this == global in non-strict mode, or this === undefined in strict mode, for inner functions not called as methods. Making such a runtime-incompatible change uses up one of my five fingers of fate and it's not to be done lightly. Agreed. The global object assumption is too prevalent in non-strict mode, so that one is out. Strict mode *might* still be OK. In any case, if we have both block lambdas and shorter method syntax (*) then everyone will automatically do the right thing in practically all cases. That would be really cool. (*) I recently heard a story of someone being surprised by seeing the word “function” in object literals – “Isn’t that supposed to be a method? Why is it called a function, then?” -- 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: `this`: methods versus functions
On Nov 9, 2011, at 4:15 PM, Mark S. Miller wrote: On Wed, Nov 9, 2011 at 4:00 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 9, 2011, at 3:48 PM, Axel Rauschmayer wrote: We talked about lexical this for functions long ago (Jan. 2008? at Google anyway) and IIRC Mark found a subtler flaw. I think my original example was smaller and more elegant. I remember longer, but could be misremembering. Anyway, your example here is great, thanks! /be But the following is adequate to demonstrate the problem: function Outer(secret) { use strict; this.v = secret; this.w = secret * 2; this.x = secret * 3; this.InnerPoint = function(x, y) { this.x = x; this.y = y; }; this.InnerPoint.prototype = { getX: function() { return this.x; }, getY: function() { return this.y; } }; } Alice does: var outer = new Outer(mySecret); var innerPoint = new outer.InnerPoint(3,5); bob(innerPoint); // passed innerPoint to Bob, who Alice does not trust. Today, Bob, receiving innerPoint, has no way to obtain Alice's secret. Given your proposal, Bob could do (1,innerPoint.getX)() / 3; Today, if Bob does that, the getX call fails when it tries to evaluate undefined.x. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: supporting ES upgrading with a programming pattern repo?
On Nov 9, 2011, at 10:55 , Claus Reinke wrote: Both the committee and JS coders could profit from examples. Amen to that. JavaScript seems worse than any other language when it comes to finding correct information on the web. For example, I trust StackOverflow for many topics, but for JavaScript, it’s often shockingly wrong. Half-truths are even worse than information that is completely wrong. However, there are so many styles in JavaScript that I don’t think there is a way of creating a corpus that everyone agrees on. The best you can do as a newbie is hitch your wagon to someone that you trust and follow his/her style. There are a few books that allow you to do that (JavaScript the good parts, Eloquent JS, etc.). I really liked “Effective Java”, a similar book would make sense for JavaScript (in many ways “the good parts” already is). Some of Brendan’s tweets, some of Allen’s or David’s posts, and Mark’s recent puzzle would all qualify as material for such a book. Apart from that, I thought that it might make sense to found some kind of “network of trust” of people who write introductory articles. It would be a brand that tells people that the information they see is correct. For example, when I see something by, say, Addy Osmany, Angus Croll, or Nicholas Zakas I know that there usually won’t be any errors. It might make sense for someone to curate the considerable introductory material that is out there. That could be complemented by a peer review process. -- 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
Fwd: supporting ES upgrading with a programming pattern repo?
Oops, I think I partially misread your email: You were talking about upcoming changes and new patterns enabled by ES.next. But some of my observations should still hold: You probably need a single person to write such material (or at least to curate it). Begin forwarded message: From: Axel Rauschmayer a...@rauschma.de Subject: Re: supporting ES upgrading with a programming pattern repo? Date: November 10, 2011 1:34:36 GMT+01:00 To: Claus Reinke claus.rei...@talk21.com Cc: es-discuss@mozilla.org On Nov 9, 2011, at 10:55 , Claus Reinke wrote: Both the committee and JS coders could profit from examples. Amen to that. JavaScript seems worse than any other language when it comes to finding correct information on the web. For example, I trust StackOverflow for many topics, but for JavaScript, it’s often shockingly wrong. Half-truths are even worse than information that is completely wrong. However, there are so many styles in JavaScript that I don’t think there is a way of creating a corpus that everyone agrees on. The best you can do as a newbie is hitch your wagon to someone that you trust and follow his/her style. There are a few books that allow you to do that (JavaScript the good parts, Eloquent JS, etc.). I really liked “Effective Java”, a similar book would make sense for JavaScript (in many ways “the good parts” already is). Some of Brendan’s tweets, some of Allen’s or David’s posts, and Mark’s recent puzzle would all qualify as material for such a book. Apart from that, I thought that it might make sense to found some kind of “network of trust” of people who write introductory articles. It would be a brand that tells people that the information they see is correct. For example, when I see something by, say, Addy Osmany, Angus Croll, or Nicholas Zakas I know that there usually won’t be any errors. It might make sense for someone to curate the considerable introductory material that is out there. That could be complemented by a peer review process. -- 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 -- 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: supporting ES upgrading with a programming pattern repo?
Amen to that. JavaScript seems worse than any other language when it comes to finding correct information on the web. For example, I trust StackOverflow for many topics, but for JavaScript, it’s often shockingly wrong. Half-truths are even worse than information that is completely wrong. Join the PromoteJS revolution. http://promotejs.org However, there are so many styles in JavaScript that I don’t think there is a way of creating a corpus that everyone agrees on. The best you can do as a newbie is hitch your wagon to someone that you trust and follow his/her style. There are a few books that allow you to do that (JavaScript the good parts, Eloquent JS, etc.). I really liked “Effective Java”, a similar book would make sense for JavaScript (in many ways “the good parts” already is). Some of Brendan’s tweets, some of Allen’s or David’s posts, and Mark’s recent puzzle would all qualify as material for such a book. As an aside, this book is pretty good too: http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752 Apart from that, I thought that it might make sense to found some kind of “network of trust” of people who write introductory articles. It would be a brand that tells people that the information they see is correct. For example, when I see something by, say, Addy Osmany, Angus Croll, or Nicholas Zakas I know that there usually won’t be any errors. It might make sense for someone to curate the considerable introductory material that is out there. That could be complemented by a peer review process. -- 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On 09/11/2011, at 22:05, Brendan Eich wrote: On Nov 9, 2011, at 12:40 PM, Jorge wrote: On 08/11/2011, at 22:17, John J Barton wrote: Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); By the way, isn't that above a(nother) good use case for a goto, given that there's no (easy) way to break out of a forEach 'loop' ? goto as in C, from body to a label in the outer function or script? Seriously? OMG. Did I say that ? a goto across functions ? :-P My bad. -- Jorge. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss