(defun get-v (json &rest path) (loop for k in path for test = (etypecase k (string #'string=) (keyword #'eql)) for v = (cdr (assoc k json :test test)) then (cdr (assoc k v :test test)) while v finally (return v)))
(defun (setf get-v) (new json &rest path) (loop for k in path for test = (etypecase k (string #'string=) (keyword #'eql)) for v = (let ((v (assoc k json :test test))) (unless v (rplacd json (cons (car json) (cdr json))) (rplaca json (cons k nil))) (assoc k json :test test)) then (let ((v* (assoc k (cdr v) :test test))) (unless v* (push (cons k nil) (cdr v))) (assoc k (cdr v) :test test)) finally (progn (setf (cdr v) new) (return json))))