Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^2: Outputting JSON with sorted names/keys

by afoken (Canon)
on Jan 26, 2020 at 19:01 UTC ( #11111912=note: print w/replies, xml ) Need Help??


in reply to Re: Outputting JSON with sorted names/keys
in thread Outputting JSON with sorted names/keys

I seem to remember that the specs are unclear if sorted hashes (aka objects) are allowed in JSON.

https://www.json.org/ is quite clear:

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

[...]

An object is an unordered set of name/value pairs.

So, "objects" are not sorted, they have no implied order, but you are free to write them out sorted by any criteria you like. But you should not expect that the ordering is retained.

BTW: I think the name "object" is an unfortunate choice, because it is no object in the sense of object-oriented programming.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
  • Comment on Re^2: Outputting JSON with sorted names/keys

Replies are listed 'Best First'.
Re^3: Outputting JSON with sorted names/keys (JS Object vs Perl hash / updated)
by LanX (Archbishop) on Jan 27, 2020 at 12:37 UTC
    > An object is an unordered set of name/value pairs.

    To make it worse, I'm pretty sure that in JS this "object" should be written capitalized as "Object".

    "Object" is the base "object" instance in JS from which all other objects inherit°, including the objects Array and Function. A literal "Object" is written with key value pairs surrounded by curlies. "object" is a type.

    From a Perl perspective objects are best understood as tied hashes which lookup missing keys via the "prototype" chain (exposed in FF thru __proto__ ).

    I'm starting to agree that Crockford should have avoided the term "object" in his JSON definition...

    update

    Demo from the FF console (please note that __proto__ is not necessarily available in other dialects)

    > hash = {a:1} Object { a: 1 } > typeof hash "object" > array = [0,1,2] Array(3) [ 0, 1, 2 ] > typeof array "object" > array.__proto__ Array [] > array.__proto__.__proto__ Object { … }

    update

    > h={} // empty hash? Object { } > h["constructor"] // well, beware of inherited attributes function Object()

    footnote

    °) seems like newer ECMA versions allow the creation of objects without prototype. This would actually be very close to a Perl hash.

    > h = Object.create(null) Object { } > h["constructor"] undefined

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      Feckless pedantry
Re^3: Outputting JSON with sorted names/keys
by LanX (Archbishop) on Jan 26, 2020 at 19:17 UTC
    > BTW: I think the name "object" is an unfortunate choice, because it is no object in the sense of object-oriented programming.

    It is correct in JS, they don't have plain hashes, you have to (ab)use objects.

    In other words you have to take care not to inherit keys. 🙄

    NB: OOP is classless in JS

    > https://www.json.org/ is quite clear:

    Well what I remember were two contradictory RFC's but I can't find the discussion anymore.

    Please keep in mind that like with utf8 definitions changed over time from more relaxed to more strict.

    This leaves some early adopters like Perl sometimes in a limbo of backwards compatibility.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      what I remember were two contradictory RFC's but I can't find the discussion anymore.

      JSON has several RFCs:

      Regarding objects, 4627 is quite short. The introduction defines them as "unordered collection", and the grammer states that the "names within an object SHOULD be unique."

      7158 keeps the definition as "unordered collection" in the introduction, and keeps the requirement that the "names within an object SHOULD be unique", but adds observations of existing implementations regarding duplicate names, and observations of existing implementations regarding member ordering. It also adds a change log.

      7159 is nearly identical to 7158, except for the copyright date. It has only a change log comparing to 4627.

      8259 is a reworked revision of 7159, but the introduction still defines objects as "unordered collection". The object definition is completely unchanged, it has just been moved down so that it now crosses a page boundary. The changelog compares to 7159. 8259 also links to ECMA-404, the ECMA version of the JSON specification.

      ECMA-404, second edition, explicitly states that the "JSON syntax specified by this specification and by RFC 8259 are intended to be identical." Syntax graphs and large parts of the text seem to be copied from https://www.json.org. The introduction does not specify objects as "unordered collection", instead just as "collections of name/value pairs". But chapter 6 differs from the RFCs: "The JSON syntax does not impose any restrictions on the strings used as names, does not require that name strings be unique, and does not assign any significance to the ordering of name/value pairs. These are all semantic considerations that may be defined by JSON processors or in specifications defining specific uses of JSON for data interchange."

      The "historic" first edition of ECMA-404 did not contain that text in chapter 6.

      So ECMA-404, 2nd edition, allows duplicate keys that should be avoided according to the RFCs, and it allows implementations to assume that objects are ordered collections.

      Great. ECMA-404, 2nd edition, defines something different than RFC-8259 and the 1st editition of ECMA-404.


      Update:

      Forgot this one from JSON.org: JSON "is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999".

      The link on the website is broken, but the 3rd Edition can still be found on the "historical edititons" ECMA page.

      4.3.3 defines "An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method." JSON explicitly has no functions, so we can safely ignore the function/method part.

      8.6 repeats: "An Object is an unordered collection of properties. Each property consists of a name, a value and a set of attributes." JSON has no attributes, so we only have to consider name and value. JSON also has no internal properties.

      Everything else, especially name handling, is specified in pseudo-code. Technically, the code implementing Javascript's objects could have special cases to allow sorted keys and non-unique keys. But the definitions for [[Get]], [[Put]], [[CanPut]], [[HasProperty]], and [[Delete]] in 8.6.2 all treat the PropertyName argument as unique. So, in ECMA-262 3rd Edition, object keys are unique. And that matches what we see in Javascript.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        Thanks for tracking it down. :)

        I think of it like of Perl code without strict and warnings . They are recommended but not obligatory.

        See also the definition of SHOULD:

        > Key words for use in RFCs to Indicate Requirement Levels

        3. SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11111912]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2020-05-25 12:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (145 votes). Check out past polls.

    Notices?