jsond
1 Quick Start
2 Syntax
3 Semantics
8.2

jsond

D. Ben Knoble

 #lang jsond package: jsond

This package provides a convienient format to embed JSON data in racket programs by making the JSON data (surprise!) racket programs.

1 Quick Start

Suppose, for example, we had some JSON data consisting of a list of albums and singles.

["Cycles", "Flatspin", "Long Way to Climb"]

We also have a map of user favorites (each value is an index in the albums array).

{

    "Jonathan Gordon": 0,

    "Brad Rubinstein": 2,

    "Paul Willmott": 1,

    "Jason Hall": 0,

    "Adam Rich": 1

}

Normally, we would need to require the json library and use read-json to read these data files. With jsond, however, we can make the files into a program:

#lang jsond
 
#:name albums
["Cycles", "Flatspin", "Long Way to Climb"]
 
#:name favorites
{
    "Jonathan Gordon": 0,
    "Brad Rubinstein": 2,
    "Paul Willmott": 1,
    "Jason Hall": 0,
    "Adam Rich": 1
}

If we put this in a file lisp.rkt, we suddenly have a program!

Examples:
> (require "lisp.rkt")
> albums

'("Cycles" "Flatspin" "Long Way to Climb")

> favorites

'#hasheq((|Adam Rich| . 1)

         (|Brad Rubinstein| . 2)

         (|Jason Hall| . 0)

         (|Jonathan Gordon| . 0)

         (|Paul Willmott| . 1))

> (for/hash ([(member fav-id) (in-hash favorites)])
    (values member (list-ref albums fav-id)))

'#hash((|Adam Rich| . "Flatspin")

       (|Brad Rubinstein| . "Long Way to Climb")

       (|Jason Hall| . "Cycles")

       (|Jonathan Gordon| . "Cycles")

       (|Paul Willmott| . "Flatspin"))

The program can also be run to recover the original JSON. The following racket code is equivalent to running a command-line

# racket lisp.rkt

Example:
> (require (submod "lisp.rkt" main))

{"albums":["Cycles","Flatspin","Long Way to Climb"],"favorites":{"Adam Rich":1,"Brad Rubinstein":2,"Jason Hall":0,"Jonathan Gordon":0,"Paul Willmott":1}}

The jsond language supports all of the JSON specification in JSON values, as well as regular racket comments between value definitions:

  #lang jsond
   
  #:name abc "abc"
   
  ;; comment
   
  #:name num 123
   
  #:name array [1, 2, {"xyz": "abc"}, true, false, null]
   

Examples:
> (require jsond/examples/data)
> abc

"abc"

> num

123

> array

'(1 2 #hasheq((xyz . "abc")) #t #f null)

2 Syntax

 

jsond

 ::= 

name-json*

 

name-json

 ::= 

#:name id json

There may be any style of racket comment between name-jsons. Each use of #:name, id, and json must be whitespace-separated. json can be any valid JSON value as determined by read-json. id can be any valid Racket identifier.

3 Semantics

The jsond language produces a module that provides each of the ids as a binding to the jsexpr? corresponding to the adjacent json.

The module has a submodule main that, when run, calls write-json on a hash mapping each provided id to its value.