Title here
Summary here
Our program demonstrates JSON encoding and decoding in Lisp, including working with built-in and custom data types.
(ql:quickload :cl-json)
(defpackage :json-example
(:use :cl :cl-json))
(in-package :json-example)
;; We'll use these two structs to demonstrate encoding and
;; decoding of custom types below.
(defstruct response1
page
fruits)
(defstruct response2
(page nil :json-key "page")
(fruits nil :json-key "fruits"))
(defun main ()
;; First we'll look at encoding basic data types to
;; JSON strings. Here are some examples for atomic values.
(format t "~a~%" (json:encode-json-to-string t))
(format t "~a~%" (json:encode-json-to-string 1))
(format t "~a~%" (json:encode-json-to-string 2.34))
(format t "~a~%" (json:encode-json-to-string "gopher"))
;; And here are some for lists and hash tables, which encode
;; to JSON arrays and objects as you'd expect.
(let ((slc '("apple" "peach" "pear")))
(format t "~a~%" (json:encode-json-to-string slc)))
(let ((map (make-hash-table :test 'equal)))
(setf (gethash "apple" map) 5)
(setf (gethash "lettuce" map) 7)
(format t "~a~%" (json:encode-json-to-string map)))
;; The JSON package can automatically encode your
;; custom data types.
(let ((res1 (make-response1 :page 1 :fruits '("apple" "peach" "pear"))))
(format t "~a~%" (json:encode-json-to-string res1)))
;; You can use the :json-key option in struct definitions
;; to customize the encoded JSON key names.
(let ((res2 (make-response2 :page 1 :fruits '("apple" "peach" "pear"))))
(format t "~a~%" (json:encode-json-to-string res2)))
;; Now let's look at decoding JSON data into Lisp
;; values. Here's an example for a generic data structure.
(let* ((json-string "{\"num\":6.13,\"strs\":[\"a\",\"b\"]}")
(decoded (json:decode-json-from-string json-string)))
(format t "~a~%" decoded)
(format t "~a~%" (cdr (assoc :num decoded)))
(format t "~a~%" (car (cdr (assoc :strs decoded)))))
;; We can also decode JSON into custom data types.
(let* ((json-string "{\"page\": 1, \"fruits\": [\"apple\", \"peach\"]}")
(res (json:decode-json-from-string json-string)))
(format t "~a~%" res)
(format t "~a~%" (cdr (assoc :fruits res))))
;; In the examples above we always used strings as intermediates
;; between the data and JSON representation. We can also
;; stream JSON encodings directly to output streams.
(let ((map (make-hash-table :test 'equal)))
(setf (gethash "apple" map) 5)
(setf (gethash "lettuce" map) 7)
(json:encode-json map *standard-output*)))
(main)
To run the program, save it as json-example.lisp
and use your Lisp interpreter. For example, if you’re using SBCL:
$ sbcl --load json-example.lisp
This will output:
true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"PAGE":1,"FRUITS":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
((:NUM . 6.13) (:STRS "a" "b"))
6.13
a
(:PAGE 1 :FRUITS ("apple" "peach"))
("apple" "peach")
{"apple":5,"lettuce":7}
We’ve covered the basics of JSON in Lisp here. The cl-json
library provides a comprehensive set of functions for working with JSON in Common Lisp. Remember to check the library’s documentation for more advanced usage and options.