json

Parse JSON text into Bern values and serialize Bern values back to JSON.

import json

Value mapping

JSON values map onto Bern values as follows:

JSONBern value
objectObject (#{ ... }#)
arrayList ([ ... ]) - order and duplicates preserved
stringstring
numberInteger (no fraction/exponent) or Double
true / falseBoolean
nullUndefined

A JSON array maps straight to a Bern List, keeping element order and duplicates. JSON arrays are heterogeneous (e.g. [1, "a", 34.2]); the library enables the impure-lists pragma internally so its own lists may hold mixed types. That pragma is file-scoped - it never leaks into the program importing json.

json_parse("[1, \"a\", 34.2, \"a\", \"banana\"]")
-- Output: [1, "a", 34.2, "a", "banana"]
Round-trip caveat: a Bern string is itself a List of Characters, so an empty list and an empty string are indistinguishable. An empty JSON array therefore serializes back as "". This is the only round-trip edge case; non-empty arrays and strings are always distinguishable by element type.

Parsing

json_parse(text) → value

Parse a JSON document into a Bern value.

person = json_parse("{\"name\": \"Bern\", \"version\": 3}")
person["name"]
-- Output: "Bern"
person["version"]
-- Output: 3
nums = json_parse("[10, 20, 30]")
nums[1]
-- Output: 20

Working with null

is_null(value) → boolean

Test whether a value is a parsed JSON null (i.e. Undefined).

is_null(json_parse("null"))
-- Output: true

doc = json_parse("{\"middle_name\": null}")
is_null(doc["middle_name"])
-- Output: true

Serialization

json_stringify(value) → string

Serialize a Bern value to a JSON string. Object fields are enumerated with the built-in keys(); lists and sets become arrays.

json_stringify(#{ items: [1, 2, 3], ok: true }#)
-- Output: {"items":[1,2,3],"ok":true}

json_stringify(json_parse("[7, 7, 7]"))
-- Output: [7,7,7]

Putting it together

Parsing, editing, and re-serializing is the bread-and-butter workflow. Here we read a config, bump a value, and write it back out:

Round-tripping a config object

import json

raw = "{\"name\": \"bern\", \"version\": 2, \"tags\": [\"lang\", \"fun\"]}"

config = json_parse(raw)
config["version"] = config["version"] + 1
config["tags"] = config["tags"] <> ["docs"]

json_stringify(config)
-- Output: {"name":"bern","version":3,"tags":["lang","fun","docs"]}

And combining with core to summarize an array of records:

Summing values from a JSON array

import core
import json

data = json_parse("[{\"price\": 12}, {\"price\": 40}, {\"price\": 8}]")

total = data
    )| map(\row -> row["price"])
    )| sum

total
-- Output: 60