Re: [[OwnPropertyKeys]] key ordering
The proposed ordering for [[OwnPropertyKeys]] is the same as the current for..in ordering in the latest versions of most browsers. As Allen pointed out, this group has basically declined to specify for..in ordering, and specifying an order for [[OwnPropertyKeys]] *technically* leaves for..in order unspecified. However, I believe that specifying an order for [[OwnPropertyKeys]] *effectively* specifies the order of for..in iteration, for the practical reason that browser implementers are really unlikely to provide two possible orderings. It would require a bunch of extra data structures and indices to offer good performance for multiple possible orderings. Given this, I would suggest that if ECMA is going to specify an order for [[OwnPropertyKeys]], it's time to go ahead and specify for..in iteration order too. Regardless of what the ordering is (what I prefer, or what Allen proposed), if for..in ordering is *technically* unspecified but implementation concerns basically require a particular order, that's the worst of all outcomes: every browser is consistent and the matter is really settled, but no one can rely on it. However, for the record, I continue to think that special treatment of numeric keys is a really bad design for property order for Objects (for Arrays, it's fine). To summarize the arguments that seemed to play best with members of this group: 1. special treatment of Array indices is surprising If we're spec'ing that order is preserved for String properties, people will continue to routinely use Objects as ordered maps [1]. This leads to the gotcha that some properties fall out of order, just because they happen to be parsable as numbers, even if you explicitly quoted the property name in your code. Consider: var extensions = { 0110:Marketing, 1225:Development, 0301:Support }; This way of specifying phone extensions in order would work, except that Development is inexplicably placed first because 1225 is an array index. To be crystal clear: I'm not raising this as a backwards compatibility issue (which some people seem to take as a cue to argue uselessly about who is to blame..). What I'm saying is that this is a gotcha being permanently enshrined in the spec, that will bite people from time to time for as long as ECMAScript is in use. 2. treating array index keys specially loses information If order was preserved, an Object would be a very convenient structure for storing the list of available options in order, as a map from stored integer values to user-visible Strings: var availableOptions = { 9 : Fixed 3 : Won't Fix 5 : Invalid }; Not being able to to do this is a loss of expressiveness for a *very* common use case in database-oriented apps. 3. treating array indices as special does not match any known use case No one has identified any application in which it would be desirable for *Object* (again *not* Array) to have this particular quirk of property ordering. It's purely an optimization detail leaking through. [1] if anyone doubts that using Objects as ordered maps has been a long-standing practice, just look at the record-setting 178 stars and long comment thread on just one of the several bugs filed against Chrome for not preserving order for integer keys: https://code.google.com/p/v8/issues/detail?id=164 There's no reason to assume this practice will go away, especially since savvy developers will now know that it's safe to assume order preservation for String keys. On Sat, Apr 19, 2014 at 12:17 PM, Brendan Eich bren...@mozilla.org wrote: Did you check against http://wiki.ecmascript.org/doku.php?id=strawman: enumeration which links off to this es-discuss thread: https://mail.mozilla.org/pipermail/es-discuss/2011-March/012965.html Sounds good, just asking for a look-back at the big thread and strawman to see if there are any missing subtleties others have pointed out in the past. /be Allen Wirfs-Brock wrote: The ordering I propose is: 1) All array index property keys, in ascending array index numeric order. Followed by: 2) All other string property keys, in property creation order. Followed by: 3) All symbol property keys, in property creation order Does anybody see any reason why we shouldn't specify (this) property ordering? ___ 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: Error stack
On Tue, Jun 12, 2012 at 5:19 AM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 12, 2012 at 10:14 AM, Charles Kendrick char...@isomorphic.com wrote: The only way I can see this working is if there is a way for a given piece of code to trap an error and ask some kind of (elevated privilege) logging system to provide diagnostic information that a (privileged) end user can see. I'm not sure what you mean by trap to an error, My actual words were to trap an error so that probably explains the confusion :) but the rest of your description seems close to how SES's console.log, console.warn, etc work. They are endowed with access to the privileged getStack function and use it to display stack traces on the console's output. See http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/logger.js#28 http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/logger.js#157 http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/useHTMLLogger.js#116 Yes, this is the pattern I had in mind. This also means there would be no need to worry about exposing too much information in a stack trace. It also seems like, in addition to this, you should be able to get to stack information programmatically so long as you stay within your module or modules that have the same privilege. If we're talking about code with some privilege to see some stacks, why not reify such privilege in a getStack function importable from some @privileged module? I don't have an objection to this being treated as an import. This doesn't sound like something that could be reasonably standardized into ECMAScript in the near future, and, without all those pieces in place, it doesn't seem like ECMAScript should just disallow the ability to get stack traces. In this thread, we've already considered APIs other than .stack. Given anything else, why is getStack(err) is any worse than introducing a novel property name? There's no problem with the API being changed to a getter method as opposed to error.stack / error.stackFrames. It would be a problem for access to a stack trace to require @import or other features that are not yet present in all mainstream browsers. If browser implementers cannot add this feature to engines which are basically only ES4/5, it's not going to be usable for mainstream code until 2019 or something - in reality, non-standard APIs will continue to be implemented and used. Regarding near future, any such proposal -- whether .stack, getStack, or whatever -- has already missed the boat for ES6. getStack certainly could be considered in an ES7 timeframe. Fortunately, these milestones have little to do with when features appear in browsers. And this is one of those features where it's valuable the moment it appears in just one browser. All we really need is clear consensus, so as to influence browser vendors' existing efforts in this area. Just to clarify, I prefer *some* of the ideas behind use strict and in fact we built a subset of use strict into our in-house tools long before JSLint existed. But if it's going to impose a security boundary between my own methods and reduce the utility of stack traces which are sometimes the only thing you have to go on.. no thank you. That seems to me to conflate useful error checking and security; there is overlap, but not 100% overlap by any means. How do getStack and @privileged reduce the utility of stack traces? They don't. The above discussion is about use strict and is not about SES. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
On Sat, Jun 9, 2012 at 12:26 PM, Brendan Eich bren...@mozilla.org wrote: We do not want a non-debugger API that works only some of the time. What we want (IMO) is an API that allows runtime diagnostics to be collected. By necessity, function arguments would be unavailable for some stack frames. This is not a new situation or a flaw in the proposal, it's a situation which exists already for the function.arguments API. Debuggers, in contrast, must be able to pierce the veil of use strict. Clearly. A debugger API is further off from standardization. Mozilla has a new one: ... This is great but pretty much unrelated - clearly we shouldn't cripple a runtime diagnostic API because there's a debugger API - these are two different use cases. Let's get concrete here - because function.arguments is actually available but not exposed by error.stack, we have implemented a system that parses error.stack, using its information to find live function instances, grabs the arguments and receiver from those and injects them into a new, enhanced stack trace which we log. And of course we have to cover the recursive case and show the arguments as not available.. Because runtime diagnostic information like this is so critical, you'll see this approach being taken by a bunch of frameworks - don't you find this distasteful and a clear indication that the standard should be exposing this information directly? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
It seems to me we've lost the thread (maybe you haven't, but I have -- apologies for revisiting). In a nutshell, I'm looking for access to function arguments, the receiver, and ideally even local variable values via *some* runtime diagnostic API. These could be all be exposed in an error.stack String or in a more OO API (say, error.stackFrames as an array of objects with various properties). I think the best solution is to have *both*. In the field right now, error.stack is a String. Adding error.stackFrames this would mean: 1. we avoid breaking code in the field 2. we provide a convenient error.stack for people who don't want to deal with error.stackFrames 3. we avoid people who want to add richer information having to parse an error.stack String 4. we eliminate all the issues we're running into in trying to standardize error.stack; it wouldn't be so important for it to expose more information or have really smart formatting rules like I previously proposed [1]. It would no longer need to be machine parsable. It might even be OK for it's format to remain completely unspecified since it's just a convenience. The confusing bit: Erik objected to making arguments available in error.stack for security reasons, and Erik is correct that use strict implies arguments would not be available in that case. However, I see no issue with error.stack or an error.stackFrames API providing function arguments *only when allowed*; it's not a new security issue or a new burden on browser / VM implementers since they must already correctly implement security checks for the equivalent function.arguments API. [1] https://mail.mozilla.org/pipermail/es-discuss/2012-June/023247.html On Mon, Jun 11, 2012 at 12:57 PM, Brendan Eich bren...@mozilla.org wrote: Charles Kendrick wrote: On Sat, Jun 9, 2012 at 12:26 PM, Brendan Eichbren...@mozilla.org wrote: We do not want a non-debugger API that works only some of the time. What we want (IMO) is an API that allows runtime diagnostics to be collected. By necessity, function arguments would be unavailable for some stack frames. This is not a new situation or a flaw in the proposal, it's a situation which exists already for the function.arguments API. It seems to me we've lost the thread (maybe you haven't, but I have -- apologies for revisiting). I replied because of this flow: CK: Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking? EA: Stack walking is not available in strict functions CK: Interesting, but it doesn't speak against programmatic access to the call stack. At this point I'm not sure what you want -- object references to calling functions? You're right that we could disclose those where use strict does not poison function.arguments and arguments.callee already, but to what end? Erik's proposal was about standardizing a string-valued .stack property. If we can't have a common string-valued .stack property, we could still make a new one (.stackString or some such; yech) that doesn't include object references. Is there a strong motivation for sometimes exposing (where use strict allows) object references, or would your use-cases be met by some better string-valued spec? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
Your point about not violating use strict or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier. I definitely recognize that making local vars available is different-in-kind from making function arguments available. However I would ideally like to see it mentioned in the spec with recommended but not required wording. However what about receivers / this value? That seems to me to be more in the realm of function arguments, and reasonable to require. As I mentioned previously, this is available from Chrome's JavaScriptStackTrace API, but not for a function defined with use strict. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
On Mon, Jun 11, 2012 at 4:51 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 12, 2012 at 7:38 AM, Brendan Eich bren...@mozilla.org wrote: I think Charles was arguing that anyone keeping secrets would need use strict to protect those secrets anyway, because otherwise arguments.caller.arguments[i] (given non-strict caller and callee) can get them. Non-strict functions should not be assumed to be encapsulated, so it would be ok if they leaked info in yet more ways. However, a stack consists of a mixture of strict and non-strict activations, so I don't see how this helps. It helps because, whether we are talking about a String API or an OO API, you make available arguments for non-strict functions, whereas for strict functions you do not. This doesn't expose any more information than is already exposed by function.arguments. This means a library using use strict and passing a secret to a non-strict function might have that secret revealed, and this is, again, already the case today (via function.arguments). This is a good argument for Error.getStack(errObj), indeed. Not Error.getStack. Error is generally available, so if the amplifier were Error.getStack, it would be generally available too. This leaves open the question of where to get things that are not generally available. I hope and expect that we can find good answers in the module system. The getStack amplifier should be obtained by importing a module that is not generally importable. We've already encountered the need for such privileged imports... I'm reading this as saying that stack traces in general should not be available unless the code is privileged in some way. This can't be what you mean, so could you clarify? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
On Mon, Jun 11, 2012 at 5:55 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 12, 2012 at 7:59 AM, Charles Kendrick char...@isomorphic.com wrote: I'm reading this as saying that stack traces in general should not be available unless the code is privileged in some way. This can't be what you mean, so could you clarify? That is exactly what I mean. The only way I can see this working is if there is a way for a given piece of code to trap an error and ask some kind of (elevated privilege) logging system to provide diagnostic information that a (privileged) end user can see. It also seems like, in addition to this, you should be able to get to stack information programmatically so long as you stay within your module or modules that have the same privilege. This doesn't sound like something that could be reasonably standardized into ECMAScript in the near future, and, without all those pieces in place, it doesn't seem like ECMAScript should just disallow the ability to get stack traces. Brendan brought up SES - I know little about it, but for its sake I hope this critical use case is taken into account. On Mon, Jun 11, 2012 at 6:17 PM, Brendan Eich bren...@mozilla.org wrote: I thought so too, but Charles is arguing both (a) no worse than today (not better than today); (b) useful for people who prefer non-strict code and a more useful stack-tracing API in the core language. Just to clarify, I prefer *some* of the ideas behind use strict and in fact we built a subset of use strict into our in-house tools long before JSLint existed. But if it's going to impose a security boundary between my own methods and reduce the utility of stack traces which are sometimes the only thing you have to go on.. no thank you. That seems to me to conflate useful error checking and security; there is overlap, but not 100% overlap by any means. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
On Fri, Jun 8, 2012 at 6:48 PM, Erik Arvidsson erik.arvids...@gmail.com wrote: On Fri, Jun 8, 2012 at 4:10 PM, Charles Kendrick char...@isomorphic.com wrote: Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities. Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking? Stack walking is not available in strict functions. Interesting, but it doesn't speak against programmatic access to the call stack. If use strict or any other security feature means that function.arguments are not accessible to a given script, then the same constraint could be trivially enforced with programmatic access to the call stack. The same could be applied to access to the receiver or values of local variables. In fact, V8's CallSite API makes the receiver inaccessible for a strict mode function (I just checked). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
On Fri, Jun 8, 2012 at 5:38 AM, Patrick Mueller pmue...@gmail.com wrote: Personally, I'm happy with a user-land way of being able to generate something like this, in V8: https://gist.github.com/312a55532fac0296f2ab You can actually do this now in userland in Chrome (except the CoffeeScript aspect). This link was posted yesterday: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi .. but I've subsequently commented on the page with some working code since people were having trouble understanding how to get to the array of CallSite objects (it's a pretty bizarre API). If there's issues dealing with recursion, or whatever, fine, just tell me what they are. You can't get to function arguments for recursive functions (appears more than once on stack). I filed this bug on it, perhaps you'd like to star it: http://code.google.com/p/v8/issues/detail?id=2169 Note: Erik just mentioned in passing that debugging APIs have security implications - this is potentially true for local variable access, but JavaScript VMs already have to handle correct security for access to function arguments due to the existing function.arguments API. So nothing new there in terms of risk or burden on the browser implementer. I think that getting access to parm values/locals is interesting, but veering into the land of the debugger. Just to connect the dots, as I said previously, you don't have a debugger when you are looking at logs for an application you can't access. Programmatic access to this information is critical in that use case, but also extremely valuable just everyday - how many times have you seen an application get into an error state that you aren't sure how to reproduce, when you didn't happen to be in the debugger? If you had robust stack traces you'd have a lot more to go on. With IE6 we solved dozens of bugs just from stack trace information. Ah the good old days! (yes that's sarcasm + irony) I'd prefer a clean take on debugging APIs rather than evolve it from an exception back-trace use case. When do we start talking about that? I'm looking at you, --expose_debug_as (V8 option). An Array of StackFrame / CallSite objects is pretty much a clean debugging API and not really something grafted on. The same concept appears in most debug APIs, eg Java's: http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/jdi/com/sun/jdi/StackFrame.html -- Patrick Mueller http://muellerware.org ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities. Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking? Also, forgive my ignorance, but is it an explicit goal of the JavaScript language that two scripts in a web page from the same domain must not be able to discover each other's runtime arguments? On Fri, Jun 8, 2012 at 3:50 PM, Erik Arvidsson erik.arvids...@gmail.com wrote: On Fri, Jun 8, 2012 at 3:25 PM, Brandon Benvie bran...@brandonbenvie.com wrote: You can get the arguments. Here's an example of getting more info out of a try..catch: https://gist.github.com/2898384 Which results in error.stack being an array of objects like (function, arguments, and receiver are actual function/array/object) { function: function, name: InjectedScript._evaluateOn, inferredName: _evaluateOn, arguments: Array[5], invocationType: call, receiver: receiver, inferredType: Object, origin: undefined, column: 33, line: 343, position: 12853, type: file }; Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities. Here is an example of when this would be a security issue: function foo(secret) { 'use strict'; thirdPartyFunction(); } ... function thirdPartyFunction() { getStackTrace(new Error)[1].arguments[0]; // oops I just leaked the secret. } Any proposal that exposes argument values and/or object references are dead on arrival. -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
No, this doesn't work. When you are in the catch() block you can discover the arguments for the function that contains the catch block and for any (non-recursive) functions further up the stack. But you cannot discover the arguments for functions that were on the stack when the error happened, but have exited by the time you hop back to the catch block. Your test happens to sidestep this because the catch block is in the function that throws the error. But the more important scenario is that a function somewhere down stack has crashed and you want to see what the arguments were when the crash occurred - because those are the arguments most valuable to know from a troubleshooting perspective. My test code for the V8 issue demonstrates this problem: http://code.google.com/p/v8/issues/detail?id=2169 On Fri, Jun 8, 2012 at 3:25 PM, Brandon Benvie bran...@brandonbenvie.com wrote: You can get the arguments. Here's an example of getting more info out of a try..catch: https://gist.github.com/2898384 Which results in error.stack being an array of objects like (function, arguments, and receiver are actual function/array/object) { function: function, name: InjectedScript._evaluateOn, inferredName: _evaluateOn, arguments: Array[5], invocationType: call, receiver: receiver, inferredType: Object, origin: undefined, column: 33, line: 343, position: 12853, type: file }; ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
Almost - there are no arguments for the function that throws, as well as all functions between the function that throws and the one that catches. On Jun 8, 2012, at 4:53 PM, Brandon Benvie bran...@brandonbenvie.com wrote: Oh I see, the arguments of the just function that throws is unset. I didn't get what you were saying at first. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Error stack
Thanks for taking this on Erik. I would suggest the following, which is mostly based on the information it was possible to extract from IE6 (which is amazingly still the leader in programmatic access to error information) as well as information we were able to get by writing a Firefox extension. All of the following might be optionally enabled, similar to Error.stackTraceLimit, if you think it's too verbose. 1. show the parameter values .. and do so intelligently: a. Show Arrays with length: Array[5] b. truncate long strings and show length: the quick brown fox jumped ...[45] c. format dates compactly: Date(2012/5/2 5:00) d. for Objects, use the toString() method if it's been customized on the object, and for other objects instead of [Object object] pick salient properties such as ID/id, name, title, type, or label. For example, in our traces we would show Obj{title:foo} if an Object with no customized toString() were present as a parameter and it happened to have a title property. This is a general strategy for dumping the value of something shown in a stack trace and is assumed for other features below. 2. show the value of this if it's not the window This is extremely important in OO frameworks. It tells you exactly what instances are involved in the call stack. Traces that go through recursive algorithms can be almost useless without this. For example: ReferenceError: doSomething is not defined at f (http://www.example.com/temp.html:5:5) [on Obj{ID:foo}] at g (eval at h (http://www.example.com/temp.html:6:5)) at http://www.example.com/temp.html:11:1 3. optionally show the line of code that crashed ReferenceError: doSomething is not defined code: this.doSomething() at f (http://www.example.com/temp.html:5:5) at g (eval at h (http://www.example.com/temp.html:6:5)) at http://www.example.com/temp.html:11:1 3. optionally show the line of code that calls down to the next frame ReferenceError: doSomething is not defined code: this.doSomething() at f (http://www.example.com/temp.html:5:5) code: if (something) f(); at g (eval at h (http://www.example.com/temp.html:6:5)) code: g(currentValue); at http://www.example.com/temp.html:11:1 4. optionally dump all non-parameter local variables for the crashing frame ReferenceError: doSomething is not defined code: this.doSomething() vars: value: 5 parent: Obj{name:foo} at f (http://www.example.com/temp.html:5:5) [on: Obj{ID:1}] code: if (something) f(); A couple quick notes: some might argue this is pushing stacks to do things debuggers do. But, you don't have a debugger when you are trying to solve a problem in a live application, and you don't have a debugger when a customer is sending you logs and you can't even access the application. But with stack traces like the above, especially when combined with good logging, you can be almost psychic when analyzing issues. This information is very easy for the browser implementer to retrieve so I don't think it imposes an undue burden, and from my 13 years of experience helping customers with issues in a large JavaScript framework, I can tell you that the value is difficult to overstate. On Thu, Jun 7, 2012 at 11:37 AM, Erik Arvidsson erik.arvids...@gmail.com wrote: I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered). http://wiki.ecmascript.org/doku.php?id=strawman:error_stack Feedback wanted. -- erik ___ 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: Error stack
I agree that something like error.stackFrames would be ideal. However I would say the V8 stack trace API is missing 3 key things: 1. access to parameter values 2. access to local variables defined in the function 3. access to the line of code that crashed / called the next frame without having to go download the source file and use the line number to find it. This is even more important for generated / eval()'d code where there is no source file per se. Note that access to the function for the frame via getFunction() is inadequate - doesn't work with recursion. APIs to get local variables and parameter values would need to be on the stackFrame. P.S. fascinating to learn that Node.js does long traces, we have done the same in SmartClient for a long time. On Thu, Jun 7, 2012 at 2:47 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Machine-parsability might be reaching too far, especially if you lose the benefits of nice function/method name inference. Instead, perhaps a separate strawman to standardize something like the V8 stack trace API [1]? It is used in Node for providing long stack traces [2], [3], [4]. It's a bit cumbersome, e.g. maybe a separate error.stackFrames getter would be nicer and the Java-style getFileName() methods could become simple properties. But the fact that it exists is extremely useful. [1]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi [2]: https://github.com/tlrobinson/long-stack-traces [3]: https://github.com/kriskowal/q/blob/0c1ffdc50a6ea77c3e97075fab35ab9f7b2d/q.js#L261-405, https://github.com/kriskowal/q/blob/0c1ffdc50a6ea77c3e97075fab35ab9f7b2d/q.js#L1307-1321 [4]: https://github.com/NobleJS/WinningJS-todo/commit/2d4ca10c4f672dac9f021b697c4c72bbff321ed9 From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Erik Arvidsson [erik.arvids...@gmail.com] Sent: Thursday, June 07, 2012 16:39 To: Jason Orendorff Cc: es-discuss@mozilla.org Subject: Re: Error stack On Thu, Jun 7, 2012 at 1:12 PM, Jason Orendorff jason.orendo...@gmail.com wrote: This isn't machine parseable in all cases, since the .message may contain newlines and can end with something like \n at ... That is a good point. This also applies to the name of a function (and object when included). It is trivial to create a function name that breaks the V8 style formatting. SpiderMonkey gets away with this by using the name of the function expression and it does not try to deduce a name based on the code.. window['\n@'] = function() { alert(new Error().stack); }; When I first set out to write the proposal I was set on the SpiderMonkey formatting but as I researched this I drifted closer and closer to the V8 formatting. The thing that convinced me was eval. I also don't think that providing ErrorName: ErrorMessage is a hard requirement. The same information is already available using errorObject.name and errorObject.message. If we remove the first line and require that non identifiers are quoted I think we can guarantee that the value is machine parseable again. Changing this in Firefox would affect any Firefox addons that use Error.stack, but maybe we can take that hit. For web apps we already have to parse two different versions so I'm not too concerned about that case. The WebKit mobile web does not depend on either format (Safari doesn't have it in any shipping version yet) so the two problematic big eco systems are Firefox and Chrome extensions (and Node.js?) -- erik ___ 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: Source Map Standard
Very strongly agree. I also suggest that in-JavaScript diagnostics, such as access to stack information when errors occur, is also standardized by this track. For example, there are bugs logged against all 3 major engines about the fact that onerror is basically useless because there's no way to get a stack trace: https://bugs.webkit.org/show_bug.cgi?id=55092 https://bugzilla.mozilla.org/show_bug.cgi?id=355430 https://connect.microsoft.com/IE/feedback/details/663758/no-way-to-programmatically-get-stack-trace-on-javascript-error In each case, this has been acknowledged as a real problem, but it's fairly clear that at least the WebKit and Firefox bugs are stalled due to lack of standardization. Also, more kudos to Joey and John for Source Maps :) Cheers, Charles On Wed, Apr 11, 2012 at 4:30 PM, Mark S. Miller erig...@google.com wrote: Hi Joey, I'm very glad to see this and I think it should be standardized by TC39. However, it should not be standardized as part of the language, and so would result in a document distinct from Ecma 262. A good model is the way the internationalization track is proceeding. Rather than create an entire new track just for source maps, I think this goes hand in hand with the need to standardize a debugging API. I suggest both be bundled into one new track. On Wed, Apr 11, 2012 at 11:11 AM, Joey Schorr jsch...@gmail.com wrote: Greetings ES Discuss! We (Joey Schorr and John Lenz, CCed) are some of the authors of the source map specification that is now implemented by WebKit and Firefox, as well as a number of compilers (Closure Compiler, GWT and soon CoffeeScript). Given that the specification is becoming a de-facto standard for mapping of code which is compiled to JS, we were curious if there was any interest in making it an actual standard under TC39. The current specification can be found here: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit, with a number of contributions from all the various parties involved. Thanks! Joey Schorr Additional information: Firefox implementation: https://github.com/mozilla/source-map WebKit implementation: http://code.google.com/codesearch#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/inspector/front-end/CompilerSourceMapping.js Tutorial for Chrome: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- 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: iteration order for Object
On 3/12/2011 2:08 AM, Claus Reinke wrote: I notice that you don't count initialization for the native Object variant. Apart from fixing that, This is not a flaw. The initialization phase for the orderedMap creates an index. This is not needed for Object because the Object *is* the index. would the following variant help (run, but not tested;-)? It keeps the previous/next key in the key's internal value, to reduce overhead. The primary differences is that your code creates one Array per property, while my code uses 3 Objects to store unlimited properties via lots of slots. This makes your code about 4x slower on IE6, where Object/Array allocation has painfully high penalties. On other browsers, the results are less clear: straight timings are not directly comparable since at the end of the test, my code has no garbage, whereas yours has orphaned 15,000 arrays that the garbage collector needs to clean up. To sum up, by using different implementations in different browsers, it may be possible to implement an order-preserving map in JavaScript and be within 5-6x of native speed. Which in turn means, a common use case is penalized badly if Object loses order for numeric properties, whereas only relatively uncommon use cases (eg crypto in JavaScript) are penalized by preserving order for numeric properties. However, *critically*, these uncommon use cases can regain full speed by using Arrays for objects with lots of numeric properties, but there is no known way to get back to full speed for the common use case of needing an ordered map. Finally, this is just one part of the overall argument. This effect combines with the backcompat issue, loss of information going from Object literals to live Objects, less compact code and higher allocation/GC costs, etc. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/13/2011 2:07 PM, Brendan Eich wrote: On Mar 13, 2011, at 3:58 PM, Charles Kendrick wrote: Brendan, Bradley and others - there's no need to search for a relatively uncommon use case for ordered maps indexed by keys - a far more common use case is enumerated data stored numerically, eg, marital status: { 2: Married, 1: Single, 5: Divorced } It's still a synthetic example, and real web sites/apps would be more compelling and helpful for forge consensus. There's two separable and mutually reinforcing lines of argument here and the appropriate evidence is different for each: 1. backcompat issue Here the primary evidence of developer pain is the Google Code issue with the record-setting 127 stars and 116 comments http://code.google.com/p/v8/issues/detail?id=164 And these two duplicates: 75 stars, 22 comments: http://code.google.com/p/chromium/issues/detail?id=37404 32 stars, 17 comments: http://code.google.com/p/chromium/issues/detail?id=20144 I have not read everything in detail but there is at least one instance of someone pointing out that part of Facebook was broken by this in Dec 2010: http://code.google.com/p/v8/issues/detail?id=164#c81 If you slog through the rest of the comments on this and other issues closed as duplicates, you find a bunch of people complaining about broken apps/sites, saying that they are advising people not to use Chrome, etc, but, most are posting with generic email addresses and do not name the specific sites. People are asking me on and off-list whether I can provide specific sites, but, I have no special access to know what these sites are. I have around 10-12 definite reports from our own customers getting bitten by assuming order was preserved and thinking it was a bug in the framework, where we've had to give them the bad news. These are all banks / insurers / defense apps, behind the firewall. My intuition is that most of the posters in the Google Chrome issue are likewise behind-the-firewall business applications. This is no way diminishes the importance of the applications that all these developers are posting about - if they are indeed mostly behind-the-firewall applications, then they deal with money and business processes and other high-value stuff. 2. usability / functional issue By this I mean: - the performance value of having Object be a native-speed order-preserving map implementation: 4-6x faster than the fastest JavaScript implementation - the loss of information going from an Object literal to a live Object if order is not preserved - more verbose code / data definitions in various use cases - the gotcha factor of Object appearing to preserve order but then dropping order for numeric keys, a reasonable behavior for Array but a surprise on Object .. etc. Here I don't think it makes sense to ask for an Alexa site or similar - we're talking about how common the use case is, not how popular the site is, and in this case I think the use case comes up most often in sites that would never appear in the Alexa 500, because they are business applications. I have presented two main arguments about how common the use case is: 1. if you look through available collection classes in the class libraries of various languages, you will very often find an order-preserving map, but you won't find an implementation of a map that preserves order for string keys but not numeric. To me, this strongly implies that the order-preserving map is a commonly desired behavior whereas a map that specifically drops order for numeric keys does not correspond to any common use case 2. order-preserving numerically-keyed maps are very common in any application that involves relational storage. Since this crowd didn't receive this as an obvious statement in the way I expected, let me provide some further information: If you consider enumerated fields (Order Status, Bug Status, Sex, Package Type, Employment Status, etc - they are ever-present) across all object-relational mapping systems across any programming language (Rails/Grails, Hibernate, Django, etc), storing such fields as numeric values is either the default or is an available option. Likewise if you consider relations between objects (Account-Manager), typically an integer id is assigned to the record and stored in the related record. For either type of information, when it is being delivered to the UI to be displayed, one very natural representation is a map from unique integer id to display value, eg Bug Status: { 2: Fixed, 1: Verified, 5: Duplicate, ... } .. or search results (eg a combobox): { 43443: Mark Mitchell, 43113: Mark Pierce, ... } This latter use case is basically what was broken on Facebook. Hopefully this is enough to make it clear that the use case is very common. Someone could, of course, go off scouring various web sites to try to find status fields stored
Re: iteration order for Object
Brendan, Bradley and others - there's no need to search for a relatively uncommon use case for ordered maps indexed by keys - a far more common use case is enumerated data stored numerically, eg, marital status: { 2: Married, 1: Single, 5: Divorced } Likewise maps from numeric primary key values to display values for the records. So this use case comes up just about every time JavaScript is manipulating data coming from a SQL database - extremely common. On Mar 12, 2011, at 3:47 PM, Brendan Eich bren...@mozilla.com wrote: 3. Object has a useful behavior (similar to Java LinkedHashMap) instead of a surprising behavior (treating indices specially) The argument from Java leaves many cold. Argument from Java??? You wound me, sir! I would never argue from the viewpoint of such a verbose language and far prefer your JavaScript. To rephrase my argument so that it does not appear to be rooted in Java: take any library of collection classes from any language: C, C++, Python, perl, Ruby, Forth, whatever: do you ever find a collection class that is written to preserve order of string keys but not numeric keys? I don't know of one. So we're looking at standardizing a behavior for Object that no one has ever felt the need to implement as a reusable component. I would argue this means we're standardizing a very rare use case. This is aside from the performance Perhaps these people should rewrite their code, To be fair we're talking about a pretty tiny rewrite, in many cases a one-line change. I made the change to JQuery is about 5 lines, with no apparent functional difference in a medium-size app. If someone can point out a benchmark involving JQuery where Chrome appears to win due to dense Arrays, I can try it out, verify a performance difference if it's real, and submit the patch. After all it applies to current Firefox regardless of what is decided here. but now we are in a perverse game: Chrome and possibly other browsers (I haven't tested IE9) optimize their code better than other browsers. Glad to see the phrase perverse game here. I feel that the right behavior for the language is in danger of being sacrificed for an advantage in synthetic benchmarks that don't reflect the real-world use cases we should really be optimizing for. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On Mar 12, 2011, at 10:41 AM, Brendan Eich bren...@mozilla.com wrote: On Mar 12, 2011, at 9:54 AM, David Bruant wrote: The little issue I see in returning 1) index properties in ascending order 2) all other properties in addition order is that there is a bit of information lost in the process: overall property addition order (index properties included). This is an issue in theory. Beware _a priori_ reasoning about usability issues. In practice both users and (especially) implementors Do Not Want indexed properties enumerated in insertion order. The proof is the use of for-in over arrays, still common enough, also advised against (but that is like talking back to the tide). I don't understand why this is still being discussed as a single behavior across Array and Object. If we define the iteration order as: 1. Object: in-order including indices 2. Array: indices first Then: 1. There's no information loss going from Object literal to live Object 2. Array has the for..in behavior people expect 3. Object has a useful behavior (similar to Java LinkedHashMap) instead of a surprising behavior (treating indices specially) This is aside from the performance and backcompat benefits covered previously. You mentioned JS conflates Arrays and Objects - so - let's stop doing that :)___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Bradley, the proposal is to define the iteration order for Object only, not all objects (eg Array). Also, if you were choosing between: 1. The strawman: preserve insertion order for non-index properties only, on both Object and Array 2. My proposal: preserve insertion order for all properties on Object only, leave other objects undefined Then what would you choose? Because there seems to be existing momentum to define an order of iteration, so it may be that what you seem to prefer (leave it totally undefined) is not a possibility. On Mar 11, 2011, at 5:55 PM, Bradley Meck bradley.m...@gmail.com wrote: I would just like to give my 2 cents. I would like some sort of iterative ordering, but not on Objects. The reasons have been stated before that iterative ordering is less optimal for performance than random access (or semi-random). However, it has its uses, perhaps it would be more suitable to put this in proxies like people have stated, which in some ways is true. Lexiconographical and declaration orderings are quite different but quite common, and even then there could be a more obscure ordering that is left out. This topic I feel is a complex one that has implementation implications if we provide it on all objects, as well as the added complexity of runtime mutation of properties needing consideration (it would be odd for object literals to be treated differently from other objects). As well as the possible reliance of people on object indexes which have no real ordering: var i = 0 for(var k in obj) { switch(i) { //stuff based upon i instead of k to determine your actions even though relying on k as a context when producing the object } i++ } is a confusing but possible code example of independence of properties and location that would be awkward. If we do go with ordering, this is a possible example of misuse (it is a simple case but would be throwing around junk strings of k without really wanting to know what k actually says). For now I would stick with arrays for ordering as ordering multiple objects together implies a relationship which should be encapsulated (because they are related somehow rather than by implicit knowledge of how ordering is going to line them up) in another object rather than symbol table. And I hope we get proxy support everywhere so we can do interesting for ... in loops soon. I am going to side with voting no on this. It seems that the idea of sorted enumeration is a great one, but the reasons to put it on the enumeration of objects is less than stellar. Most of the reasons appear to be due to legacy systems or possible memory saving, but I am not convinced you would save memory/cpu due to the need of tracking/sorting this order of properties whenever a for in loop is performed (assuming we can do it lazily). In reality I see it as a native code implementation of what is being done with libraries today when they do need to keep track of multiple fields at the same time, but a reliance on this would mean instead of only doing it as needed, the native implementation would perform this every single time, slowing down setting of properties as well as all for ... in loops. Cheers, Bradley On Fri, Mar 11, 2011 at 6:31 PM, Charles Kendrick char...@isomorphic.com wrote: On 3/11/2011 3:58 PM, Jeff Walden wrote: On 03/11/2011 02:07 PM, Charles Kendrick wrote: Your perspective is common in a group like this - very spec and standard focused. Isn't it fun to bash those developers? Everyone's doing it.. I hope you realize it's irrelevant though? Insinuating bad faith (Isn't it fun and Everyone's doing it) may not be a successful strategy for swaying others to your point of view. Just saying. My apologies. It is frustrating to open a discussion with a proposal of what is best, and have it be redirected repeatedly into a discussion of who is to blame. And I tend to agree with David Bruant about the makeup of the list being lightly-involved developers, true standardistas, implementers, spec writers, and more: a fairly mixed bunch with lots of different motivations and goals, to which few generalized sentiments can fairly be attributed. You're certainly correct that it's a mixed bunch of roles, but that's within the very narrow subset of developers who know about the standards process and care enough to be here. However I would never attribute a general sentiment to any group, that's almost always wrong. I said a certain perspective would be more common. It's been my (repeated) personal experience that you get very different responses on a list devoted to standards than from (say) an enterprise development shop. Easily verified. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org
Re: iteration order for Object
On 3/11/2011 7:07 AM, Claus Reinke wrote: I believe it is very very important that the ECMAScript standard specify that when a new Object is created, for..in iteration traverses properties in the order they are added, regardless of whether the properties are numeric or not. Some users might prefer 'in the order of keys'. That is predictable, and allows for efficient implementation (both sparse and dense). This: 1. breaks completely with the de-facto standard. 2. still requires the verbose, high allocation cost data formats previously explained in order to define an in-order map 3. prevents the use of Object literals in JSON to convey ordered data A SortedMap collection for JavaScript would be great, and useful for certain types of code. But it doesn't help with the problems I'm pointing out. Most of these are just awkward ways of saying this is the order I want and I also want hashmap access. So why not write that out explicitly, with an optional ordering parameter, making the enumeration explicit when the default ordering isn't suitable: selectControl.setOptions({ storedValue1 : displayValue1, storedValue2 : displayValue2, storedValue3 : displayValue3 },['storedValue1','storedValue2','storedValue3']) Because this is spectacularly bad in all the ways I previously mentioned: even more redundancy than the prior worst option, even more allocation and GC load. It may seem convenient if keys happen to be enumerated in the order they are written, but if that extends to the order of insertion, things get complicated (if you delete an entry, then reinsert it, has it lost its position? do you want an insert before?). There are several clear behaviors to choose from here (eg Java's LinkedHashMap). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/11/2011 7:35 AM, Wes Garland wrote: Someone -- Mark Miller? -- suggested an interesting option when this discussion came up last on this list (around Christmas 2010 IIRC). Basically -- enumerate named props in insertion order, and numeric props in numeric. This gets pretty close to what most developers seem to expect, while leaving the door wide open for fast implementation of array-like objects. Just connecting the dots - I addressed this in my first email on the subject. While it superficially sounds like a good compromise, I actually think it's the worst possibility: it requires browser vendors to implement limited order preservation, preventing deeper optimizations like sorted keys. At the same time, it requires that applications and frameworks deal with lack of order for numeric keys, which are very common: in the use case of mapping stored to displayed values, stored values are very often numeric. I also think that it's surprising and counter-intuitive that numeric keys are treated differently from non-numeric. The reality is that an implementation detail of Array is bleeding through to Object. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/11/2011 2:39 AM, David Bruant wrote: Le 11/03/2011 00:48, Charles Kendrick a écrit : == Expressiveness and Performance argument A very common use case where order preservation is desirable is providing the set of options for a drop-down list in JavaScript. ... This is one (very valid, intuitive and common) use case. What if I want to implement some sort of dictionnary and want keys to be ordered in alphabetic order? If the spec imposes one order, then people with other use cases have additional work. Since so far, the spec has never said anything about property ordering, it would create some biase to add to the spec one specific order. If the spec doesn't impose an order, *everybody* has extra work because there's no default strategy that can be relied upon. I have no problem with *multiple* strategies being available, as either a set of collection classes similar to Java Collections, or as strategy hints to Objects. However as far as the default strategy, the highest value thing to do seems to me to impose the de-facto standard of 15 years - insertion order - which is a very useful behavior and will avoid thousands of websites having to compensate for a change in de-facto standard behavior. The point I am trying to make is that having keys and values as strings is required by the DOM API in order to create the option elements, so when you mention 2 Strings per property, this is work that has to be done anyway. This might even be cheaper to have strings created from parsing the source than extracted as object property names. No - the difference is, if you eval a JSON Object, you either have 2 JavaScript Strings per property (or even more overhead than that in some scenarios), or you have a single JavaScript Object in which only the property values actually exist as Strings - the slots are implicit, only existing inside the underlying VM. This has less memory footprint, less allocation overhead, less GC overhead. It is far far faster to remove or replace keys with this structure as well. Whether this is used to render a DOM as well, or for something else, can be treated as a separate issue. Already, you have this tremendous efficiency at the data structure level, and you've preserved JSON's ability to encode an ordered object. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Hello John, I'll assume you meant this as humor since the analogy has such obvious flaws. Having a default strategy on Object of maintaining order obviously does not preclude other strategies, nor does it damage the JavaScript language itself, as locking int to 16 bits would obviously have damaged C by requiring various new types. On 3/11/2011 11:44 AM, John Tamplin wrote: On Fri, Mar 11, 2011 at 11:31 AM, Charles Kendrick char...@isomorphic.com mailto:char...@isomorphic.com wrote: However as far as the default strategy, the highest value thing to do seems to me to impose the de-facto standard of 15 years - insertion order - which is a very useful behavior and will avoid thousands of websites having to compensate for a change in de-facto standard behavior. So I suppose you think C should have kept int at 16 bits since there was lots of Win16 code that assumed sizeof(int)==2 because it happened to work on their platform, or likewise sizeof(int)==sizeof(char*)? Things unspecified in the spec mean unspecified -- it doesn't mean rely on whatever behavior the implementation you use exhibits and expect it to be portable. -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Not so - order-preserving implementations are backwards compatible with non-order-preserving implementations. Just rev the spec, and like any other versioned spec, developers can use the new behavior when they know the application environment uses only the new version. On 3/11/2011 12:41 PM, Dean Landolt wrote: Billions of JSON messages vs a handful of sites should be pretty clear cut, but I've collected some numbers anyway just to make it more obvious. You've asserted this JSON-advantage claim several times now so you should probably know that keys in JSON are specifically specified as unordered. Nothing TC39 does can alter this fact -- it won't (and /can't/) be changed. Even if ECMAScript were to go this route, nothing says that JSON implementations will (or must) respect this ordering. Surprises would lurk around every corner. [snipped the rest] ___ 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: iteration order for Object
Yes Allen, hence the urgency. If IE9 final ships that way, the goose is cooked: 1. we will have a new de facto standard iteration order for Object that does not match any known use case - it is purely an implementation detail leaking through 2. the majority of real-world applications will be slowed down because developers will need to re-implement the very commonly needed LinkedHashMap behavior in JavaScript 3. developers will waste a bunch of time doing this when the language could have provided it 4. developers will waste a bunch of time upgrading old sites and applications 5. JavaScript code will forever be more verbose than it needs to be wherever ordered maps are needed 6. JSON messages will forever be more verbose than they need to be, and result in larger JavaScript allocation and GC loads when eval()d/parsed Against all this, we have various misunderstandings (thinking the iteration order of Array is being affected, etc), but finally only: 1. for certain unusual use cases, implementers of code that use lots of integer indexes will need to use Arrays for best performance - a perfectly reasonable optimization technique to require, in my opinion 2. there may, in the immediate term only, for some unspecified use cases which may well be very synthetic, be an advantage for JQuery, which may well vanish as JQuery evolves On 3/11/2011 11:37 AM, Allen Wirfs-Brock wrote: On Mar 10, 2011, at 5:44 PM, Charles Kendrick wrote: This behavior was perfectly consistent across all browsers until Chrome 6. I think it's more appropriate to say that Chrome is not interoperable with thousands of sites than to define interoperable behavior based on a minority browser's very very recent break from a de-facto standard that stood for 15 years. Note that it isn't just Chrome. IE9 also has similar behavior (at least in its late platform previews, I don't have the RC installed yet) On IE9 preview 1.9.8023.6000 standards mode: var a={x:'x', 3:3, 2:2,1:1}; a.a='a'; print(Object.keys(a)); //-- 1,2,3,x,a print(JSON.stringify(a); //-- {1:1,2:2,3:3,x:x,a:a} var k=''; for (var e in a) k+=e+ ; print(k); //-- 1 2 3 x a ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Probably the language which most commonly handles JSON is JavaScript itself. So a major chunk of the benefit, possibly even the majority of the benefit, would be immediate: eval(), application config files expressed in JSON, etc. And as you alluded to (also I CAN HAZ CUSTIM CLAZZES?) JSON will probably eventually have versions. On 3/11/2011 12:55 PM, Dean Landolt wrote: On Fri, Mar 11, 2011 at 3:48 PM, Charles Kendrick char...@isomorphic.com mailto:char...@isomorphic.com wrote: Not so - order-preserving implementations are backwards compatible with non-order-preserving implementations. Just rev the spec, and like any other versioned spec, developers can use the new behavior when they know the application environment uses only the new version. The JSON spec has no version number, intentionally -- it would have to be supersetted entirely. You could make the argument that perhaps it's about time (I CAN HAZ DATES?) but that's a much bigger challenge, and your claimed advantages to JSON handling would still be moot until ECMAScript adopted your JSON replacement. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/11/2011 1:33 PM, David Bruant wrote: Le 11/03/2011 21:49, Charles Kendrick a écrit : Yes Allen, hence the urgency. If IE9 final ships that way, the goose is cooked: Let's face it right now: IE9 will ship that way. They're on RC phase, it's completely irrealistic to consider they would change object implementation. From the spec point of view, there is no urgency since Harmony won't ship for couple of years I think. I disagree - if there is a clear consensus that ECMAScript will standardize on a particular iteration order, there's a strong chance IE9 will update to reflect this (so, on reflection, I should not have said the goose is cooked). They are aggressively embracing standards across the board now, after all. 1. we will have a new de facto standard iteration order for Object that does not match any known use case - it is purely an implementation detail leaking through As said by someone else, the iteration order has never been standardized. It was dangerous from the developers to base their code on an implementation detail even though this one was at some point consistent accross browsers. Standards aren't only for implementors. Your perspective is common in a group like this - very spec and standard focused. Isn't it fun to bash those developers? Everyone's doing it.. I hope you realize it's irrelevant though? These developers took a calculated risk at a time when standards were so vague and partial that they had to take similar risks everywhere. Most of them stand ready to accept the consequences and change their code. It's just that it's a tremendous waste of time for them to do so. *That's* the point. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/11/2011 3:13 PM, David Bruant wrote: Have you reported an issue to Microsoft Connect (or their bug reporting platform, I do not remember the exact name)? I will report it the second that I can link to, say, an email from Brendan Eich replying to 2 other heavies saying yeah, we're agreed ES4 Harmony should specify in-order iteration as the default strategy. (I am not impugning your waistline Brendan). I still believe they won't do a change to the implementation even if the entire TC-39 committee was knocking at the IE team door in the next hour. Great idea David, I'll catch a flight if you will ;) These developers didn't take a calculated risk. They saw it worked with the implementations at the time and hoped it would be so in the future. That is precisely the calculated risk they took. Many were aware that technically, the spec left it undefined, but again, saw the feature as so obviously valuable that there would never be a reason to go against a behavior all browsers agreed on. And again, I agree with them - I think the language should be standardized in exactly the way they assumed it would. If you could go back in time and explain to those developers that we now have browsers that are 10,000 times faster on hardware that's 10 times faster, but we're going to sacrifice in-order iteration in order to get a little bit more, I think they'd be stunned. But it requires some involvment anyway if you want your code to be robust over time. If you write code that is supposed to last one browser generation, you can rely on implementation details. If you want to write robust code, you have to make sure you understand the spec and are not relying on implementation specificities. On robustness, just to set perspective, today I have the luxury of the extra speed and memory to make my own LinkedHashMap in JavaScript, as I showed - at the time some of these decisions were made, there was not enough breathing room to do this. The applications would not have hit performance targets. Think, in particular, of my second implementation in the context of the pre-IE7 garbage collector. Sure, it rips through a million keys in a couple seconds on a modern Firefox browser, it also trebles the GC load relative to an Object: this is game over on older IE. If reminding this means bashing to you, then I am sorry, I am bashing developers. I may be wrong, but I think it's relevent to remind that it isn't the spec fault if developers didn't follow it while implementations did. Not only do I agree it is not the spec's fault, I'm not interested in assigning blame at all, which was really my point. Whoever we point to as at fault, the language gets worse and a bunch of developers waste their time. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/11/2011 3:58 PM, Jeff Walden wrote: On 03/11/2011 02:07 PM, Charles Kendrick wrote: Your perspective is common in a group like this - very spec and standard focused. Isn't it fun to bash those developers? Everyone's doing it.. I hope you realize it's irrelevant though? Insinuating bad faith (Isn't it fun and Everyone's doing it) may not be a successful strategy for swaying others to your point of view. Just saying. My apologies. It is frustrating to open a discussion with a proposal of what is best, and have it be redirected repeatedly into a discussion of who is to blame. And I tend to agree with David Bruant about the makeup of the list being lightly-involved developers, true standardistas, implementers, spec writers, and more: a fairly mixed bunch with lots of different motivations and goals, to which few generalized sentiments can fairly be attributed. You're certainly correct that it's a mixed bunch of roles, but that's within the very narrow subset of developers who know about the standards process and care enough to be here. However I would never attribute a general sentiment to any group, that's almost always wrong. I said a certain perspective would be more common. It's been my (repeated) personal experience that you get very different responses on a list devoted to standards than from (say) an enterprise development shop. Easily verified. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
iteration order for Object
I believe it is very very important that the ECMAScript standard specify that when a new Object is created, for..in iteration traverses properties in the order they are added, regardless of whether the properties are numeric or not. The primary reason is that I think it makes ECMAScript a much more expressive and usable language, and results in better performance in real-world applications. Secondarily, the fact that the Chrome browser has deviated from this de-facto standard is creating a small crisis for site owners and web application developers, and it will get much much worse if any other browser vendors follow suit. This seems to have been most recently discussed in 2009 with inconclusive results. https://mail.mozilla.org/htdig/es-discuss/2009-October/010060.html I have summarized the argument for this feature below - this argument has swayed others who were initially opposed. I'm hoping we can get quick consensus that *specifically Object iteration order* should be preserved, without getting too bogged down in the details of specifying exactly what happens for Arrays, prototype chains, etc. Major stakeholder agreement on this one aspect should be enough to prevent any other vendors from shipping browsers that break sites, and get the Chrome bug for this re-instated. == Expressiveness and Performance argument A very common use case where order preservation is desirable is providing the set of options for a drop-down list in JavaScript. Essentially all Ajax widget kits have such an API, and usage is generally: selectControl.setOptions({ storedValue1 : displayValue1, storedValue2 : displayValue2, storedValue3 : displayValue3 }) Here are some examples of what alternatives might look like - all of them are far, far worse: #1 Parallel arrays: selectControl.setOptions( [storedValue1, storedValue2, storedValue3], [displayValue1, displayValue2, displayValue3] }) - this is awkward and unnatural, and doesn't correspond to how a list of options is specified in HTML - involves *double* the number of allocations / GC-tracked objects (6 strings and 2 Arrays vs one Object and 3 Strings - slots don't GC) - replacing a key/value pair requires a linear (0(n)) search unless secondary indexing approaches are used, which requires yet more allocation both to build and maintain the index, as well as a level of sophistication not typical for a scripting language user #2 Array of Objects selectControl.setOptions([ {value: storedValue1, text: displayValue1}, {value: storedValue2, text: displayValue2}, {value: storedValue3, text: displayValue3} ]); - verbose and redundant code - reiterates value and text once per entry - much worse Object allocation than #1 (which was already bad): one Object + 2 Strings per property - same linear search / extra allocation / developer sophistication issue as #1 #3 Array of Arrays selectControl.setOptions([ [storedValue1, displayValue1], [storedValue2, displayValue2], [storedValue3, displayValue3] ]); - verbose, finger-spraining punctuation density - much worse Object allocation than #1 (which was already bad): one Array + 2 Strings per property - same linear search / extra allocation / developer sophistication issue as #1 In a nutshell, dropping order preservation results in: 1. less expressive code 2. more bytes on the wire (both in code-as-such and JSON) 3. degraded application performance via increased allocations and the overhead of implementing order-preserving behavior in JavaScript == Historical behavior argument All browsers that have ever had non-negligible market share have implemented order-preserving Objects - until Chrome 6. Like many universally consistent, obviously beneficial behaviors, many developers relied on it assuming eventual standardization. Thousands of sites and applications are broken by Chrome's decision to drop the order-preserving behavior. There is a bug against Chrome's V8 engine (currently marked WorkingAsIntended): http://code.google.com/p/v8/issues/detail?id=164 People can star issues to be notified of changes in status or discussion. This issue has by far more stars than the most-starred Feature Request (E4X support), more than double the stars of the runner-up, and more stars than roughly the top 20 confirmed bugs combined. And this does not consider all the stars on other versions of this issue that were closed as duplicates. Various arguments have gone back and forth on whether Chrome should fix this bug without waiting for standardization, but not a single person has indicated that they would prefer that Object does not preserve order. In a nutshell, there is overwhelming support for adding this behavior to the standard, and still time to avoid all the wasted effort of changing all these sites and
Re: iteration order for Object
On 3/10/2011 5:03 PM, Allen Wirfs-Brock wrote: But those details are exactly the situations that break interoperability. This behavior was perfectly consistent across all browsers until Chrome 6. I think it's more appropriate to say that Chrome is not interoperable with thousands of sites than to define interoperable behavior based on a minority browser's very very recent break from a de-facto standard that stood for 15 years. Further, Chrome is used principally by developers and auto-updates itself. If Chrome behavior were reverted today, the number of browsers out there with this behavior would trend to zero in probably months. But the sites and applications will last many years. Just being practical here. In https://mail.mozilla.org/pipermail/es-discuss/2010-December/012469.html I identified scenarios where you can expect to get interoperable enumeration order among all major objects: The object has no inherited enumerable properties The object has no array indexed properties No properties have been deleted No property has had its attributes modified or been changed from a data property to an accessor property or visa versa Quite correct, but because of your #2, this is worst-of-both options behavior: --- 3. It's good enough to preserve order for non-numeric keys only This is an abysmal compromise, with the worst traits of each alternative. It requires browser vendors to implement order preservation, such that we don't get the minor optimization that's possible from not preserving order at all. At the same time, it requires that applications and frameworks deal with lack of order for numeric keys, which are very common: in the use case of mapping stored to displayed values, stored values are very often numeric. --- The distinction you make between Arrays and Objects isn't one that necessarily exist at the implementation level. Correct. You and I know that Objects and Arrays share most of their implementation. But don't you agree that, approaching the language as a beginner, it's a surprise that numeric indices behave differently from other indices *on Object*? Are you suggesting that for all objects other than Array instances that array indexed properties must enumerate in insertion order? Chrome isn't the only browser where that currently isn't true. No. I have no opinion on standardized iteration order on Array or on any object other than Object (Date, Regexp, et al). There never was any consistency there, and I have never seen a use case where it could conceivably be important that properties on eg a Regexp have a specific order. I think it would probably be best to leave these unstandardized, to give browser vendors maximum leeway to optimize. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
I'd love to have a full set of collections for JavaScript, but just to clarify, adding a separate OrderedObject wouldn't address most of the issues I've raised: 1. it would be no help to JSON - there would still be the severe expressiveness and object allocation overhead I previously described 2. it would remain a surprising gotcha that numeric indices behave specially on Object 3. it would not address the backcompat issue with all the sites that depend on ordering On 3/10/2011 5:00 PM, Jeff Walden wrote: Another idea might be to introduce OrderedObject or somesuch with guaranteed enumeration order. You might lose object literal support (although that could be readded), but that's the only loss that comes to mind after brief thought. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Yes, great performance enhancements are available for *Arrays* - but this is not relevant because as I explicitly stated, I am not suggesting anything be clarified or standardized with respect to for..in order for Arrays. People use Objects as classes, instances, associative arrays / Maps, etc. Numeric keys are a tiny minority and there would be no measurable performance gains for special treatment of such keys *on Object*. However because frameworks have to deal with all possible keys, we end up with a much, much more expensive data structure that has to be used just because numeric keys are being treated specially. This means that the real-world, application-level impact of not preserving order is *slower* applications. On 3/10/2011 5:48 PM, Boris Zbarsky wrote: On 3/10/11 8:44 PM, Charles Kendrick wrote: It requires browser vendors to implement order preservation, such that we don't get the minor optimization that's possible from not preserving order at all. For what it's worth, not preserving order for numeric properties allows optimizations that are decidedly not minor. You can compare the performance of fast and slow arrays in Spidermonkey to see the difference. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Boris, this is why I also took care to mention that for..in iteration on Arrays should remain unordered, so that developers doing relatively obscure things like crypto evoting in JavaScript (the use case in the first bug) still have access to a dense-array implementation. Best of both worlds: Object does what you would expect, Array has optimizations for obscure use cases. Last point below. -- == Objections and counter-arguments 1. Array for..in iteration order has always been inconsistent across browsers Yes, this is true. I am proposing only that Object preserves insertion order, not Array. No developers or sites rely on Array for..in iteration order, since it was never consistent. If Array for..in iteration continues to be unordered, any developer that cares about the tiny performance difference can use an Array to store non-numeric property/value pairs. --- On 3/10/2011 6:11 PM, Boris Zbarsky wrote: On 3/10/11 9:00 PM, Charles Kendrick wrote: People use Objects as classes, instances, associative arrays / Maps, etc. Numeric keys are a tiny minority and there would be no measurable performance gains for special treatment of such keys *on Object*. You may want to read https://bugzilla.mozilla.org/show_bug.cgi?id=594655 and https://bugzilla.mozilla.org/show_bug.cgi?id=611423. People are running into performance issues due to lack of such special treatment today. Now maybe these people are just doing dumb things they shouldn't be doing, but that doesn't make the performance differences observed on those tests not measurable. However because frameworks have to deal with all possible keys, we end up with a much, much more expensive data structure that has to be used just because numeric keys are being treated specially. I agree this is an issue. I just think you're underestimating the performance drag of preserving numeric property order for vanilla Objects. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Thanks for the link Brendan. This strawman continues to treat numeric indices specially on Object. Let's ignore, for the moment, the fact that the underlying implementation of Object and Array is very similar. Has a use case been identified where treating numeric properties differently from other properties is a desirable behavior? Is there any programming language or library for any programming language where this behavior has been intentionally implemented as a collection class? In my limited experience both are no. Harmony is a clean break: seems like a great opportunity to implement the behavior for Object for..in iteration that is most useful. On 3/10/2011 5:02 PM, Brendan Eich wrote: Please see http://wiki.ecmascript.org/doku.php?id=strawman:enumeration. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Boris, compare: 1. tens of thousands of web applications that need to define a sorted map plus perhaps billions of JSON messages per day .. to .. 2. a handful of crypto / computational use cases used by a tiny minority of sites What should be optimized for? Note that we don't really even have to choose. If you tell the guys implementing these crypto / bignum libraries that their code is going to run 6x faster in Firefox if they use an Array, they'll probably have switched by Tuesday. It's a perfectly reasonable and acceptable way to close a bug to say that if you want the best performance when using lots of numeric indices, use an Array. On 3/10/2011 6:35 PM, Boris Zbarsky wrote: On 3/10/11 9:18 PM, Charles Kendrick wrote: Boris, this is why I also took care to mention that for..in iteration on Arrays should remain unordered What does this have to do with the post you're replying to? so that developers doing relatively obscure things like crypto evoting in JavaScript (the use case in the first bug) still have access to a dense-array implementation. The point is that the bignum library there is using vanilla objects, not arrays. And they're using numeric property names. If Array for..in iteration continues to be unordered, any developer that cares about the tiny performance difference can use an Array to store non-numeric property/value pairs. 1) They're not doing that now, necessarily, and there's no indication that they'll start. 2) A factor of 6 is not a tiny performance difference. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/10/2011 6:50 PM, John Tamplin wrote: If you care about order, you don't use a hash map, and a JS object literal seems more closely related to a hash map than anything else. Object behaved like a LinkedHashMap for 15 years, and still does behave like a LinkedHashMap, even in Chrome, except for numeric keys. It seems like a very broadly held perception that Objects behave this way (based on the record-setting 127 stars on Chrome's issue for this, if nothing else). An alternative you didn't consider in your original post is using a single array, which is guaranteed to not change the order and never pick up additional properties: selectControl.setOptions([ storedValue1, displayValue1, storedValue2, displayValue2, storedValue3, displayValue3 ]) I'm aware, but omitted it because I thought it was an even worse option. It has all the allocation / GC drawbacks of the other approaches mentioned: two Strings per property vs just slots. It also retains the drawback that developers have to build a secondary index to avoid O(n) property change costs, and that this will be slower in practice, for real applications. On top of this, and perhaps worst of all, it has the further disadvantage that it looks like a list of values. You can't look at the code and see that values are being mapped to one another. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 3/10/2011 7:18 PM, Brendan Eich wrote: On Mar 10, 2011, at 6:50 PM, Charles Kendrick wrote: Has a use case been identified where treating numeric properties differently from other properties is a desirable behavior? If I'm reading you right, you don't mind us specifying arrays enumerating indexed own properties first and in index order. Yes, exactly. I understand the performance advantage here and I think Arrays should either do exactly what's in the strawman or even not have a standardized iteration order (for maximum optimization leeway). But it gets worse: several notable JS libraries, including IIRC jQuery (the #1 library in popularity right now), use indexed properties on Object instances -- frequently. I'll try to dig up the references. Those VMs that optimize indexed properties on Object to be (a) fast; (b, and therefore) enumerated in index order, do better on such code. VMs that optimize only for certain dense-enough arrays lose. This creates pressure to follow the performance leader and treat indexed properties the same, in terms of enumeration, on all objects including arrays. You're correct, JQuery returns most query results as an Object where each matching element is placed at a numeric index and it also does a lot of subsetting and traversal on such objects. However, I doubt very much that the effect on JQuery of dense arrays could be shown outside of synthetic benchmarks and very very niche use cases. References would be great if you can find them. However large the effect on JQuery, I expect that a benchmark of a JavaScript LinkedHashMap implementation as compared to native speed would be, I would guess, something like a 25x advantage. Further, note that JQuery's use of Object is an implementation detail that may change in the future. Big chunks of JQuery are now shims for old browsers to duplicate HTML5/CSS3 native support, and libraries are emerging that are roughly JQuery-compatible but directly return an augmented native NodeList instead of an Object with indices: http://chocolatechipmobile.wordpress.com/ JQuery may well adopt this just as it adopted Sizzle, so it would be a shame to optimize the language for such a short-lived advantage. Harmony is *not* a clean break. I don't know why you wrote that. Quite right Brendan, sorry about that, I understand that it's designed as a more minimal break. Thanks for giving me the fingers ;) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss