Re: Are some es-discuss submissions automatically blocked?
We use Google Postini in concert with Mailman. Postini needs to be told sometimes. If you don't see mail get through, mail es-discuss-ow...@mozilla.org about it. /be While that has helped usually, in this particular case my email to es-discuss-owner (19.10.2011) also disappeared without reply. As did another attempt to reach you directly (22.10.2011). So the system seems to have more serious issues at the moment. How many es-discuss-owners are left, and do they all use the same filters as es-discuss? Do they check their spam folders (perhaps weekly), or is spam deleted automatically/unseen? Claus ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: An array destructing specification choice
On 7 November 2011 18:42, Allen Wirfs-Brock al...@wirfs-brock.com wrote: or let [first,second] = abc; Yes, that's a more convincing example -- although we should probably be aware that users will then also do let [x, y, ...s] = somestring and expect it to slice a string efficiently. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [Proxies] Refactoring prototype climbing in the spec
I am a big fan of this refactoring. I like the idea that the algorithm transfers full control to the proxy. Also, accepting this strawman would solve my inherited event properties problem because I would have access to the receiver from the get trap and would be able to do the binding I want. Glad to hear that. About [[SetP]]: * It seems to me that we've traded a duplicated [[GetProperty]] call for a duplicated [[GetOwnProperty]] (Step 1 and 5.a) call on the receiver. This could be avoided by storing the property descriptor at the beginning (when O.[[setP]](Receiver, P, V) is called and O === receiver). Step 5.a could be remove by the change. The double [[GetOwnProperty]] invocation on the initial receiver should not be observable: if the initial Receiver of [[SetP]] is a proxy, the proxy's [[SetP]] algorithm (which triggers the set trap) executes instead of this algorithm. So it's only if the initial Receiver is a normal object that this code executes, and then the call to [[GetOwnProperty]] on line 1 will never trigger proxy code. When [[SetP]] is called by evaluating a property assignment expression, Receiver also always denotes a normal non-proxy object. However, with the proposed Object.getProperty built-in one can write: Object.getProperty(aProxy, name, aNormalObject) which would trigger aNormalObject.[[SetP]](aProxy, name), so then Receiver would indeed be a proxy. Line 1 then calls aNormalObject.[[GetOwnProperty]], while line 5.a, if reached, would trigger aProxy.[[GetOwnProperty]]. Long story short: the O variable in the [[SetP]] algorithm always denotes a normal non-proxy object. In general, the Receiver variable can be any object. * If step 5.a is removed, I think that step 5.b.i is useless, because we would have returned from the set when O was the receiver (by step 2.a of [[setP]]) * If step 5.a is removed, then step 5.c is useless, because if the desc had a [[set]], then we would have already returned from one of the substep of step 3 when O was the receiver Why not redefining [[Get]] as what you have defined as [[GetP]] and equivalent for [[Set]] and [[SetP]]? Current 8.12.3 [[Get]] (P) would become [[Get]] (Receiver, P). It would be called with O as initial value for Receiver pretty much everywhere in the spec except within [[Get]] recursive calls. Equivalent for [[Set]]. It would prevent the replacement of 2 Object.* methods by 2 others. The reason I introduced separate [[GetP]] and [[SetP]] methods is simply so that the public API of Objects remained intact. Your suggestion is reasonable: trade proliferation of built-in methods for a small public API change in the spec. I guess this is just a matter of find/replacing all the calls to [[Get]]/[[Put]]. Might even be an opportunity to get rid of put and use set consistently throughout the spec. With the refactoring, on the direct proxy strawman, I don't think we need the proxy argument for the get and set traps anymore. It was here as the receiver, but since we have the receiver itself, the get and set trap can just have the receiver and the target as argument. Good point. I'd wager that in most use cases, knowing that |receiver| is either your own proxy or a descendant of that proxy is sufficient. I can't currently think of a use case where the get/set trap would really want to be able to access the proxy itself, not just the proxy or a descendant. That doesn't mean that use cases for it don't exist, however. I guess if access to the proxy is really needed, it's easy enough to accomplish: var p = Proxy.for(target, handler); handler.proxy = p; Now the proxy is accessible as |this.proxy| in all traps. This may seem like a hassle, but if the use cases for accessing a proxy are sufficiently minor, getting rid of the proxy argument to the get/set traps seems like a good tradeoff. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: An array destructing specification choice
On 7 November 2011 22:46, Brendan Eich bren...@mozilla.com wrote: On Nov 7, 2011, at 3:04 AM, Andreas Rossberg wrote: One possible semantics could be treating let [x, y, z, ...r] = e as equivalent to let {0: x, 1: y, 2: z, ..._r} = e let r = [].slice.call(_r, 3) where I assume the canonical matching semantics for object rest patterns that would make _r an ordinary object (not an array) accumulating all properties of e not explicitly matched (even if e itself is an array, in which case _r includes a copy of e's length property). Of course, engines would optimize properly. Right, but why the 3 passed to slice.call if _r captured all enumerable properties except those with ids 0, 1, and 2 (stringified, of course)? I was assuming that we want let [x, y,z, ...r] = [1, 2, 3, 4, 5] to bind r to [4, 5]. For that to hold, you have to shift down the numeric indices in _r by 3, which is what the slice call was intended to do. At least that's the behaviour I'd expect from an array rest pattern, and Allen's earlier example in this thread seems consistent with this assumption. But looking at the proposal, I now see that it does not actually do the shifting. So now I'm confused about what the intended semantics actually is. Anyway, you've hit what I was advocating over the weekend as the answer to the pair of questions I posed: [no, no]. Lasse makes a good case for [yes, yes]. The call to .slice implicitly reads the length, so it rather seems to implement [no, yes]. Using [no, no] would work, too, but requires a somewhat non-standard form of slicing. I have a slight preference for being consistent with the existing slicing semantics. I don't like [yes, yes] that much. I prefer to view array patterns merely as straightforward sugar for object matching, and [yes, yes] kind of breaks that and puts more special cases into the language. So I'd actually turn around Lasse's argument. :) I still think we should argue about row capture in object patterns a bit before concluding. What do you think? Well, I think that row capture in object patterns is indeed a useful feature, esp for record-like use cases. I agree that shallow cloning isn't a big problem -- in any case, it's no worse than doing the same sort of cloning for array-like objects. It also seems more consistent to me to have rest patterns in both forms. If object rows enable maintaining the syntactic sugar explanation for array patterns, then the overall result might even be a slightly simpler language. /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 7 November 2011 16:54, Tom Van Cutsem tomvc...@gmail.com wrote: I wrote up an initial (but fairly complete) draft of a proposed refactoring of the ES5 [[Get]], [[Put]] and [[HasProperty]] algorithms to change the way in which these algorithms climb the prototype chain: http://wiki.ecmascript.org/doku.php?id=strawman:refactoring_put Looks good, and as far as I can see from a first read, solves the issues we were discussing so far. 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. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: An array destructing specification choice
On Nov 8, 2011, at 4:01 AM, Andreas Rossberg wrote: I was assuming that we want let [x, y,z, ...r] = [1, 2, 3, 4, 5] to bind r to [4, 5]. For that to hold, you have to shift down the numeric indices in _r by 3, which is what the slice call was intended to do. Gotcha, my mistake -- thanks. Using [no, no] would work, too, but requires a somewhat non-standard form of slicing. I have a slight preference for being consistent with the existing slicing semantics. Agreed, you're right again. (I am 0 for 2!) I don't like [yes, yes] that much. I prefer to view array patterns merely as straightforward sugar for object matching, and [yes, yes] kind of breaks that and puts more special cases into the language. So I'd actually turn around Lasse's argument. :) [yes, yes] does put more special casing and length-capturing-in-a-temp and bounds-checking, and that still makes me rebel against its consistency. There's consistency in [no, no] too. Lasse's point that {0:x, 1:y} and [x, y] being the same is not a mark against consistency, but redundancy or lack of new semantics for the [x, y] pattern (viz, length filtering of the RHS properties). But that seems better to me on balance than the length sampling and bounding. I still think we should argue about row capture in object patterns a bit before concluding. What do you think? Well, I think that row capture in object patterns is indeed a useful feature, esp for record-like use cases. I agree that shallow cloning isn't a big problem -- in any case, it's no worse than doing the same sort of cloning for array-like objects. That's my thinking too. We see people building such things with for-in loops in libraries today. That's a signal amid the noise. It also seems more consistent to me to have rest patterns in both forms. If object rows enable maintaining the syntactic sugar explanation for array patterns, then the overall result might even be a slightly simpler language. Agreed. Thanks, /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [Proxies] Refactoring prototype climbing in the spec
Le 08/11/2011 11:54, Tom Van Cutsem a écrit : About [[SetP]]: * It seems to me that we've traded a duplicated [[GetProperty]] call for a duplicated [[GetOwnProperty]] (Step 1 and 5.a) call on the receiver. This could be avoided by storing the property descriptor at the beginning (when O.[[setP]](Receiver, P, V) is called and O === receiver). Step 5.a could be remove by the change. The double [[GetOwnProperty]] invocation on the initial receiver should not be observable: if the initial Receiver of [[SetP]] is a proxy, the proxy's [[SetP]] algorithm (which triggers the set trap) executes instead of this algorithm. Very true. And even if there is no trap, the default action is to trigger [[Set]] on the target, so no duplicated call. (...) Long story short: the O variable in the [[SetP]] algorithm always denotes a normal non-proxy object. In general, the Receiver variable can be any object. * If step 5.a is removed, I think that step 5.b.i is useless, because we would have returned from the set when O was the receiver (by step 2.a of [[setP]]) * If step 5.a is removed, then step 5.c is useless, because if the desc had a [[set]], then we would have already returned from one of the substep of step 3 when O was the receiver Why not redefining [[Get]] as what you have defined as [[GetP]] and equivalent for [[Set]] and [[SetP]]? Current 8.12.3 [[Get]] (P) would become [[Get]] (Receiver, P). It would be called with O as initial value for Receiver pretty much everywhere in the spec except within [[Get]] recursive calls. Equivalent for [[Set]]. It would prevent the replacement of 2 Object.* methods by 2 others. The reason I introduced separate [[GetP]] and [[SetP]] methods is simply so that the public API of Objects remained intact. Your suggestion is reasonable: trade proliferation of built-in methods for a small public API change in the spec. I guess this is just a matter of find/replacing all the calls to [[Get]]/[[Put]]. Exactly, that's what I had in mind. Might even be an opportunity to get rid of put and use set consistently throughout the spec. I cannot agree more with this idea. Especially with proxies having a set trap and accessor properties having setters, [[Put]] sounds wrong even though that has been the name in ES5, ES3 (and even before?) With the refactoring, on the direct proxy strawman, I don't think we need the proxy argument for the get and set traps anymore. It was here as the receiver, but since we have the receiver itself, the get and set trap can just have the receiver and the target as argument. Good point. I'd wager that in most use cases, knowing that |receiver| is either your own proxy or a descendant of that proxy is sufficient. I can't currently think of a use case where the get/set trap would really want to be able to access the proxy itself, not just the proxy or a descendant.That doesn't mean that use cases for it don't exist, however. Oh true, I thought that proxy and the receiver were the same objects but if the proxy is on the prototype, it is not the case. I guess if access to the proxy is really needed, it's easy enough to accomplish: var p = Proxy.for(target, handler); handler.proxy = p; Indeed. 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)
Le 08/11/2011 14:26, Andreas Rossberg a écrit : On 3 November 2011 23:55, Mark S. Miller erig...@google.com wrote: If I understood Mark correctly, the features needed for SES are already part of ES.5 and are shipping in browsers (and hence don't bear upon future features). Did I misunderstand? These do bear on future features in three ways: 1) Future features could easily destroy all the security gains that ES5 achieved. I'm still trying to grasp the implications of the recent direct proxy proposal in this respect -- more precisely, its startTrapping functionality. Just as a reminder, startTrapping really is not necessary to direct proxies (Proxy.for) and should both should be considered independently (even though they are on the same strawman) It seems to me that the ability to attach to a function, in particular, invalidates all current security guarantees, since it gives a whole new way of completely redefining any random function _in place_ by simply turning it into a function proxy. That is, even if that function is given by a non-writable binding or property! Given that direct proxies are not in a position to violate any of the *non-configurability or non-extensibility constraints* of their wrapped target, it should be safe to replace an existing normal object by a direct proxy wrapping that object. My understanding is that regarding the issue you mention, you cannot do more with startTrapping than redefining built-ins by (re)setting a property. Though, I agree about the non-writable binding. Something should be added about that. And it seems so much safer to prevent start trapping the global object because things could get nasty otherwise. To achieve the effect of today's Object.{seal,freeze}, you hence also would have to make _every_ of the object's properties non-attachable. That is certainly possible, but seems considerably more fragile.And it still breaks the security of pre-existing SES code. IOW, I sense a security hazard. I agree that there is a hazard but I am not sure it is that much bigger than the opportunity for an attacker to redefine built-ins. This opportunity exists since the origin of JavaScript (so before ES5 and SES). I also wonder about the effect that turning an (ordinary) object into a proxy would have on the visibility of private names. If one of the original methods accesses a private property on `this', then, according to the private names proposal, the handler only gets to see the .public property of that name. But can't this still leak information? The handler cannot use it to _read_ the existing property data, but it will still receive all future _writes_ to it. Am I missing something? I don't think you are. I think you are right. As said, the startTrapping proposal is controversial. Proxies are still very new. I'm not sure it's wise to add the startTrapping. If we ever realize that this is really needed, i don't think there is a problem with adding it in a later ECMAScript version. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [Proxies] Refactoring prototype climbing in the spec
This is all going in a good direction. I only have a few minor comments: 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. 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. We either need to eliminate any internal methods that don't trap or add corresponding traps. In this proposal you eliminate the need for [[CanPUt]] and you raise the question of whether that is possible for also get rid of [[GetProperty]]. My analysis (https://docs.google.com/spreadsheet/ccc?key=0Ak51JfLL8QLYdDFkcy1VUl9OQ3BSc1kxeDI4RkJsc0E ) says that we can, so we should just go ahead and eliminate it. We might even consider eliminating [[Delete]] by defining [[DefneOwnProperty]](name,undefined) to mean delete. Finally, I also have some thoughts about [[HasProperty]] but I will put those in a replay to Andreas message on that touches on that. Allen On Nov 7, 2011, at 7:54 AM, Tom Van Cutsem wrote: Hi, I wrote up an initial (but fairly complete) draft of a proposed refactoring of the ES5 [[Get]], [[Put]] and [[HasProperty]] algorithms to change the way in which these algorithms climb the prototype chain: http://wiki.ecmascript.org/doku.php?id=strawman:refactoring_put This is mainly beneficial for proxies, as the prototype walking strategy becomes observable to proxies-used-as-prototypes. IMHO, the refactored algorithms interoperate with proxies in a much saner way, finally restoring the intuitive semantics of the get and set traps that MarkM and I had in mind from the beginning, but which Sean Eagan pointed out were flawed given the ES5 spec algorithms. The biggest change is in the [[Put]] algorithm. For those not into ES spec language, I wrote up the behavior for ES5 [[Put]] and my proposed ES.next [[Put]] in JS itself: ES5 [[Put]]: http://code.google.com/p/es-lab/source/browse/trunk/src/es5adapt/setProperty.js#115 Proposed ES.next [[Put]]: http://code.google.com/p/es-lab/source/browse/trunk/src/es5adapt/setProperty.js#68 The refactored version also fixes the anomalies resulting from the ES5 [[CanPut]] vs. [[Put]] split that Andreas Rossberg pointed out earlier on this list. When I say refactoring here, I really do intend for these new algorithms to be equivalent to the ES5 algorithms for non-proxy objects. To test whether these algorithms are indeed equivalent, I wrote up a little test-suite that runs in the browser: http://es-lab.googlecode.com/svn/trunk/src/es5adapt/testSetProperty.html The results look promising (success on Firefox7, 1 failure on Chrome/Safari because these allow overriding of non-writable inherited data props, haven't tested other browsers yet). Still, the more es-discuss eye-balls that can scrutinize these algorithms, the better. Cheers, Tom ___ 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: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On Tue, Nov 8, 2011 at 5:26 AM, Andreas Rossberg rossb...@google.comwrote: On 3 November 2011 23:55, Mark S. Miller erig...@google.com wrote: If I understood Mark correctly, the features needed for SES are already part of ES.5 and are shipping in browsers (and hence don't bear upon future features). Did I misunderstand? These do bear on future features in three ways: 1) Future features could easily destroy all the security gains that ES5 achieved. I'm still trying to grasp the implications of the recent direct proxy proposal in this respect -- more precisely, its startTrapping functionality. It seems to me that the ability to attach to a function, in particular, invalidates all current security guarantees, since it gives a whole new way of completely redefining any random function _in place_ by simply turning it into a function proxy. That is, even if that function is given by a non-writable binding or property! To achieve the effect of today's Object.{seal,freeze}, you hence also would have to make _every_ of the object's properties non-attachable. That is certainly possible, but seems considerably more fragile. And it still breaks the security of pre-existing SES code. IOW, I sense a security hazard. Hi Andreas, thanks for starting a discussion on this. I agree that there is a huge danger here. There is another approach to so-called data binding (treat it like an optimization of polling) that cannot cause any loss of security (if equivalence to polling really is maintained). Altogether, from a security pov, we'd certainly be better off without Proxy.attach. The reason Proxy.attach may not be fatal is that it only allows attachment to extensible objects. Our hypothesis is that any ES5 object that is interested in defending itself has already made itself non-extensible. This is why we must key this off of non-extensibility, rather than introducing a new orthogonal bit -- to avoid breaching the defenses of those ES5 era objects that tried to defend themselves. ES3 era objects could not defend themselves, so attaching to them cannot violate any of their valid assumptions -- to a first approximation, they could not validly assume anything. I also wonder about the effect that turning an (ordinary) object into a proxy would have on the visibility of private names. If one of the original methods accesses a private property on `this', then, according to the private names proposal, the handler only gets to see the .public property of that name. But can't this still leak information? The handler cannot use it to _read_ the existing property data, but it will still receive all future _writes_ to it. Am I missing something? Only the defensiveness points above. Regarding data binding, we should also see if the non-dangerous poll-optimization-equivalence can meet our needs instead, in which case we probably don't need Proxy.attach. /Andreas -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
for..in, hasOwnProperty(), and inheritance
Hi everyone, There is a widespread practice of doing this: - for (key in obj) { if (obj.hasOwnProperty(key)) { … } } - The oft-stated purpose for this pattern is to weed out code that comes from Object.prototype. The result, though, is that we prevent iteration through *any* inherited properties, which seems like overkill for handling the original problem. (Incidentally, I’m surprised that augmenting Object.prototype isn’t warned/deprecated in ES5 Strict. It seems far easier to get people to stop augmenting Obj.pro, which is likely to break all kinds of things, than to get everyone to filter every for..in loop. But, anyway.) It’s especially unproductive because it works against prototypal inheritance patterns. e.g.: - var dog = { speak: function() { return arf! } }; var beagle = Object.create(dog); beagle.colors = [white,black,brown]; var my_dog = Object.create(beagle); my_dog.name = Chip; - Note that filtering via hasOwnProperty() will prevent a for..in iteration from seeing either colors or speak. Another example: in YUI, it’s impossible to do this would-otherwise-be-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. So, a solution I am considering for my own work defines two methods: Object.gave(giver, key, obj) Function.prototype.gave(key,obj) They do what they look like: Object.gave checks if the “giver” really “gave” the “key”ed value to the “obj”ect. The Function.prototype version does the same but assigns the function’s prototype as “giver”. (The original Object.gave() offloads to the prototype method if called with just two args.) Thus: -- var HOP = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); Object.gave = function(giver,key,obj) { if (arguments.length === 2) { Function.prototype.gave.apply(this,arguments); } var last_prototype; while ( obj !== giver ) { if (HOP(obj,key) || (obj === last_prototype)) return false; last_prototype = obj; obj = Object.getPrototypeOf(obj); } return true; }; Function.prototype.gave = function(key,obj) { return Object.gave( this.prototype, key, obj ); }; -- Then, we can do: -- for (var key in obj) { if (Object.gave(key,obj)) { … } } -- …which will still filter out anything in Object.prototype, but will allow iteration through inherited properties. This seems to me far more useful in general than the hasOwnProperty() check. Thoughts? -Felipe Gasper cPanel, Inc. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
Whats wrong with enumeration over own properties? Object.keys() gets all enumerable own properties in a for .. in loop. for .. in gets all enumerable properties in prototype chains. I personally think it's bad practice to have code that enumerates over properties in the prototype chain. I can't see any good use case for it On Tue, Nov 8, 2011 at 7:59 AM, Felipe Gasper fel...@felipegasper.comwrote: Hi everyone, There is a widespread practice of doing this: - for (key in obj) { if (obj.hasOwnProperty(key)) { … } } - The oft-stated purpose for this pattern is to weed out code that comes from Object.prototype. The result, though, is that we prevent iteration through *any* inherited properties, which seems like overkill for handling the original problem. (Incidentally, I’m surprised that augmenting Object.prototype isn’t warned/deprecated in ES5 Strict. It seems far easier to get people to stop augmenting Obj.pro, which is likely to break all kinds of things, than to get everyone to filter every for..in loop. But, anyway.) It’s especially unproductive because it works against prototypal inheritance patterns. e.g.: - var dog = { speak: function() { return arf! } }; var beagle = Object.create(dog); beagle.colors = [white,black,brown]; var my_dog = Object.create(beagle); my_dog.name = Chip; - Note that filtering via hasOwnProperty() will prevent a for..in iteration from seeing either colors or speak. Another example: in YUI, it’s impossible to do this would-otherwise-be-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. So, a solution I am considering for my own work defines two methods: Object.gave(giver, key, obj) Function.prototype.gave(key,**obj) They do what they look like: Object.gave checks if the “giver” really “gave” the “key”ed value to the “obj”ect. The Function.prototype version does the same but assigns the function’s prototype as “giver”. (The original Object.gave() offloads to the prototype method if called with just two args.) Thus: -- var HOP = Object.prototype.**hasOwnProperty.call.bind(**Object.prototype.* *hasOwnProperty); Object.gave = function(giver,key,obj) { if (arguments.length === 2) { Function.prototype.gave.apply(**this,arguments); } var last_prototype; while ( obj !== giver ) { if (HOP(obj,key) || (obj === last_prototype)) return false; last_prototype = obj; obj = Object.getPrototypeOf(obj); } return true; }; Function.prototype.gave = function(key,obj) { return Object.gave( this.prototype, key, obj ); }; -- Then, we can do: -- for (var key in obj) { if (Object.gave(key,obj)) { … } } -- …which will still filter out anything in Object.prototype, but will allow iteration through inherited properties. This seems to me far more useful in general than the hasOwnProperty() check. Thoughts? -Felipe Gasper cPanel, Inc. __**_ 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: for..in, hasOwnProperty(), and inheritance
What’s the use case? Don’t forget that whenever you set a property, you only ever modify the first object in the prototype chain. The “own property” debate mainly exists, because objects are (ab)used as dictionaries. Then you don’t want inherited entries such as toString. On Nov 8, 2011, at 8:59 , Felipe Gasper wrote: Hi everyone, There is a widespread practice of doing this: - for (key in obj) { if (obj.hasOwnProperty(key)) { … } } - The oft-stated purpose for this pattern is to weed out code that comes from Object.prototype. The result, though, is that we prevent iteration through *any* inherited properties, which seems like overkill for handling the original problem. (Incidentally, I’m surprised that augmenting Object.prototype isn’t warned/deprecated in ES5 Strict. It seems far easier to get people to stop augmenting Obj.pro, which is likely to break all kinds of things, than to get everyone to filter every for..in loop. But, anyway.) It’s especially unproductive because it works against prototypal inheritance patterns. e.g.: - var dog = { speak: function() { return arf! } }; var beagle = Object.create(dog); beagle.colors = [white,black,brown]; var my_dog = Object.create(beagle); my_dog.name = Chip; - Note that filtering via hasOwnProperty() will prevent a for..in iteration from seeing either colors or speak. Another example: in YUI, it’s impossible to do this would-otherwise-be-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. So, a solution I am considering for my own work defines two methods: Object.gave(giver, key, obj) Function.prototype.gave(key,obj) They do what they look like: Object.gave checks if the “giver” really “gave” the “key”ed value to the “obj”ect. The Function.prototype version does the same but assigns the function’s prototype as “giver”. (The original Object.gave() offloads to the prototype method if called with just two args.) Thus: -- var HOP = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); Object.gave = function(giver,key,obj) { if (arguments.length === 2) { Function.prototype.gave.apply(this,arguments); } var last_prototype; while ( obj !== giver ) { if (HOP(obj,key) || (obj === last_prototype)) return false; last_prototype = obj; obj = Object.getPrototypeOf(obj); } return true; }; Function.prototype.gave = function(key,obj) { return Object.gave( this.prototype, key, obj ); }; -- Then, we can do: -- for (var key in obj) { if (Object.gave(key,obj)) { … } } -- …which will still filter out anything in Object.prototype, but will allow iteration through inherited properties. This seems to me far more useful in general than the hasOwnProperty() check. Thoughts? -Felipe Gasper cPanel, Inc. ___ 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: [Proxies] Refactoring prototype climbing in the spec
On Nov 8, 2011, at 7:33 AM, Andreas Rossberg wrote: On 7 November 2011 16:54, Tom Van Cutsem tomvc...@gmail.com wrote: I wrote up an initial (but fairly complete) draft of a proposed refactoring of the ES5 [[Get]], [[Put]] and [[HasProperty]] algorithms to change the way in which these algorithms climb the prototype chain: http://wiki.ecmascript.org/doku.php?id=strawman:refactoring_put Looks good, and as far as I can see from a first read, solves the issues we were discussing so far. 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. I believe that the [[HasProperty]] [[Get]] combination is always used in situations where a conditional [[Get]] is desired. I suggest that we redefine [[Get]] to take a second optional argument which is used as a signal value to indicated that the property does not exist. Internally (within the specification) any unique object value can be used as the signal value as the spec. will never allow that value to escape such that it could be stored as a property value. A similar approach could be taken with the trap and Object.getProperty APIs but there is the hazard that handler code might capture and misuse (store into a property) the signal value. It isn't clear to me whether this would constitute an exploitable hazard or whether it would just be an annoying bug. This capture problem could be avoid if the trap always passed a new object to the handler when the [[Get]] call uses its second argument. I'm reluctant to impose an (even trivial) object allocation on [[Get]] traps but it probably is still less overhead then making two traps. Also, it would not be needed in situations where the [[Get]] only had a single argument. Using this approach, the get handler signature could be something like: function(receiver, name, target, proxy, missingMarker=undefined) and the signature for Object.getProperty could be: function(receiver, name, missingMarker=undefined, parent=receiver) (for the optional argument ordering, I'm assuming that use of a missingMarker is more common then using an explicit parent) Given the limitations of ES function protocol the moral equivalent of either reference parameters or multiple value returns also require an object allocation. It isn't clear that we can do much better than this style of API. If we do this we should be able to eliminate both the [[HasProperty]] internal method and the has trap. allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
On 11/8/11 12:37 PM, Axel Rauschmayer wrote: What’s the use case? I thought I gave a pretty reasonable one before, but just in case: In YUI, it’s impossible to use this otherwise-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. Don’t forget that whenever you set a property, you only ever modify the first object in the prototype chain. Right…that’s why gave() walks the prototype chain unless it finds the property *on* the object itself. The “own property” debate mainly exists, because objects are (ab)used as dictionaries. Then you don’t want inherited entries such as toString. I disagree. That’s actually the crux of what I’m getting at. IMO, you actually do want “inherited entries”; what you don’t want are specifically those things inherited from Object.prototype. Weeding out *all* inherited properties assumes that there is no legitimate use case for objects inheriting from other objects…which defeats the whole purpose of stuff like Object.create(). -FG ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
What’s the use case? I thought I gave a pretty reasonable one before, but just in case: Thanks! Shorter is better... ;-) In YUI, it’s impossible to use this otherwise-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. Got it, you want to non-destructively modify base_config. It is kind of tricky to know when to stop traversing the prototype chain, so the more straightforward solution is to make a copy and modify there or to non-destructively merge: https://developer.yahoo.com/yui/3/examples/yui/yui-merge.html -- 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: Security and direct proxies (Was: Re: Lecture series on SES and capability-based security by Mark Miller)
On 8 November 2011 18:47, David Bruant bruan...@gmail.com wrote: Given that direct proxies are not in a position to violate any of the *non-configurability or non-extensibility constraints* of their wrapped target, it should be safe to replace an existing normal object by a direct proxy wrapping that object. My understanding is that regarding the issue you mention, you cannot do more with startTrapping than redefining built-ins by (re)setting a property. That may be true for plain objects, but I think the situation is quite different for functions, because there is no equivalent to non-configurable for the [[Call]] and [[Construct]] properties. On 8 November 2011 19:13, Mark S. Miller erig...@google.com wrote: The reason Proxy.attach may not be fatal is that it only allows attachment to extensible objects. Our hypothesis is that any ES5 object that is interested in defending itself has already made itself non-extensible. This is why we must key this off of non-extensibility, rather than introducing a new orthogonal bit -- to avoid breaching the defenses of those ES5 era objects that tried to defend themselves. I don't think that addresses the issue I was describing. The problem is: the object itself can all be frozen, non-extensible, non-attachable just fine, but that doesn't achieve much by itself anymore because an attacker can still attach to each individual method, since they are entirely separate objects! So instead of just freezing an object, you _additionally_ would have to make all its _individual methods_ non-attachable (by whatever means). AFAICS, that affects assumptions of existing ES5 code quite severely. /Andreas ___ 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 8 November 2011 20:29, Andreas Rossberg rossb...@google.com wrote: On 8 November 2011 18:47, David Bruant bruan...@gmail.com wrote: Given that direct proxies are not in a position to violate any of the *non-configurability or non-extensibility constraints* of their wrapped target, it should be safe to replace an existing normal object by a direct proxy wrapping that object. My understanding is that regarding the issue you mention, you cannot do more with startTrapping than redefining built-ins by (re)setting a property. That may be true for plain objects, but I think the situation is quite different for functions, because there is no equivalent to non-configurable for the [[Call]] and [[Construct]] properties. BTW, a similar issue applies to getters and setters: even if a property is non-configurable, as long as it is defined by accessors an attacker could attach to the underlying JS functions and thereby essentially redefine the property without actually modifying it. /Andreas ___ 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 11:29 AM, Andreas Rossberg rossb...@google.comwrote: On 8 November 2011 19:13, Mark S. Miller erig...@google.com wrote: The reason Proxy.attach may not be fatal is that it only allows attachment to extensible objects. Our hypothesis is that any ES5 object that is interested in defending itself has already made itself non-extensible. This is why we must key this off of non-extensibility, rather than introducing a new orthogonal bit -- to avoid breaching the defenses of those ES5 era objects that tried to defend themselves. I don't think that addresses the issue I was describing. The problem is: the object itself can all be frozen, non-extensible, non-attachable just fine, but that doesn't achieve much by itself anymore because an attacker can still attach to each individual method, since they are entirely separate objects! So instead of just freezing an object, you _additionally_ would have to make all its _individual methods_ non-attachable (by whatever means). AFAICS, that affects assumptions of existing ES5 code quite severely. In general, for an object to be defensive, much of the surface reachable from it by transitive prototype and reflective property traversal should usually be frozen, and at least non-extensible. This is possible to express in ES5 http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#623, but inconvenient and expensive. That's why I have been advocating better defensive abstractions for ES6: const functions, const classes, traitsjs or its syntactic derivatives, etc. 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. Perhaps we should be more conservative here, without necessarily backing away from the whole Proxy.attach idea? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
You shouldnt store properties on the prototype chain like that. Your abusing Object.create as a shallow copy. Use a real shallow copy method. On Nov 8, 2011 7:07 PM, Felipe Gasper fel...@felipegasper.com wrote: On 11/8/11 12:37 PM, Axel Rauschmayer wrote: What’s the use case? I thought I gave a pretty reasonable one before, but just in case: In YUI, it’s impossible to use this otherwise-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_co... Don’t forget that whenever you set a property, you only ever modify the first object in the prot... Right…that’s why gave() walks the prototype chain unless it finds the property *on* the object itself. The “own property” debate mainly exists, because objects are (ab)used as dictionaries. Then ... I disagree. That’s actually the crux of what I’m getting at. IMO, you actually do want “inherited entries”; what you don’t want are specifically those things inherited from Object.prototype. Weeding out *all* inherited properties assumes that there is no legitimate use case for objects inheriting from other objects…which defeats the whole purpose of stuff like Object.create(). -FG ___ es-discuss mailing list es-discuss@mozilla.org http... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
On 11/8/11 1:17 PM, Axel Rauschmayer wrote: What’s the use case? In YUI, it’s impossible to use this otherwise-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. Got it, you want to non-destructively modify base_config. It is kind of tricky to know when to stop traversing the prototype chain, … Actually, have you ever seen a use case of wanting to prevent iteration through inherited properties *other* than Object.prototype? (Besides using for..in on Array objects.) All of the examples I’ve ever seen of the problems that ensue from for..in iteration and prototypes stem from extending Object.prototype. Why not, then, specifically address that problem rather than preventing all iteration through inherited properties? -FG ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
On Nov 8, 2011, at 11:48 AM, Felipe Gasper wrote: Actually, have you ever seen a use case of wanting to prevent iteration through inherited properties *other* than Object.prototype? (Besides using for..in on Array objects.) Sure. People make classes by defining function C(){} and decorating C.prototype.method1 = function(...){...}, etc. A for-in loop on (new C) will see all the methods, unlike the case with built-in constructors. That is an unwanted abstraction break: we should support abstracting over user-defined and built-in functions. All of the examples I’ve ever seen of the problems that ensue from for..in iteration and prototypes stem from extending Object.prototype. Why not, then, specifically address that problem rather than preventing all iteration through inherited properties? I think you're focusing too narrowly. I agree with Jake: make a copy into a single object, and access it (if it's a config dictionary) with a stylized API. Sounds like you could make YUI happy that way. Separately, I think I'll propose for own(...) based on CoffeeScript's for own in/of loops. That seems more important for the long run than any API elaboration beyond Object.prototype.hasOwnProperty. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
Brendan EichNovember 8, 2011 11:59 AM On Nov 8, 2011, at 11:48 AM, Felipe Gasper wrote: Actually, have you ever seen a use case of wanting to prevent iteration through inherited properties *other* than Object.prototype? (Besides using for..in on Array objects.) Sure. People make "classes" by defining function C(){} and decorating C.prototype.method1 = function(...){...}, etc. A for-in loop on (new C) will see all the methods, unlike the case with built-in constructors. That is an unwanted abstraction break: we should support abstracting over user-defined and built-in functions. I believe people decorate a class prototype directly because they always have, and because defineProperties wasn't available for them to declare prototype methods as not enumerable, not because they explicitly want class proto methods to be enumerable. Can you elaborate on "we should support abstracting over user-defined and built-in functions"? All of the examples I’ve ever seen of the problems that ensue from for..in iteration and prototypes stem from extending Object.prototype. Why not, then, specifically address that problem rather than preventing all iteration through inherited properties? I think you're focusing too narrowly. I agree with Jake: make a copy into a single object, and access it (if it's a config dictionary) with a stylized API. Sounds like you could make YUI happy that way. Copying loses the benefit of shared defaults via prototype. I would rather see a method to flatten an object before enumeration than lose the flexibility of shared state. Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
On Nov 8, 2011, at 12:12 PM, Luke Smith wrote: Sure. People make classes by defining function C(){} and decorating C.prototype.method1 = function(...){...}, etc. A for-in loop on (new C) will see all the methods, unlike the case with built-in constructors. That is an unwanted abstraction break: we should support abstracting over user-defined and built-in functions. I believe people decorate a class prototype directly because they always have, and because defineProperties wasn't available for them to declare prototype methods as not enumerable, not because they explicitly want class proto methods to be enumerable. Yup, that's a fact. However it contradicts Felipe's belief that only Object.prototype might-be-enumerable properties need to be excluded, which was my point. Can you elaborate on we should support abstracting over user-defined and built-in functions? Abstract over means I can for-in an instance of either a built-in or (such a) user-defined constructor and not see methods. I can self-host or wrap Date without methods showing up. Yes, ES5 supports Object.defineProperty etc. so I can make the WrappedDate.prototype methods non-enumerable, if I can target ES5. But the general point stands: enumeration up the prototype chain either is a bug, or you want no enumerable prototype properties (except perhaps those added by one privileged library), or you want a more elaborate protocol such as Felipe's gave/giver one. Copying loses the benefit of shared defaults via prototype. I would rather see a method to flatten an object before enumeration than lose the flexibility of shared state. That might be handy but Felilpe's gave/giver protocol still seems necessary in general (if you can't assume no one has decorated intermediate prototypes with enumerable properties that should not be considered). The flattening idea reminds me of traits (http://traitsjs.org/), since you might want different conflict-handling policies in case of shadowing. The default could shadow. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
On 11/8/11 2:19 PM, Jake Verbaten wrote: Flexibility of shared state? Are you really corrupting the state of defaults at runtime? Do you really want changes to your default options to propogate to all objects extending the defaults? It’s the same thing as redefining a method inherited from a prototype. Why would you extend the default at all if you *don’t* want changes to it to propagate to descendents? If you don’t want propagation, make a copy. This seems like a right pain in the ass to debug/maintain? In some cases, maybe; in other cases, I think not. It also can better model what’s going on: if the schema conceives of multiple objects explicitly sharing the same default, then yes, you *do* want descendents of the parent to stay in sync with the parent (unless the descendents themselves have set values). That seems very intuitive to me. If you *want* a descendent to be independent of the parent, then don’t make it a descendent; make it a copy. FWIW, the YUI thing was pretty unintuitive to me and took me a while to “debug”. -FG ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
The recommended practice when writing for-in loops in JS today is to write: for (i in o) { if (o.hasOwnProperty(i)) { body } } Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). 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. /be___ 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 8 November 2011 20:46, Mark S. Miller erig...@google.com wrote: In general, for an object to be defensive, much of the surface reachable from it by transitive prototype and reflective property traversal should usually be frozen, and at least non-extensible. This is possible to express in ES5 http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#623, but inconvenient and expensive. That's why I have been advocating better defensive abstractions for ES6: const functions, const classes, traitsjs or its syntactic derivatives, etc. 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. 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. /Andreas ___ 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 11/8/11 2:49 PM, Brendan Eich wrote: 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. This is a fantastic idea, IMO. The hasOwnProperty() thing is buggy if you create a “hasOwnProperty” property on the object, and it’s wordy besides. -FG ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
On 11/8/11 2:19 PM, Brendan Eich wrote: On Nov 8, 2011, at 12:12 PM, Luke Smith wrote: Sure. People make classes by defining function C(){} and decorating C.prototype.method1 = function(...){...}, etc. A for-in loop on (new C) will see all the methods, unlike the case with built-in constructors. That is an unwanted abstraction break: we should support abstracting over user-defined and built-in functions. I believe people decorate a class prototype directly because they always have, and because defineProperties wasn't available for them to declare prototype methods as not enumerable, not because they explicitly want class proto methods to be enumerable. Yup, that's a fact. However it contradicts Felipe's belief that only Object.prototype might-be-enumerable properties need to be excluded, which was my point. Wasn’t so much a *belief* as an observation that the reasons most folks give for wanting the hasOwnProperty() check in for..in loops are similar to what Crockford wrote here: http://www.yuiblog.com/blog/2006/09/26/for-in-intrigue/ …i.e., the “main” concern, esp. if you inherit objects from just anywhere (e.g., YUI’s config objects), is Object.prototype. The case Brendan mentions is closer to what I had in mind as a reason for the more fine-grained control of gave(). In Brendan’s case: --- function C(){}; C.prototype.foo = function(){}; var my_c = new C(); my_c.bar = null; --- …it makes sense to weed out stuff from the prototype. Even then, though, it might be equally, or more, gainful to check for: --- for (key in my_c) { if ( !C.gave(key,my_c) ) { … } } --- …or, at least, there could be multiple use cases, e.g. multiple levels of inheritance, and I want to filter out either *just* the original (gave/giver) or all prototypes (hasOwnProperty()). Anyhow. Thanks to everyone for the bandwidth on the idea. -FG ___ 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 Tue, Nov 8, 2011 at 12:49 PM, Brendan Eich bren...@mozilla.com wrote: The recommended practice when writing for-in loops in JS today is to write: for (i in o) { if (o.hasOwnProperty(i)) { body } } Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). 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. Just as a point of comparison, I use this form: Object.keys(o).forEach( function(key) { body }); I would use |for own| if it existed, solely to avoid thinking about overhead and because single stepping would work better. jjb ___ 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)
I see two domains for the concept of “own” properties: 1. Meta-programming. 2. Using objects as dictionaries. Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts? I also like the Python-style iterator-based approach, e.g. something like the following: for ([key,value] on pairs(obj)) { } On Nov 8, 2011, at 21:49 , Brendan Eich wrote: 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. -- 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 Tue, Nov 8, 2011 at 3:49 PM, Brendan Eich bren...@mozilla.com wrote: for own (i in o) { *body* } This is a small thing but it might pay off in the long run. This is a very useful feature ... but for better or for worse, also shows off how much paren-free would help things. for own key in object { reads well, whereas for own (key in object) { reads strangely, because the adjective own naturally belongs next to it's nown key, without an interloping lparen. ___ 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)
Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that. http://jsperf.com/hasownproperty-vs-for-in/4#c300 On Tue, Nov 8, 2011 at 3:49 PM, Brendan Eich bren...@mozilla.com wrote: The recommended practice when writing for-in loops in JS today is to write: for (i in o) { if (o.hasOwnProperty(i)) { *body* } } Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). 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. /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: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
for own (i in o) { body } What happened to @iter.keys and 'for (key of keys) {}'? http://wiki.ecmascript.org/doku.php?id=harmony:iterators Claus http://clausreinke.github.com/ http://clausreinke.github.com/js-tools/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
Le 08/11/2011 08:59, Felipe Gasper a écrit : Hi everyone, There is a widespread practice of doing this: - for (key in obj) { if (obj.hasOwnProperty(key)) { … } } - The oft-stated purpose for this pattern is to weed out code that comes from Object.prototype. The result, though, is that we prevent iteration through *any* inherited properties, which seems like overkill for handling the original problem. (...) So, a solution I am considering for my own work defines two methods: Object.gave(giver, key, obj) Function.prototype.gave(key,obj) They do what they look like: Object.gave checks if the “giver” really “gave” the “key”ed value to the “obj”ect. The Function.prototype version does the same but assigns the function’s prototype as “giver”. (The original Object.gave() offloads to the prototype method if called with just two args.) Thus: -- var HOP = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); Object.gave = function(giver,key,obj) { if (arguments.length === 2) { Function.prototype.gave.apply(this,arguments); } var last_prototype; while ( obj !== giver ) { if (HOP(obj,key) || (obj === last_prototype)) return false; last_prototype = obj; obj = Object.getPrototypeOf(obj); } return true; }; Function.prototype.gave = function(key,obj) { return Object.gave( this.prototype, key, obj ); }; -- Then, we can do: -- for (var key in obj) { if (Object.gave(key,obj)) { … } } -- …which will still filter out anything in Object.prototype, but will allow iteration through inherited properties. This seems to me far more useful in general than the hasOwnProperty() check. Thoughts? Specifically regarding not enumerating Object.prototype properties, why not make every Object.prototype property non-enumerable at the beginning of your program? - for(p in Object.prototype) Object.defineProperty(Object.prototype, p, {enumerable:false}); - Afterward, for any for..in loop, all properties (own or inherited) of your object are enumerated except the Object.prototype ones. It makes less properties to iterate over, it removes the .hasOwnProperty or Object.gave test. It only break scripts which rely on and expect Object.prototype properties being enumerated in a for..in loop (which I am not sure there are many out there) If you ever care about enumerating Object.prototype properties, Object.getOwnPropertyNames is still here. Of course, I do not cover the case Function.prototype.gave covers. David ___ 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 08/11/11 18:49, Brendan Eich wrote: The recommended practice when writing for-in loops in JS today is to write: for (i in o) { if (o.hasOwnProperty(i)) { /body/ } } Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). 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. Isn't that just: Object.keys(o).forEach(function(i){ body }) Iirc, that's faster than a for..in loop with filter in v8 due to the aggressive function inlining, not sure about SpiderMonkey. It also reads better and it's more composable -- for me, at least. I do use keep `var keys = Object.keys' and other hand aliases though. It still seems to me it's overkill to add special syntax (and a new reserved word, yuck!) to something that isn't really worth it, given the Object API already provides those methods. Also, are Object.values and Object.items standardised in ES.next. They're quite useful? /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: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On 08/11/11 19:19, Axel Rauschmayer wrote: I see two domains for the concept of “own” properties: 1. Meta-programming. Could you expand on the use of `own' properties for meta-programming? I'm afraid I can't really envision it =/ 2. Using objects as dictionaries. Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts? I would think most of the cases where objects are used as dicts would be solved by using `Object.create(null)', today on ES5-compliant engines. Except for the nasty, nasty `__proto__' on engines that use that magic, but then you can proxy property access/assignment. It's quite ad-hoc, but works. The dicts proposal looks nice though. ___ 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 08/11/2011 21:49, Brendan Eich a écrit : The recommended practice when writing for-in loops in JS today is to write: for (i in o) { if (o.hasOwnProperty(i)) { /body/ } } As said in the thread your forked from, this practice is often recommended to not enumerate Object.prototype methods (rather than enumerating only own properties) Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). 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. Why would developers use for own while they currently do not use hasOwnProperty? I really am skeptical on this. Enumeration of own enumerable properties can be done with Object.keys. Why not encourage people to use this? Are you also proposing an addition of for own (... of ...) if for-own-in and for-of are both accepted? David ___ 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)
I see two domains for the concept of “own” properties: 1. Meta-programming. Could you expand on the use of `own' properties for meta-programming? I'm afraid I can't really envision it =/ Whenever you copy properties from one object to another one, you are usually doing meta-programming (unless you use an object as a dictionary). 2. Using objects as dictionaries. Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts? I would think most of the cases where objects are used as dicts would be solved by using `Object.create(null)', today on ES5-compliant engines. Except for the nasty, nasty `__proto__' on engines that use that magic, but then you can proxy property access/assignment. It's quite ad-hoc, but works. The dicts proposal looks nice though. Modulo what Allen is proposing for [] to keep program domain and data domain separate. Then dicts can actually get a size() method. -- 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 Tue, Nov 8, 2011 at 1:45 PM, Timmy Willison timmywill...@gmail.com wrote: Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that. http://jsperf.com/hasownproperty-vs-for-in/4#c300 Added case Object.keys().forEach: http://jsperf.com/hasownproperty-vs-for-in/7 Of course results depend more on browser than form of the loop... jjb ___ 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 8, 2011, at 1:19 PM, Axel Rauschmayer wrote: I see two domains for the concept of “own” properties: 1. Meta-programming. 2. Using objects as dictionaries. Thanks, good to focus on use-cases. Both would like shorthand and freedom from Object.prototype.hasOwnProperty tamper-proofing. Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts? We don't know how dicts will fare. Making progress with for own does not interact badly with dicts if we spec them to be for-in'able -- for own (k in d) for d a dict should work, just as for objects. I also like the Python-style iterator-based approach, e.g. something like the following: for ([key,value] on pairs(obj)) { } s/on/of/ I like that too, and we have keys/values/items in the strawman (items, not pairs -- after Python). These are own-only. But plain old for-in still benefits from own. If 'for (let k of keys(obj))' is good enough to de-motivate 'for own (let k in obj)', great. The latter is only slightly shorter (two chars, the way I've coded it with space after own, for the parens saving), but more important: it is a simpler upgrade to existing for-in loops that otherwise need rewriting. /be On Nov 8, 2011, at 21:49 , Brendan Eich wrote: 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. -- 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 Nov 8, 2011, at 1:19 PM, Jeremy Ashkenas wrote: On Tue, Nov 8, 2011 at 3:49 PM, Brendan Eich bren...@mozilla.com wrote: for own (i in o) { body } This is a small thing but it might pay off in the long run. This is a very useful feature ... but for better or for worse, also shows off how much paren-free would help things. for own key in object { reads well, whereas for own (key in object) { reads strangely, because the adjective own naturally belongs next to it's nown key, without an interloping lparen. You'll be glad to know I'm still working on paren-free. You will be unsurprised to hear it needs even more newline significance to overcome some issues Waldemar Horwat pointed out. I give paren-free very long odds for ES.next. Better to design and prototype it, get it in as an opt-in for Narcissus, SpiderMonkey and other implementations to enable user-testing. Good news for ES.next remains: array comprehensions and generator expressions use *only* paren-free for/of syntax. /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 8, 2011, at 1:48 PM, Claus Reinke wrote: for own (i in o) { body } What happened to @iter.keys and 'for (key of keys) {}'? Still there, but write it out fully, to compare to the cited text: import keys from @iter; for (i of keys(o)) { body } Unless we default-import a standard prelude, this is a bit much compared to add own as a modifier after for in for/in (not for/of) loops. /be http://wiki.ecmascript.org/doku.php?id=harmony:iterators Claus http://clausreinke.github.com/ http://clausreinke.github.com/js-tools/ ___ 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 08/11/11 20:22, Axel Rauschmayer wrote: I see two domains for the concept of “own” properties: 1. Meta-programming. Could you expand on the use of `own' properties for meta-programming? I'm afraid I can't really envision it =/ Whenever you copy properties from one object to another one, you are usually doing meta-programming (unless you use an object as a dictionary). Hm, I see. I always tend to think of meta-programming in the Lisp sense (macros that mutate the AST), but I guess I see the point in generating objects dynamically. ___ 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 8, 2011, at 2:03 PM, Quildreen Motta wrote: On 08/11/11 18:49, Brendan Eich wrote: The recommended practice when writing for-in loops in JS today is to write: for (i in o) { if (o.hasOwnProperty(i)) { body } } Although many JS developers do not follow the recommendation (out of ignorance or intentionally, doesn't matter). 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. Isn't that just: Object.keys(o).forEach(function(i){ body }) Good grief. Your just is pointing the wrong way. The longer, more contingent in terms of mutable global and Object property bindings, form is not the primitive one. Iirc, that's faster than a for..in loop with filter in v8 due to the aggressive function inlining, not sure about SpiderMonkey. It's not necessarily faster or slower, implementations vary. And what is the length of the necessarily-reified, returned keys array? Have you tested large objects? You can use it if you like (performance is not usually overriding). It also reads better and it's more composable -- for me, at least. YMMV. Again, ES.next already will support for (let i in keys(o)) { body } if you have keys imported. There is no there must be only one way to say things in JS dogma in JS; this is a feature. I do use keep `var keys = Object.keys' and other hand aliases though. It still seems to me it's overkill to add special syntax (and a new reserved word, yuck!) No new unconditionally reserved word. Rather, contextually reserved after 'for', no impact on other uses of 'own'. ECMA-357 (E4X) did likewise with 'for each(... in ...)'. Overkill may be writing a function around one's code just to call an array extra on a reified array of keys. Iterators can be much faster. Here's another, more real-world concern: wrapping //body// in function (){...} breaks the principle of equivalence (TCP) and people can and do fail to capture the outer |this|, e.g. by var self = this, and propagate it to the revised //body// as self. Tom Van Cutsem had such a bug, Mark Miller has seen such bugs. They are serious runtime type/instance confusion bugs, possibly with security implications. (Block-lambdas would help here, shameless plug -- but let's stay on target.) to something that isn't really worth it, given the Object API already provides those methods. for-in loops are quite commonly used. Object.keys is new and while people polyfill it, practice varies wildly. Also, are Object.values and Object.items standardised in ES.next. They're quite useful? They are *not* object methods, and you're mistaking Object.keys for the @iter module's keys function. Returning iterators instead of eager arrays is a serious perf win for large objects. /be /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 ___ 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 12:50 PM, Andreas Rossberg rossb...@google.comwrote: 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. A program should not only work. It should also appear to work. --Carl Hewitt. -- Cheers, --MarkM ___ 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)
I see two domains for the concept of “own” properties: 1. Meta-programming. 2. Using objects as dictionaries. Thanks, good to focus on use-cases. Both would like shorthand and freedom from Object.prototype.hasOwnProperty tamper-proofing. Isn’t #2 the majority (at least as far as non-library-programmers are concerned)? Will the concept become less relevant once we have David Herman’s dicts? We don't know how dicts will fare. Making progress with for own does not interact badly with dicts if we spec them to be for-in'able -- for own (k in d) for d a dict should work, just as for objects. Ah, shame. I had hoped that a good dictionary implementation would largely make the notion of own properties obsolete (except for #1 use cases). Bringing inheritance into the collection mix seems problematic. That’s why I like Allen’s “data-only-[]” proposal. I agree with “not interact badly” if there are indeed other use cases. -- 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: Lecture series on SES and capability-based security by Mark Miller
Perhaps __proto__ should not be writeable in use strict? That's a great idea! This never occurred to me, and I have not heard anyone suggest this. Thanks! Doesn't work. obj[(function(__){return __ + proto + __})(__)] 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 8, 2011, at 2:26 PM, John J Barton wrote: On Tue, Nov 8, 2011 at 1:45 PM, Timmy Willison timmywill...@gmail.com wrote: Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that. http://jsperf.com/hasownproperty-vs-for-in/4#c300 Added case Object.keys().forEach: http://jsperf.com/hasownproperty-vs-for-in/7 Of course results depend more on browser than form of the loop... 54 properties per object, if my skimming is accurate (is it?). Not enough to show the difference in keys allocating an array vs. some internal snapshot or iterator used by for..in. Lots of confounding variables here. Firefox 8 wins top prize but only for the for-in loop without hasOwn guard. FF9 has type inference, so may do better still. More work on inlining should level the scores. But this kind of performance is an ongoing arms race, and it's usually wrong to bend your coding style around particular results -- especially for small objects where the keys array allocation, and even a not-inlined function expression call, do not matter. POitRoaE. 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. Finally, there ain't just one way to say it in JS. We'll have Object.keys(o).forEach(function(v,i){...}) *and* (in ES.next) for (i of keys(o))... or for ([k,v] of items(o))... given the module imports or a standard prelude. /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 8, 2011, at 2:26 PM, John J Barton wrote: On Tue, Nov 8, 2011 at 1:45 PM, Timmy Willison timmywill...@gmail.com wrote: Yes, I think JS needs something like this. This is new to no one here, but my main concern with using hasOwnProperty is the loss of performance, so I think it would be worth exploring more than just syntactic sugar. But I don't know how realistic it is to hope for that. http://jsperf.com/hasownproperty-vs-for-in/4#c300 Added case Object.keys().forEach: http://jsperf.com/hasownproperty-vs-for-in/7 Also, isn't this like jsperf.com? Random people running on different machines upload results without any normalization? Just asking, not really my point (since I think performance is only one consideration, and for non-large objects probably not significant unless the loop is called at high frequency). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Lecture series on SES and capability-based security by Mark Miller
On Tue, Nov 8, 2011 at 3:33 PM, David Herman dher...@mozilla.com wrote: Perhaps __proto__ should not be writeable in use strict? That's a great idea! This never occurred to me, and I have not heard anyone suggest this. Thanks! Doesn't work. obj[(function(__){return __ + proto + __})(__)] If the [ above is a strict [, it should not be able to address __proto__, regardless of whether the __proto__ is computed or not. Or if we intend only to suppress writing, then obj[(function(__){return __ + proto + __})(__)] = {} should still fail if the [ above is in strict code. Dave -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Lecture series on SES and capability-based security by Mark Miller
On Tue, Nov 8, 2011 at 3:46 PM, Mark S. Miller erig...@google.com wrote: On Tue, Nov 8, 2011 at 3:33 PM, David Herman dher...@mozilla.com wrote: Perhaps __proto__ should not be writeable in use strict? That's a great idea! This never occurred to me, and I have not heard anyone suggest this. Thanks! Doesn't work. obj[(function(__){return __ + proto + __})(__)] If the [ above is a strict [, it should not be able to address __proto__, regardless of whether the __proto__ is computed or not. Or if we intend only to suppress writing, then obj[(function(__){return __ + proto + __})(__)] = {} should still fail if the [ above is in strict code. Sorry, it should not fail. It should simply create a normal property that happens to be named __proto__. Likewise, your first example should simply address such a normal property. Then JSON would again be an almost-subset of ES5/strict, modulo \u2028 and \u2029. Dave -- Cheers, --MarkM -- Cheers, --MarkM ___ 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 Tue, Nov 8, 2011 at 6:36 PM, Brendan Eich bren...@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. -Andrew ___ 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 08/11/11 21:36, Brendan Eich 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. Well, I use Object.keys, etc, a lot thorough my code. I can't remember a case where I forgot to pass the `thisObject' parameter to the `forEach'/`map' call in the last months, though it was weird when I transitioned to a more functional coding style. I guess the number of cases I was bitten by the wrong |this| in the beginning is about the same number of ASI issues I ran into when I started using destructuring assignments for arrays. I'd assume that has a lot to do with coding habits — writing without properly thinking. `reduce' and `reduceRight' don't have a `thisObject' argument. Why are they the only odd ones? ___ 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 Tue, Nov 8, 2011 at 11:36 PM, Brendan Eich bren...@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. /be I personally use `Object.keys()` on all my objects just because it's a neater construct. I havn't really run into much problems with the `this` value. None more then I would be forgetting it on any other inner function. As an aside `break and continue` are emulated using `Object.keys(o).any`. But that is rarely done. Trying to access outer arguments or returning from inside the loop is also rare. the former is gaurded by unpacking arguments at the top of the function and the latter is gaurded by using `.any` again and propagating the return value. (Most of the time if I return from a loop it's a boolean) However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim ___ 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 08/11/11 23:59, Jake Verbaten wrote: However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim Do you mean `rare' as in they have to work with the lowest common denominator (IE)? Because ES5-not-so-fully-but-somewhat-there-for-most-common-stuff environments are the majority, afaik. ___ 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)
In the real world IE9 still accounts for almost 50% of browsers. Then there's another 6% for FF3.6 and another 3% for opera. As much as I like promoting that you should ignore legacy browsers, for most people 50% market share is a good enough reason to support them. On Wed, Nov 9, 2011 at 2:03 AM, Quildreen Motta quildr...@gmail.com wrote: On 08/11/11 23:59, Jake Verbaten wrote: However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim Do you mean `rare' as in they have to work with the lowest common denominator (IE)? Because ES5-not-so-fully-but-somewhat-**there-for-most-common-stuff environments are the majority, afaik. __**_ 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: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
Still there, but write it out fully, to compare to the cited text: import keys from @iter; for (i of keys(o)) { body } Unless we default-import a standard prelude, I think we should. this is a bit much compared to add own as a modifier after for in for/in (not for/of) loops. For for-of semantics is one of the places we've bought into a do-over for a JS form. It muddies the waters to say for-of is the new for-in but also halfway reform for-in at the same time. I don't really think for (i of keys(o)) { /body/ } is such a burden (two characters, as you say). Instead of taking a hard-to-use-right form like for-in and partly taming it, I'd rather suggest people simply move to for-of, and have the default keys iterator Do The Right Thing and only iterate over own, enumerable property names (thanks to Yehuda and Arv for straightening us out on this point recently). Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Lecture series on SES and capability-based security by Mark Miller
http://www.google.com/support/forum/p/Google+Docs/thread?tid=0cd4a00bd4aef9e4 But yes. Because the difference would be silent, I'm skeptical too. On Tue, Nov 8, 2011 at 8:23 PM, David Herman dher...@mozilla.com wrote: And another silent semantic change? I wouldn't be so quick to do that. And that's not the direction we were going for __proto__ in the last f2f. I *wish* __proto__ were just treated as another normal property. And I'd like for us to work towards a future where that's the case. I'm just skeptical we can do it by cramming it into strict mode. Dave On Nov 8, 2011, at 3:50 PM, Mark S. Miller wrote: On Tue, Nov 8, 2011 at 3:46 PM, Mark S. Miller erig...@google.com wrote: On Tue, Nov 8, 2011 at 3:33 PM, David Herman dher...@mozilla.com wrote: Perhaps __proto__ should not be writeable in use strict? That's a great idea! This never occurred to me, and I have not heard anyone suggest this. Thanks! Doesn't work. obj[(function(__){return __ + proto + __})(__)] If the [ above is a strict [, it should not be able to address __proto__, regardless of whether the __proto__ is computed or not. Or if we intend only to suppress writing, then obj[(function(__){return __ + proto + __})(__)] = {} should still fail if the [ above is in strict code. Sorry, it should not fail. It should simply create a normal property that happens to be named __proto__. Likewise, your first example should simply address such a normal property. Then JSON would again be an almost-subset of ES5/strict, modulo \u2028 and \u2029. Dave -- Cheers, --MarkM -- Cheers, --MarkM -- Cheers, --MarkM ___ 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 8, 2011, at 9:08 PM, Jake Verbaten rayn...@gmail.com wrote: In the real world IE9 still accounts for almost 50% of browsers. Then there's another 6% for FF3.6 and another 3% for opera. Latest Opera builds are 100% ES5.1 compliant. (according to opera dev-rel) As much as I like promoting that you should ignore legacy browsers, for most people 50% market share is a good enough reason to support them. On Wed, Nov 9, 2011 at 2:03 AM, Quildreen Motta quildr...@gmail.com wrote: On 08/11/11 23:59, Jake Verbaten wrote: However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim Do you mean `rare' as in they have to work with the lowest common denominator (IE)? Because ES5-not-so-fully-but-somewhat-there-for-most-common-stuff environments are the majority, afaik. ___ 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
Standard Prelude (was: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance))
On Nov 8, 2011, at 8:39 PM, David Herman wrote: Instead of taking a hard-to-use-right form like for-in and partly taming it, I'd rather suggest people simply move to for-of, and have the default keys iterator Do The Right Thing and only iterate over own, enumerable property names (thanks to Yehuda and Arv for straightening us out on this point recently). I'm with you -- for-of is the new for-in, let is the new var. So, what is imported as part of the standard prelude when one opts into ES.next? module Name from @name; import {iterator, keys, values, items} from @iter; ? /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Standard Prelude (was: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance))
Let's answer this once we have the module-ized version of the standard library. Which I've been promising for far too long (mea culpa). Will get started on this tonight. Dave On Nov 8, 2011, at 9:04 PM, Brendan Eich wrote: On Nov 8, 2011, at 8:39 PM, David Herman wrote: Instead of taking a hard-to-use-right form like for-in and partly taming it, I'd rather suggest people simply move to for-of, and have the default keys iterator Do The Right Thing and only iterate over own, enumerable property names (thanks to Yehuda and Arv for straightening us out on this point recently). I'm with you -- for-of is the new for-in, let is the new var. So, what is imported as part of the standard prelude when one opts into ES.next? module Name from @name; import {iterator, keys, values, items} from @iter; ? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Lecture series on SES and capability-based security by Mark Miller
One more thought: people are already avoiding use strict; because it bites back: * concatenation with non-strict code and under-testing, but let's hope we are past this now; * performance dinged a bit by strict mode, or at least non-strict calling strict and vice versa. We should try to avoid taking away the forbidden fruit prematurely. In particular since ES6 is based on ES5 strict. When | is out and well-deployed, maybe. No predictable schedule for when we could actually hope to remove __proto__. /be On Nov 8, 2011, at 8:57 PM, Mark S. Miller wrote: http://www.google.com/support/forum/p/Google+Docs/thread?tid=0cd4a00bd4aef9e4 But yes. Because the difference would be silent, I'm skeptical too. On Tue, Nov 8, 2011 at 8:23 PM, David Herman dher...@mozilla.com wrote: And another silent semantic change? I wouldn't be so quick to do that. And that's not the direction we were going for __proto__ in the last f2f. I *wish* __proto__ were just treated as another normal property. And I'd like for us to work towards a future where that's the case. I'm just skeptical we can do it by cramming it into strict mode. Dave On Nov 8, 2011, at 3:50 PM, Mark S. Miller wrote: On Tue, Nov 8, 2011 at 3:46 PM, Mark S. Miller erig...@google.com wrote: On Tue, Nov 8, 2011 at 3:33 PM, David Herman dher...@mozilla.com wrote: Perhaps __proto__ should not be writeable in use strict? That's a great idea! This never occurred to me, and I have not heard anyone suggest this. Thanks! Doesn't work. obj[(function(__){return __ + proto + __})(__)] If the [ above is a strict [, it should not be able to address __proto__, regardless of whether the __proto__ is computed or not. Or if we intend only to suppress writing, then obj[(function(__){return __ + proto + __})(__)] = {} should still fail if the [ above is in strict code. Sorry, it should not fail. It should simply create a normal property that happens to be named __proto__. Likewise, your first example should simply address such a normal property. Then JSON would again be an almost-subset of ES5/strict, modulo \u2028 and \u2029. Dave -- Cheers, --MarkM -- Cheers, --MarkM -- Cheers, --MarkM ___ 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 Tue, Nov 8, 2011 at 9:03 PM, Rick Waldron waldron.r...@gmail.com wrote: Latest Opera builds are 100% ES5.1 compliant. (according to opera dev-rel) The latest externally visible Opera is Opera 12 alpha build 1116. It is indeed very close to ES5.1 compliant. But it still fails http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.3/15.3.4/15.3.4.5/S15.3.4.5_A5.js http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch08/8.6/8.6.2/S8.6.2_A8.js http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.1/15.1.2/15.1.2.2/S15.1.2.2_A5.1_T1.js And http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch10/10.4/10.4.2/S10.4.2.1_A1.js is currently disabled because it crashes Opera 12 alpha. The second one, S8.6.2_A8.js, is important. -- Cheers, --MarkM ___ 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 12:12 AM, Mark S. Miller erig...@google.com wrote: On Tue, Nov 8, 2011 at 9:03 PM, Rick Waldron waldron.r...@gmail.comwrote: Latest Opera builds are 100% ES5.1 compliant. (according to opera dev-rel) The latest externally visible Opera is Opera 12 alpha build 1116. It is indeed very close to ES5.1 compliant. But it still fails http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.3/15.3.4/15.3.4.5/S15.3.4.5_A5.js http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch08/8.6/8.6.2/S8.6.2_A8.js http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.1/15.1.2/15.1.2.2/S15.1.2.2_A5.1_T1.js And http://hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch10/10.4/10.4.2/S10.4.2.1_A1.js is currently disabled because it crashes Opera 12 alpha. The second one, S8.6.2_A8.js, is important. The point that I was that Opera didn't deserve to be listed among the lost causes, but thanks for the point for point rebuttal ;) /Rick -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss