sigildocs

JSON

Bidirectional conversion between JSON and Scheme values.
(import (sigil json))

Type Mapping

JSONScheme
objectdict: #{ name: "Alice" }
arrayarray: #[1 2 3]
stringstring: "hello"
numbernumber: 42, 3.14
true#t
false#f
null'null symbol

json-encode

Convert a Scheme value to a JSON string.

;; Objects (dicts or alists)
(json-encode #{ name: "Alice" age: 30 })
; => "{\"name\":\"Alice\",\"age\":30}"

(json-encode '((name . "Alice") (age . 30)))
; => "{\"name\":\"Alice\",\"age\":30}"

;; Arrays
(json-encode #[1 2 3])
; => "[1,2,3]"

;; Primitives
(json-encode "hello")  ; => "\"hello\""
(json-encode 42)       ; => "42"
(json-encode #t)       ; => "true"
(json-encode 'null)    ; => "null"

;; Pretty-print with indentation
(json-encode #{ a: 1 b: #[2 3] } indent: #t)
; => "{\n  \"a\": 1,\n  \"b\": [\n    2,\n    3\n  ]\n}"

(json-encode #{ x: 1 } indent: 4)  ; 4-space indent

json-decode

Parse a JSON string into Scheme values.

;; Objects become dicts
(json-decode "{\"name\": \"Alice\", \"age\": 30}")
; => #{ name: "Alice" age: 30 }

;; Arrays become arrays
(json-decode "[1, 2, 3]")
; => #[1 2 3]

;; Nested structures
(json-decode "{\"user\": {\"name\": \"Bob\"}, \"scores\": [10, 20]}")
; => #{ user: #{ name: "Bob" } scores: #[10 20] }

;; Primitives
(json-decode "true")   ; => #t
(json-decode "null")   ; => null (symbol)
(json-decode "3.14")   ; => 3.14

;; Convert to alist if needed
(dict->alist (json-decode "{\"x\": 1}"))
; => ((x . 1))

json-read / json-write

Port-based I/O for streaming to files or sockets.

;; Write to file
(call-with-output-file "data.json"
  (lambda (port)
    (json-write #{ name: "Alice" } port)))

;; Read from file
(call-with-input-file "data.json" json-read)

;; Write to stdout
(json-write #{ x: 1 y: 2 } (current-output-port))

;; Pretty-print to port
(json-write data port indent: #t)

json-null?

Check if a value is JSON null (the symbol 'null).

(json-null? 'null)  ; => #t
(json-null? #f)     ; => #f (false is not null)
(json-null? '())    ; => #f

(json-null? (json-decode "null"))   ; => #t
(json-null? (json-decode "false"))  ; => #f

Common Patterns

Parse API Response

(import (sigil json)
        (sigil http))

(let* ((response (http-get "https://api.example.com/users"))
       (data (json-decode (http-response-body response))))
  (dict-ref data users:))

Build API Request

(let ((body (json-encode #{ name: "Alice" email: "alice@example.com" })))
  (http-post "https://api.example.com/users"
             body
             '(("Content-Type" . "application/json"))))

Read Config File

(define (read-config path)
  (call-with-input-file path json-read))

(let ((config (read-config "config.json")))
  (dict-ref config database:))