S-Expressions: The Fat-Free Alternative to JSON
shinkirou.org
shinkirou.org
If you need to markup your data, use a markup language like XML or S-Expressions. If you need to serialize data, JSON is an excellent choice.
C, asm, ML, Lisp, Java, Tcl?
Javascript Object Notation
eXtended Markup Language
JSON's a nearly-perfect balance between human-readability, ease of generation/parsing, and data size. I'm not going to say that it can't get better, but I feel pretty okay saying that I don't feel a burning need to replace it.
[1,[2,3],4,{"a":5,"b":6}] // 25 characters
can be rewritten as: [1[2 3]4{"a":5 "b":6}] // 22 characters
Also, currently, JSON requires all string literals to be quoted. If we relax that constraint and only quote string literals that contain escape characters, we can achieve even more space savings. The above example can be rewritten as: [1[2 3]4{a:5 b:6}] // 18 characters
And, in my opinion, the formatted version (with uncollapsed spaces) is just as readable as the original JSON expression: [1 [2 3] 4 {a:5 b:6}] // 21 charactersIf the data set is fairly large, then the markup will contribute much less to the overall size, so the improvement will probably be more like 5-10%. After HTTP compression, the difference might be negligible.
Testing should definitely be done to see if the space saving is worth the additional parsing overhead (relaxing constraints makes the language more complicated).
Same applies to the original post, especially since the examples seem even more contrived. E.g., the author goes from <p></p> in (X)HTML to delimit a paragraph to {"format":"Paragraph","content":[]} in JSON, when one could just as easily contrive <format type="paragraph"></format> in XML versus {"p":[]} to make JSON look better.
It's about as lispy you can get without being Lisp. The curly braces could be changed to parentheses and it would be rather trivial to write a Lisp macro to parse JSON into a nested set of associative arrays or hash maps.
In fact, if you just remove the JS ':' member notation, you can shove most of JSON into a Clojure repl already, since Clojure supports the convenient {} notation for maps.
There's no reason to make JSON look precisely like Lisp. Given that many people seem to be allergic to Lisp-style nested parentheses once they've been educated that it's Lisp, JSON offers the flexibility of constructing arbitrary sexp trees without people ever noticing they're almost generating and parsing Lisp.
When writing Lisp, it's of course sensible to use sexps instead of JSON for internal marshalling.
Reminds me of this tiny LISP: http://www.brool.com/index.php/the-tiniest-lisp-in-python
JSON: [[ "if" [ ">" a b ] "foo" "bar" ]
If you are writing code then I'd go for the Lisp approach, for general purpose data then these days I'd go with JSON.
If you can answer this question then you have already answered your own question.
But if your answer is "I don't have to because I use Lisp and I don't use other languages" then you miss the point of JSON.
(p "Paragraph text here, " (b "bold text"))
becomes ['p','paragraph text here, ',['b','bold text']]
where space become commas, and '()' become '[]'.The json example form html formatting is willingly verbose without reason to be.
{ 'p': ['Paragraph text here', { 'b': 'bold text' }] }
Still more verbose than the sexp example but not terribly so. (or (= 0 (+ x y)) (print "hi"))
['or', ['=', 0, ['+', 'x', 'y']], ['print', 'hi']] {'a': 1}
{'a': [1]}
['a' 1]
['a' [1]]
into this: ('a' 1)
Isn't that ambiguous? Or, do they need to be demarcated using special tokens (e.g. a for array and o for object) like this? {'a': 1} => (o ('a' 1))
{'a': [1]} => (o ('a' (a 1)))
If that's the case, nested arrays would require more characters to encode in S-expression than in JSON. ['a',['b',['c',['d',['e']]]]]
vs (a 'a' (a 'b' (a 'c' (a 'd' (a 'e')))))An even simpler problem is how do you express an empty array and an empty object in S-expressions? Is it () for both?
EDIT: and what about nulls? What about strings that resemble numbers?
["a", "b", "c"]
("a" "b" "c")
Since people generally put spaces after their commas.{'a': 1} -> (dict ('a' 1))
{'a': [1]} -> (dict ('a' (1)))
['a' 1] -> ('a' 1)
['a' [1]] -> ('a' (1))
['a',['b',['c',['d',['e']]]]] -> ('a' ('b' ('c' ('d' ('e')))))
Any sufficiently complicated C or Fortran program
contains an ad-hoc, informally-specified, bug-ridden,
slow implementation of half of CommonLisp. Any sufficiently complicated CommonLisp
program contains an ad-hoc, informally-specified,
bug-ridden, slow implementation of half of Prolog. Including Common Lisp.It's not really a general serialization solution at all.
I laughed at that. Lisp-ers might want to have a word with him.
Well, I thought it was a clever joke, anyway.