15

I like json as a format for configuration files for the software I write. I like that it's lightweight, simple, and widely supported. However, I'm finding that there are some things I'd really like in json that it doesn't have.

Json doesn't have multiline strings or here documents ( http://en.wikipedia.org/wiki/Here_document ), and that is often very awkward when you want your json file to be human-readable and -editable. You can use arrays of strings, but that's a kludgy workaround.

Json doesn't allow comments.

If you look at the formats of unix configuration files, you see a lot of people designing their own awkward formats for things that it would really make more sense to do using some kind of general-purpose thing. For example, here's some code from an Apache config file:

RewriteEngine on
RewriteBase /temp
RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml
RewriteCond %{HTTP_ACCEPT} !application/xhtml\+xml\s*;\s*q=0
RewriteCond %{REQUEST_URI} \.html
RewriteCond %{THE_REQUEST} HTTP/1\.1
RewriteRule t\.html t.xhtml [T=application/xhtml+xml]

Essentially, what's going on here is that they've invented an extremely painful way of writing a boolean function f(w,x,y,z)=w&!x&y&z. You want a logical "or"? They've got some separate (ugly) mechanism for that, too.

What this seems to point toward is some kind of data description language that is simple and Turing-incomplete, but still more expressive, flexible, and convenient than json. Does anyone know of such a language?

To my taste, XML is too complicated, and lisp expressions have the wrong features (Turing-completeness) and lack the right features (here documents, expressive syntax).

[EDIT] The title is misleading. I'm not literally interested in the next iteration of json. I'm not interested in languages that are a subset of javascript. I'm interested in alternative data-description languages.

  • 3
    [YAML](http://en.wikipedia.org/wiki/YAML)? – BalusC Jan 11 '12 at 03:23
  • @BalusC: Interesting suggestion :-) But YAML doesn't seem to offer any nice way of doing the boolean function/Apache example, or applications of a similar flavor. –  Jan 11 '12 at 03:52

9 Answers9

5

The EDN format is one option based on Clojure literals. It is almost a superset of JSON, except that no special symbol separates keys and values in maps (as : does in JSON); rather, all elements are separated by whitespace and/or a comma and a map is encoded as a list with an even number of elements, enclosed in {..}.

EDN allows for comments (to newline using ;, or to end of the next element read using #_), but not here-docs. It is extensible to new types using a tag notation:

#myapp/Person {:first "Fred" :last "Mertz"}

The argument of the myapp/Person tag (i.e. {:first "Fred" :last "Mertz"}) must be a valid EDN expression, which makes it unextensible to here-doc support.

It has two built-in tags: #inst for timestamps and #uuid. It also supports namespaced symbol (i.e. identifier) and keyword (i.e. map key consts) types; it distinguishes lists (..) and vectors [..]. An element of any type may be used as a key in a map.

In the context of your above problem, one could invent an #apache/rule-or tag which accepts a sequence of elements, whose semantics I leave up to you!

joeln
  • 3,563
  • 25
  • 31
4

Have a look at http://github.com/igagis/puu/

It is even simpler than JSON.

It has C++ style comments.

It is possible to format multiline strings and use escaped new line \n and tab \t chars if "real" new line or tab is needed.

Here is the example snippet:

"String object"
AnotherStringObject
"String with children"{
    "child 1"
    Child2
    "child three"{
        SubChild1
        "Subchild two"

        Property1 {Value1}
        "Property two" {"Value 2"}
        //comment

        /* multi-line
           comment */

        "multi-line
         string"

        "Escape sequences \" \n \r \t \\"
    }

R"qwerty(
This is a
raw string, "Hello world!"
int main(argc, argv){
    int a = 10;
    printf("Hello %d", a);
}
)qwerty"
}
igagis
  • 1,959
  • 1
  • 17
  • 27
  • This is love at first sight. It even has raw string literal awesome – Abdurrahim Mar 10 '17 at 09:16
  • Glad that you liked it. Unfortunately, raw string support is only implemented in C++ library. C# and Java libs are lacking raw strings support at the moment. – igagis Mar 10 '17 at 10:57
  • Guess it's time to collaborate the OS development. Especially C# library needs improvement seems like a C++ developer wrote it :) – Abdurrahim Mar 11 '17 at 14:38
3

Consider TOML. Designed for configuration. Appears to be pretty friendly and powerful. Easy to read and supports a wide range of datatypes and structures. There are parsers for a lot of languages: C C# C++ Common Lisp Crystal Dart Erlang Fortran Go Janet Java JavaScript Julia Kotlin Lua Nim OCaml Perl Perl6/Raku Python Rust Swift V

