Comparison of selected data serialization formats.
- JSON - ECMA-404
- EDN - github.com/edn-format/edn
- CLJ - clojure.org/reader
| JSON | EDN | CLJ | |
|---|---|---|---|
| whitespace character | U+0009 (tab) U+000A (newline) U+000D (return) and U+0020 (space) | whitespace chars, explicitly mentions just , |
|
| delimiters | whitespaces, all structural ({ } : , [ ]) and literal (true false null) tokens |
whitespaces and [ ] { } ( ) ( " \ ;) |
[ ] { } ( ) " \ ; @ ^ ` ~ (:warning: no explicit mention in specs) |
| JSON | EDN | CLJ | |
|---|---|---|---|
| null literal | null |
nil |
nil |
| JSON | EDN | CLJ | |
|---|---|---|---|
| true literal | true |
true |
true |
| false literal | false |
false |
false |
| JSON | EDN | CLJ | |
|---|---|---|---|
| syntax | NONE ❌ | \X |
\X |
| special characters | n/a | \newline \tab \return \space |
\newline \tab \return \space \backspace \formfeed |
| unicode escapes | n/a | \uNNNN |
\uNNNN |
| octal escapes | n/a | NO ❌ | \o0 to \o377 |
| JSON | EDN | CLJ | |
|---|---|---|---|
| syntax | wrapped in " |
wrapped in " |
wrapped in " |
| may span multiple lines | NO ❌ | YES | YES |
| characters which must be escaped | " \ and control characters (U+0000 to U+001F) |
" \ |
" \ |
| escape characters | \" \\ \/ \b \f \n \r \t |
\" \\ \n \r \t |
\" \\ \' \b \f \n \r \t |
| unicode escapes | \uNNNN |
NO, not mentioned in specs ❌ | \uNNNN |
| octal escapes | NO ❌ | NO ❌ | \0 to \377 |
| JSON | EDN | CLJ | |
|---|---|---|---|
| varbitrary precision indicator | NO ❌ | N suffix |
N suffix |
| vvalid signs | - |
- + |
- + |
-0 is valid |
YES | YES | YES |
| decimal integer | YES | YES | YES |
| custom radix | NO ❌ | NO ❌ | NNrNNNNN |
| hexa integer | NO ❌ | NO ❌ | 0xNNNNN, but undocumented |
| octal integer | NO ❌ | NO ❌ | 0NNN, but undocumented |
| JSON | EDN | CLJ | |
|---|---|---|---|
| ratios | NO ❌ | NO ❌ | NN/NN |
| decimals | NO ❌ | M suffix |
M suffix |
| floats | YES | YES | YES |
| valid signs | - |
- + |
- + |
| JSON | EDN | CLJ | |
|---|---|---|---|
| symbols | NO ❌ | YES | YES |
| symbol start character | n/a | alphabetic, + - . followed by non-numeric symbol character, * ! _ ? $ % & = < > (/ is special, see below) |
alphabetic, + - * ! _ ? (/ and . are special, see below), ( $ = < > % &) |
| symbol character | n/a | alphanumeric, + - . * ! _ ? $ % & = < > : # |
alphanumeric, + - * ! _ ? (. / and : are special, see below), ( $ = < > % & # ') |
| special symbol character | n/a | /, used alone or in following combinations foo/bar (:warning: In my opinion specs does not allow foo// combination, see this ticket). First character after slash must follow rule for symbol start character |
/, used alone or in following combinations foo/bar foo// (:warning: latter combination is undocumented). ., used as prefix or suffix is reserved to Clojure, used inside symbol divides namespace or package names. : can be used inside symbol, used as suffix is reserved to Clojure (currently it produces an error). (:warning: undocumented restrictions: symbol can not contain ::, namespace part can not end with :, first character after slash must follow rule for symbol start character) |
| keyword | NO ❌ | prefixed with : |
prefixed with : |
| keyword character | n/a | alphanumeric, + - . * ! _ ? $ % & = < > : # |
alphanumeric, + - * ! _ ? (. / and : are special, see below), ( $ = < > % & # ') |
| keyword invalid second character | n/a | : |
none special |
| special keyword character | n/a | /, used in following combinations :foo// :foo/bar. First character after slash must follow rule for symbol start character |
/, used in following combinations :foo/bar :foo// (:warning: latter combination is undocumented). : used as second character resolves keyword in the current namespace, used as suffix is reserved to Clojure (currently it produces an error). (:warning: undocumented restrictions: keyword can not contain :: other than as a prefix, namespace part can not end with :, first character after slash must follow rule for symbol start character) Specs also say that keywords cannot contain '.' ( |
| JSON | EDN | CLJ | |
|---|---|---|---|
| list | NO ❌ | (a b c) |
(a b c) |
| vector | [a, b, c] |
[a b c] |
[a b c] |
| set | NO ❌ | #{a b c} items are unique |
#{a b c} items are unique |
| map | {string1 : val1, string2 : val2] |
{key1 val1 key2 val2} keys are unique |
{key1 val1 key2 val2} keys are unique |
| JSON | EDN | CLJ | |
|---|---|---|---|
| comments | NO ❌ | ; till the end of the line |
; till the end of the line |
| discard | NO ❌ | #_ discards next read object |
#_ discards next read object |
| tagged literal | NO ❌ | # followed immediately by a symbol starting with an alphabetic character |
# followed immediately by a symbol starting with an alphabetic character |
| builtin tags | n/a | #inst #uuid |
#inst #uuid, deftypes, defrecords and java classes constructors |
| regular expressions | NO ❌ | NO ❌ | #"pattern" |
| macros | NO ❌ | NO ❌ | ' (quote), @ (deref), ^ (metadata), #' (var quote), #(% %n %&) (anonymous function), ` (syntax quote), ~ (unquote), ~@ (unquote splicing). (:warning: undocumented macros #= #! #< and deprecated #^) |