{
"x": [
{
"y": "a",
"z": 23,
"q": [
54,
32,
45
]
}
],
"r": 43
} {
"x": [
{
"y": "a",
"z": 23,
"q": [
54,
32,
45
]
}
],
"r": 43
}The other difference is that there are JSON parsers and generators for more languages and they're not programmable.
{ ("x" ( { ("y" "a") ("z" 23) ("q" ( 54 32 45 )) } )) ("r" 43) }
SBCL:
(defun f (x y) (let ((z (gethash x :a))) (+ z y))
Clojure
(defn f [x y] (let [z (get x :a)] (+ x y)))
Having syntax for maps is a huge win. Like ML's pattern matching, it's one of those things that changes your coding style entirely for the better, in a way that you wouldn't predict just by looking at the feature.
The only think I miss from CL when I work in Clojure is keyword arguments to functions. There, the Clojure way is a bit worse:
(defun f (x &key y z) (list x y z)) (f 2 :z 3) => (2 nil 3)
(defn f [x {y :y z :z}] (list x y z)) (f 2 {:z 3}) => (2 nil 3)
vs
> (defn f [x y] (let [z (get x :a)] (+ x y)))
The CL defn of f is a function that is called with two arguments. That function is called like "(f a b)" If the Clojure definition is comparable, that is, the call looks like "(f a b)", why are []s used in the definition and the let?
> This slight decrease in regularity makes a lot of functionality more visible.
What functionality? x,y aren't part of a vector and neither is z. (x,y may come from a vector in the caller, but I'll assume that the defn works if they don't, so that shouldn't matter.)
(defn sum-vec [vec] (let [vec-len (count vec)] (loop [idx 0 acc 0] (if (< idx vec-len) (recur (inc idx) (+ acc (vec idx))) acc))))
If I have Javascript then I already have mobile code.
If I'm using json in a situation where I don't have a Javascript interpreter, then I probably don't have a Lisp interpreter around either.
My experience is that it is as little as and possibly less initial development and maintenance as a custom flat-file format or a really robust csv parser.
(I actually prefer Python's style of using indentation to indicate blocks, but I recognize generating such code is harder than code with tokens.)
def indent(code): return code.replace('\n', '\n ')
The code I generate has no indents and no newlines. Not having to keep track of these makes life simpler. To make my generated code more legible, I just run indent on it.
Again, I see no point in making efforts to generate clean looking code when utilities like indent exist.
surely this is unambiguous?
x:
y: "a",
z: "23",
q: 54,
32,
45
,
r: 43