David M
  • 51
  • 2
  • ToML is used in gradle's dependency version definitions https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml – Anarchofascist Mar 25 '22 at 14:15
2

Since March 2018 you can use JSON5 which seems to have added everything you (& many others) were missing from JSON.

Short Example (JSON5)

{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}

The JSON5 Data Interchange Format (JSON5) is a superset of JSON that aims to alleviate some of the limitations of JSON by expanding its syntax to include some productions from ECMAScript 5.1.

Summary of Features

The following ECMAScript 5.1 features, which are not supported in JSON, have been extended to JSON5.

Objects

  • Object keys may be an ECMAScript 5.1 IdentifierName.
  • Objects may have a single trailing comma.

Arrays

  • Arrays may have a single trailing comma.

Strings

  • Strings may be single quoted.
  • Strings may span multiple lines by escaping new line characters.
  • Strings may include character escapes.

Numbers

  • Numbers may be hexadecimal.
  • Numbers may have a leading or trailing decimal point.
  • Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
  • Numbers may begin with an explicit plus sign.

Comments

  • Single and multi-line comments are allowed.

White Space

  • Additional white space characters are allowed.

GitHub: https://github.com/json5/json5

DJDaveMark
  • 2,669
  • 23
  • 35
  • To be fair, comments support in JSON5 is partial, because JSON5 does not preserve comments after saving configuration back in JSON (i.e. you can use comments in JSON5 only for read-only configuration files as JSON5.stringify() returns json without comments). – tav Jan 23 '19 at 00:06
  • @tav Absolutely, since comments are only for developers. Once you parse the contents, the comments have already been _lost_. So it's not `stringify's fault`. That's the way it's supposed to happen. Another example: Compiled Java classes don't contain the comments. Decompile one. You wont find them. – DJDaveMark Jan 23 '19 at 10:08
  • Lacking native regexp support in JSON5 really puts me off. – Marshal Feb 22 '19 at 05:51
  • @Marshal [Here's the discussion](https://github.com/json5/json5/issues/91#issuecomment-197048166) about why native RegExp support didn't make it into JSON5 `v1.0`. I tend to agree. RegExp as a string is no biggie for me. – DJDaveMark Feb 22 '19 at 08:44
  • @DJDaveMark Thanks for the link. Is the experimental feature still not in the current JSON5 release? If so the current suggested way of stringify regex is using the replacer function like:? Thanks. – Marshal Feb 24 '19 at 22:48
1

The 'J' in JSON is "Javascript". If a particular desired syntax construct isn't in Javascript, then it won't be on JSON.

Heredocs are beyond JSON's purview. That's a language syntax construct for simplified multi-line string definition, but JSON is a transport notation. It has nothing to do with construction. It does, however, have multiline strings, simply by allowing \n newline characters within strings. There's nothing in JSON that says you can't have a linebreak in a string. As long as the containing quote characters are correct, it's perfectly valid. e.g.

{"x":"y\nz"}

is 100% legitimate valid JSON, and is a multiline string, whereas

{"x":"y
z"} 

isn't and will fail on parsing.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 1
    "If a particular desired syntax construct isn't in Javascript, then it won't be on JSON." That's cute, but JSON isn't actually a subset of JavaScript, and supports things that JavaScript does not. – remmy Nov 07 '16 at 13:38
1

There's always what I like to call "real JSON". JSON stands for JavaScript Object Notation, and JavaScript does have comments and something close enough to heredocs.

For the heredoc, you would use JavaScript's E4X inline XML:

{
    longString: <>
                Hello, world!
                This is a long string made possible with the magic of E4X.
                Implementing a parser isn't so difficult.
                </>.toString() // And a comment
    /* And another
       comment */
}

You can use Firefox's JavaScript engine (FF is the only browser to support E4X currently) or you can implement your own parser, which really isn't so difficult.

Here's the E4X quickstart guide, too.

Ry-
  • 218,210
  • 55
  • 464
  • 476
0

For configuration you could use an embeddable scripting language, such as lua or python, in fact this is not an uncommon thing to do for configuration. That gives you multiline strings or here documents, and comments. It also makes it easier to have things like the boolean function you describe. However, the scripting languages are, of course, Turing complete.

Thayne
  • 6,619
  • 2
  • 42
  • 67
0

There is also ELDF.

Although it does not support comments, they can be emulated via empty keys:

config_var1 = value1
=some comment
config_var2 = value2
tav
  • 587
  • 6
  • 9
0

One important attribute of JSON (probably the most important) is that you can easily "flip" between the string representation and the representation in object form, and the objects used to represent the object form are relatively simple arrays and maps. This is what makes JSON so useful in a networking context.

The functions you want would conflict with this dual nature of JSON.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151