Loading ...
Sorry, an error occurred while loading the content.

Cycles

Expand Messages
  • Douglas Crockford
    JSON is not able to directly represent cyclical structures. However, with some simple transformation, it can. This is demonstrated by two JavaScript functions,
    Message 1 of 3 , Oct 27, 2008
    View Source
    • 0 Attachment
      JSON is not able to directly represent cyclical structures. However,
      with some simple transformation, it can. This is demonstrated by two
      JavaScript functions, decycle(value) and retrocycle(value).

      decycle produces a deep copy of a value, except that recurrences are
      replaced with JSPON notations. retrocycle modifies an object by
      replacing JSPON notations, restoring cycles. The result of decycle can
      be given to an encoder (such as JSON.stringify). The result of a JSON
      decoder (such as JSON.parse) can be given to retrocycle.

      These functions use a subset of Kris Zyp's JSPON, which uses a subset
      of Stefan Goessner's JSONPath.

      See http://www.JSON.org/cycle.js
    • Kris Zyp
      This is great to see, obviously I am pleased to see further adoption of reference-capable JSON. I did want to make a few comments: While I had originally
      Message 2 of 3 , Oct 27, 2008
      View Source
      • 0 Attachment
        This is great to see, obviously I am pleased to see further adoption of
        reference-capable JSON. I did want to make a few comments:

        While I had originally specified "$" as the reference to the root of
        current JSON document following the lead of JSONPath, I have since began
        to think that "#" is be a better choice. The reason for this is because
        full JSON referencing (formerly known as JSPON, JSPON was an earlier
        attempt at full CRUD protocol, but now it essentially superseded by HTTP
        + JSON + JSON referencing) is intended to be exactly analogous to the
        semantics of hyperlinks, with resolution following the rules of relative
        URIs, essentially allowing JSON to act as RESTful hypermedia with JSON
        referencing is applied. Path-based referencing is intended to define the
        referencing targets based upon position in the current JSON document and
        integrates well with the relative URL, forming a subset that is purely
        internal. Path-based referencing is the subset of JSON referencing that
        Crockford has implemented in cycle.js. However, in the context of
        considering path-based referencing as a proper subset of full relative
        URI based hyperlinking, it is actually more semantically correct to
        prefix a path-based reference with "#". The "#" symbol is specifically
        designated to have the purpose of referencing parts of the currently
        loaded document. Just as we use the hash part of URLs in HTML to
        navigate to different parts of a page, this is analogous to
        resolving/dereferencing different parts of the current JSON
        document/object graph. By using the "#" symbol to refer to the root of
        the JSON document, this path-based referencing can act as an exact
        subset of relative URI referencing, where the references implicitly
        indicate that their targets are internal, and referencing
        implementations like cycle.js can act on this exact subset without any
        further relative URI knowledge while implementations that are integrated
        with URI resolving and retrieval capabilities can act on the full set of
        JSON references without incompability.

        For further information on JSON referencing (with path and id-based
        referencing), I originally described it here:
        http://www.json.com/2007/10/19/json-referencing-proposal-and-library/,
        with some more examples here:
        http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo/. This
        is all with the original "$" notation for the root. The impetus for
        using "#" came from recent discussions with the RESTful JSON group
        (http://groups.google.com/group/restful-json, and cc'ing them on this
        email), and my resultant proposal for RESTful JSON interaction
        (http://www.json.com/specifications/json-resources/). I haven't updated
        these blog posts nor http://jspon.org with the "#" because these
        discussions were quite recent, and actually I would love to get feedback
        from this group for the best approach. Right now Dojo's implementation
        of JSON referencing uses the "#" notation. However, I would certainly be
        willing to change it per the consensus of the community.

        Also, I am certainly not asking for a change in names, but I have been
        hesitant to use the term cycle/circular only because I think multiple
        referencing is every bit as valuable circular referencing. Multiple
        referencing is covered by cycle.js as well; cycles are subset of the
        referencing dependent data structures that are enabled by cycle.js. For
        example:

        var b= {foo:"bar"};
        var c={d:b,e:b};
        JSON.stringify(decycle(c)) ->
        "{"d":{"foo":"bar"},"e":{"$ref":"$[\"d\"]"}}"
        And
        var newC = retrocycle(decycle(c));
        newC.d === new.e // -> true (identity is preserved)

        Just didn't want you to sell yourself on the capabilities of this
        library, it does more than it's name suggests.

        Anyway, once again, I think this library looks great, it is exciting to
        see the growing potential for ubiquitous interchange of rich data
        structures with a common technique for referencing implemented by this
        library, Dojo, Persevere, and hopefully others.
        Thanks,
        Kris

        Douglas Crockford wrote:
        >
        > JSON is not able to directly represent cyclical structures. However,
        > with some simple transformation, it can. This is demonstrated by two
        > JavaScript functions, decycle(value) and retrocycle(value).
        >
        > decycle produces a deep copy of a value, except that recurrences are
        > replaced with JSPON notations. retrocycle modifies an object by
        > replacing JSPON notations, restoring cycles. The result of decycle can
        > be given to an encoder (such as JSON.stringify). The result of a JSON
        > decoder (such as JSON.parse) can be given to retrocycle.
        >
        > These functions use a subset of Kris Zyp's JSPON, which uses a subset
        > of Stefan Goessner's JSONPath.
        >
        > See http://www.JSON.org/cycle.js <http://www.JSON.org/cycle.js>
        >
        >


        [Non-text portions of this message have been removed]
      • Red Daly
        I made RJSON about a year ago to handle cycles and types. It uses function call forms, as used by cyclic JSON, but instead of a JSON path it uses integers or
        Message 3 of 3 , Oct 27, 2008
        View Source
        • 0 Attachment
          I made RJSON about a year ago to handle cycles and types. It uses function
          call forms, as used by cyclic JSON, but instead of a JSON path it uses
          integers or strings ids to encode references. This way you can transmit
          object graphs that reference objects that have already been sent, cannot be
          sent, etc. by referencing a non-local id.

          If you can read lisp, this example should be obvious:

          (rjson:encode-rjson
          (let* ((a (list "one" "two" "three"))
          (b a)
          (fruit (make-instance 'fruit :calories 55)))
          (push a a)
          (list a b fruit))
          *standard-output*)

          ->
          {"header":{
          "allocs":[rjalloc(2,"json:array")],
          "inits":[rjinit(2,["one","two","three"])]
          },"content":
          [ [rjref(2),"one","two","three"], // a
          rjref(2), //b
          rjconstruct("fruit",{"calories":55})] // fruit
          }

          The four Javascript functions required to implement this are rjalloc,
          rjinit, rjref, and the auxiliary rjconstruct. Allocation occurs first to
          assign an ID to cross-referenced objects; these objects are then initialized
          with some piece of data; the objects may then be cross-referenced with
          rjref. Assuming these functions are implemented, you decode an RJSON
          string in Javascript with eval( rjsonString ).content

          This does not cover all cases for transmitting graphs efficiently, but I
          have found it a sufficiient JSON++ for my needs.

          See
          http://common-lisp.net/project/suave/

          or the implementation
          http://common-lisp.net/project/suave/darcs/rjson/lisp-src/rjson-encode.lisp

          Best,
          Red Daly

          On Mon, Oct 27, 2008 at 9:34 PM, Kris Zyp <kriszyp@...> wrote:

          > This is great to see, obviously I am pleased to see further adoption of
          > reference-capable JSON. I did want to make a few comments:
          >
          > While I had originally specified "$" as the reference to the root of
          > current JSON document following the lead of JSONPath, I have since began
          > to think that "#" is be a better choice. The reason for this is because
          > full JSON referencing (formerly known as JSPON, JSPON was an earlier
          > attempt at full CRUD protocol, but now it essentially superseded by HTTP
          > + JSON + JSON referencing) is intended to be exactly analogous to the
          > semantics of hyperlinks, with resolution following the rules of relative
          > URIs, essentially allowing JSON to act as RESTful hypermedia with JSON
          > referencing is applied. Path-based referencing is intended to define the
          > referencing targets based upon position in the current JSON document and
          > integrates well with the relative URL, forming a subset that is purely
          > internal. Path-based referencing is the subset of JSON referencing that
          > Crockford has implemented in cycle.js. However, in the context of
          > considering path-based referencing as a proper subset of full relative
          > URI based hyperlinking, it is actually more semantically correct to
          > prefix a path-based reference with "#". The "#" symbol is specifically
          > designated to have the purpose of referencing parts of the currently
          > loaded document. Just as we use the hash part of URLs in HTML to
          > navigate to different parts of a page, this is analogous to
          > resolving/dereferencing different parts of the current JSON
          > document/object graph. By using the "#" symbol to refer to the root of
          > the JSON document, this path-based referencing can act as an exact
          > subset of relative URI referencing, where the references implicitly
          > indicate that their targets are internal, and referencing
          > implementations like cycle.js can act on this exact subset without any
          > further relative URI knowledge while implementations that are integrated
          > with URI resolving and retrieval capabilities can act on the full set of
          > JSON references without incompability.
          >
          > For further information on JSON referencing (with path and id-based
          > referencing), I originally described it here:
          > http://www.json.com/2007/10/19/json-referencing-proposal-and-library/,
          > with some more examples here:
          > http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo/. This
          > is all with the original "$" notation for the root. The impetus for
          > using "#" came from recent discussions with the RESTful JSON group
          > (http://groups.google.com/group/restful-json, and cc'ing them on this
          > email), and my resultant proposal for RESTful JSON interaction
          > (http://www.json.com/specifications/json-resources/). I haven't updated
          > these blog posts nor http://jspon.org with the "#" because these
          > discussions were quite recent, and actually I would love to get feedback
          > from this group for the best approach. Right now Dojo's implementation
          > of JSON referencing uses the "#" notation. However, I would certainly be
          > willing to change it per the consensus of the community.
          >
          > Also, I am certainly not asking for a change in names, but I have been
          > hesitant to use the term cycle/circular only because I think multiple
          > referencing is every bit as valuable circular referencing. Multiple
          > referencing is covered by cycle.js as well; cycles are subset of the
          > referencing dependent data structures that are enabled by cycle.js. For
          > example:
          >
          > var b= {foo:"bar"};
          > var c={d:b,e:b};
          > JSON.stringify(decycle(c)) ->
          > "{"d":{"foo":"bar"},"e":{"$ref":"$[\"d\"]"}}"
          > And
          > var newC = retrocycle(decycle(c));
          > newC.d === new.e // -> true (identity is preserved)
          >
          > Just didn't want you to sell yourself on the capabilities of this
          > library, it does more than it's name suggests.
          >
          > Anyway, once again, I think this library looks great, it is exciting to
          > see the growing potential for ubiquitous interchange of rich data
          > structures with a common technique for referencing implemented by this
          > library, Dojo, Persevere, and hopefully others.
          > Thanks,
          > Kris
          >
          >
          > Douglas Crockford wrote:
          > >
          > > JSON is not able to directly represent cyclical structures. However,
          > > with some simple transformation, it can. This is demonstrated by two
          > > JavaScript functions, decycle(value) and retrocycle(value).
          > >
          > > decycle produces a deep copy of a value, except that recurrences are
          > > replaced with JSPON notations. retrocycle modifies an object by
          > > replacing JSPON notations, restoring cycles. The result of decycle can
          > > be given to an encoder (such as JSON.stringify). The result of a JSON
          > > decoder (such as JSON.parse) can be given to retrocycle.
          > >
          > > These functions use a subset of Kris Zyp's JSPON, which uses a subset
          > > of Stefan Goessner's JSONPath.
          > >
          > > See http://www.JSON.org/cycle.js <http://www.JSON.org/cycle.js>
          > >
          > >
          >
          > [Non-text portions of this message have been removed]
          >
          >
          >


          [Non-text portions of this message have been removed]
        Your message has been successfully submitted and would be delivered to recipients shortly.