iteration order for Object

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Mar 14 19:26:50 PDT 2011


On Mar 14, 2011, at 9:42 AM, David Bruant wrote:

> Le 14/03/2011 17:02, John Tamplin a écrit :
>> 
>> On Mon, Mar 14, 2011 at 10:21 AM, Brendan Eich <brendan at mozilla.com> wrote:
>> Web developers find and exploit many de-facto standards. Enumeration order being insertion order for non-arrays at least, if not for all objects (arrays tend to be populated in index order), is old as the hills and web content depends on it, as far as I can tell. I'll do some experiments to try to get data on this.
>> 
>> Aside from the JSON example of populating a dropdown list given (which I will agree is a real if contrived use case), there has been a lot of talk of "thousands of web developers" depending on preserving insertion order, but not one concrete example -- do you have one?
> I gave one https://mail.mozilla.org/pipermail/es-discuss/2011-March/013036.html
> It is theorical (sorry, not concrete like "there is code using it right now"), but the point is that for objects (actual objects not arrays) used as "dictionaries", numbers could be used as "alphabetic keys". When the user writes objects as object literals in code, they might (not a single proof since it has never been the case) appreciate if the JS engine kept the order they have written the key in.
> 
> The order the user provides the keys in is the only bit of information (I can think of) that the JS engine looses. But once again, if users would have appreciate this feature, they have been forced (by spec and implementations) to find other ways. So, unless we can reach all web devs to ask "have you ever been disappointed of the implementation for-in loop order?", you cannot really have facts on if they would use the feature. Apparently, for the case of non-numeric properties, they seem satisfied of the implementation which iterate them over
> 
> For more concrete numerical results, let's wait for Brendan to do his experiments (or help him out if there is any way to do so?)
> 
> 
> I think that in-memory objects (created as such) for-in enumeration and JSON.parse created objects are two different concerns. Of course, they should certainly be solved consistently, but they are different in my opinion. 
> 
> I am a bit worried about JSON. JSON as an interchange format is defined as unordered. "An object is an unordered collection of zero or more name/value pairs". If people expect JSON as an interchange format to be ordered, they are assuming something about the JSON parse method which isn't itself standardized either.
If you inspect any JSON document that conforms to the RFC 4627 (for example,  {"y": 1 , "z":2, "x":3})  will see that each object clearly has some specific ordering of its name/value pairs. It must, it is inherent in such a textual representation. "y" is first, then "z", and finally "x". So the language in 4627 that says "An object is an unordered collection of zero or more name/value pairs" clearly can not be saying that the name/value pairs do not occur in some order.  It must mean something else.  Crock can probably tell us exactly what he intended those words to mean. Until he chimes in, I'll make an educated guess about the meaning.  It means that the order of  occurrence of key/value pairs should not be assigned any semantic meaning.  That, {"y": 1 , "z":2, "x":3} and {"x": 3 , "z":2, "1":1} and the 4 other possible permutations of these key/value pairs must all be considered semantically equivalent.

If you are defining a JSON-based schema for some application and that schema assigns semantic significance to key/value pair orderings you are doing sometime outside the bounds of RFC 4627.  You  may well get away with doing so, but there is no guarantee that when somebody tries to ready your JSON document using the FORTRAN  JSON library that the ordering information you thought was implicit will actually be visible to them.

BTW, there is a very straightforward way to encode a ordered set of key/value pairs using 4627 JSON:  ["y",1,"z",2,"x",3].  It's the exact same length as the "object" encoding.  If you want to easily decode it into an object (assume insertion ordering) you might encode it as ["ordered-n/v","y",1,"z",2,"x",3] and then process the document using JSON.parse with a reviver function like:

function reviver(k,v) {
   if (!Array.isArray(v)) return v;
   if (v[0]!=="ordered-n/v") return v;
   var o={};
   var len=v.length;
   for (var i=1;i<len;)  o[v[i++] ]= v[i++]; 
   return o;
}
> 
> One conceptual issue I see with ordering in the ES spec JSON.parse-created objects is that the ECMA spec would explicitely say "we consider that objects are ordered and we decide an order for JSON.parse-created objects, (we decide of an order while there isn't in the JSON format)". Once again, it's conceptual. I would be in favor of adding an order, but it had to be said.
> All of that said, it's a bit weird to say that an interchange format (so something with a beginning, an end and a direction) has some "unordered" part. The JSON grammar itself seem to contain an implicit order:
> JSONMemberList :
>     JSONMember
>     JSONMemberList , JSONMember 
> 
> So I don't know. Does it really make sense to define JSON objects as an unordered collection in the interchange format (in-memory objects are a different story) or is it just an ECMAScript legacy?
> 

In talking about JSON you need to be careful not to conflate the JSON interchange format defined by RFC 4627 with the serialization process required to convert that format to/from the object model of your favorite programming language.  These are two separate things. While, 4627 says name/value pairs are unordered, that doesn't prevent a JSON serialization library from specifying such ordering in its definition of the mapping between 4627 and language "objects" (or whatever language elements are used in the mapping).   ES5 does this for JSON.stringify when it says that the own properties are processed in the same order as produced by Object.keys.  It also specifies this for JSON.parse in step 3 when it says process the JSON document as if it was a ECMAScript Program.  This means the any property ordering that is implicit  in processing object ECMAScript object literals will also be applied to generated objects corresponding to JSONObjects.  (Where this falls short, is where ES5 for reasons already discussed doesn't require a specific enumeration order).

The reason the ES5 JSON spec talks about property ordering, even though 4627 does not, is because we would really like JSON.stringify when run on identical objects by two different ECMASScript implementations to produce exactly the same JSON output.  This isn't saying that the name/value pair ordering has meaning when 4627 says it doesn't.  it is just about making sure that ECMAScript implementations behave identically in as many ways as is possible. This is go for testing and overall interoperability among ECMAScript implementations.

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110314/6de4fce9/attachment-0001.html>


More information about the es-discuss mailing list