How do Lisp developers deal with XML and JSON? Convert it to s-expressions.

As a common lisp developer, that is only very vaguely true for me.

The mapping I prefer for json<->Lisp is:

  true:  t
  false: nil
  null:  :null
  []     #()
  {}     (make-hash-table :test #'equal)
This falls out of my desire for the mapping to be bijective:

- The only built-in type that is unambiguously a mapping type is hash-tabe.

- nil is the only value that is falsy in CL

- () is the same as nil, so we can't use it as an empty list; vectors are the obvious alternative

- Not really any obvious values left to use for "null" so punt to a keyword.

In Kernel I would use something like this:

    true        #t
    false       #f
    null        ()
    [...]       (& ...)
    "k" : v     (: k v)
    {...}       (@ ...)  
Where &, :, @ are defined as:

    ($define! &
        ($lambda args (cons list args)))

    ($define! : 
        ($vau (key value) env
            (list key (eval value env))))
            
    ($define! @ 
        (wrap 
            ($vau kvpairs env 
                (eval (list* $bindings->environment kvpairs) env))))
Using the "person" example from the JSON/syntax section on Wikipedia:

    ($define! person
        (@
            (: first_name "John")
            (: last_name "Smith")
            (: is_alive #t)
            (: age 27)
            (: address 
                (@
                    (: street_address "21 2nd Street")
                    (: city "New York")
                    (: state "NY")
                    (: postal_code "10021-3100")))
            (: phone_numbers
                (& (@ (: type "home") (: number "212 555-1234"))
                   (@ (: type "office") (: number "646 555-4567"))))
            (: children
                (& "Catherine" "Thomas" "Trevor"))
            (: spouse ())))
I would then define `?`

    ($define! ? $remote-eval)
Now we can query the object.

    > (? age person)
    27

    > (? postal_code (? address person))
    "10021-3100"

    > (car (? children person))
    "Catherine"

    > (cdr (? children person))
    ("Thomas" "Trevor")

    > (? type (cadr (? phone_numbers person)))
    "office"

    > (? number (car (? phone_numbers person)))
    "212 555-1234"

    > ($define! full_name ($lambda (p) (string-append (? first_name p) " " (? last_name p))))
    > (full_name person)
    "John Smith"

In Clojure

    true: true
    false: false
    null: nil
    []: []
    {}: {}