BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Google Proposes to Enhance JSON with Jsonnet

Google Proposes to Enhance JSON with Jsonnet

Leia em Português

This item in japanese

Bookmarks

Google has open sourced Jsonnet, a configuration language that supersedes JSON and adds new features without breaking backwards compatibility: comments, references, arithmetic and conditional operators, array and object comprehension, imports, functions, local variables, inheritance and others. Jsonnet programs are translated to compliant JSON data formats.

Comments. Jsonnet accepts both C (/* …. */) and C++ (//… ) comment styles.

References. The keyword self can be used to reference the current object, while the operator $ references the root object.

Arithmetic and Conditional Operators. The + operator adds numbers, strings, arrays, and objects. The == or != operators are evaluated to true or false. if works like the ternary operator ?: in C. Following are some Jsonnet operations and the resulting JSON code, taken from the language’s examples:

// bar_menu.3.jsonnet
{
    foo: 3,     
    bar: 2 * self.foo,  // Multiplication.
    baz: "The value " + self.bar + " is "
         + (if self.bar > 5 then "large" else "small") + ".",
    array: [1, 2, 3] + [4],
    obj: {a: 1, b: 2} + {b: 3, c: 4},
    equality: 1 == "1",
}
{
   "foo": 3,
   "bar": 6,
   "baz": "The value 6 is large.",
   "array": [1, 2, 3, 4],
   "obj": {a: 1, b: 3, c: 4},
   "equality": false
}

Building Arrays and Objects. The for construct can be used to build arrays and objects as shown in the next sample:

{
    foo: [1, 2, 3],
    bar: [x * x for x in self.foo if x >= 2],
    baz: { ["field" + x]: x for x in self.foo },
    obj: { ["foo" + "bar"]: 3 },
}
{
   "foo": [ 1, 2, 3 ],
   "bar": [ 4, 9 ],
   "baz": {
      "field1": 1,
      "field2": 2,
      "field3": 3
   },
   "obj": { "foobar": 3 }
}

Modularity. With Jsonnet the code can be split up into multiple files that are then accessed using import. Objects imported are then concatenated with other objects using +.

Functions. Jsonnet values can contain functions which are marked as hidden fields which are not translated into JSON. Functions are used for various evaluations. An example can be seen here.

Jsonnet also features local variables, a way of inheriting objects by importing them and using the concatenation operator +, computed and optional fields.

The Jsonnet language engine is implemented in C++11 and wrapped around with a C API for easier porting to other languages. C and Python libraries are provided. The C++ implementation can be compiled to JavaScript with Emscripten and an unofficial nodejs package is available.

For more details we recommend the language specification and a comparison with other configuration languages.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • Minor point...

    by John Passaniti,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Saying that "Google has open sourced Jsonnet" might be misleading. From the linked web page:

    "Jsonnet was designed and implemented at Google as a 20% project. [...] Jsonnet has been open-sourced under the Apache 2.0 license. Jsonnet is not an official Google product."

  • Why not EDN?

    by J Davenport,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I get that this is a 20% project from Google, but why not look to an existing open standard? It looks to be as feature rich as this project, but already implemented in multiple languages. For more information: github.com/edn-format/edn

  • Re: Minor point...

    by Abel Avram,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    What makes a project an "official" Google project? All work done by Google developers in their 20% time belongs to Google.

    I'm not sure how things work inside Google, but I suppose there is a management decision at some level to open source a project. They have hundreds of 20% projects, but only some are released on GitHub. Jsonnet was published on GitHub on Google's account along with many other projects of theirs.

    I'd say this is a Google project. What we can't say is how committed is Google for this project. They are very committed for some projects -Android, GMail, GDocs, etc. - and less committed about others, abandoning some of them quite easily -Reader, Wave, etc.

  • Unhappy with the stdlib

    by Nikolay Kolev,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I love the project, but they should've used standard JavaScript functions and not reinvent them in the standard library. Basic functions were missing and adding new ones was not easy, so this forced me to stick with my pre-existing JSON preprocessor, unfortunately.

  • Re: Why not EDN?

    by David Cunningham,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hi, Jsonnet lead here! Great question, but EDN is really not much like Jsonnet. EDN is really "just data", it does not have computation or abstraction capabilities. It is extensible, which means you can add such constructs to it, but then you have defined a new language which is not compatible with other systems.

    When we designed Jsonnet, we were acutely aware of the need to follow existing standards. We chose JSON because of its popularity, but we also tried to follow existing programming languages (mainly Javascript and Python) as closely as possible in our extensions to JSON. Jsonnet is also a standard, as it is fully specified with operational semantics.

    Note that it is possible to integrate Jsonnet with systems that consume EDN by generating EDN from Jsonnet. You would do this by writing a custom 'manifest' function (probably in a resuable Jsonnet library). This has already been done for INI files, Lua, and Python configuration files. It allows driving the configuration of many systems (even if they use different configuration syntaxes) from a centralized source.

    Finally, Jsonnet is available in 3 languages (C, Python, Javascript) and any language can bind to the C interface. Native implementations in more languages are planned, perhaps by porting to Haxe.

  • Re: Unhappy with the stdlib

    by David Cunningham,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The standard library is definitely the weakest part of Jsonnet and something we will be improving with new, better organized, better documented functions before v1.0. We welcome feedback on this, especially from people with real-world use-cases.

    It'd be really helpful if you could file a bug on github for specific missing stdlib functionality.

    It is also possible to extend the stdlib yourself or just write your own library in Jsonnet. The following Jsonnet code first uses a little trick to add the function add2 to the stdlib:


    local std2 = std { // Temporarily define std2 to avoid self-reference.
    add2(x):: x + 2,
    };
    local std = std2; // Bind std2 over std.

    // Rest of Jsonnet file below:
    {
    foo: std.add2(10), // Expands to 12.
    }

    In general it may not be possible for us to replicate functions from existing languages, as their semantics may not make sense in Jsonnet (it being declarative). However we understand that being different for no reason does not help anybody either! This is why the stdlib function that implements string formatting exactly matches the Python % operator. More of that sort of thing is definitely on the table.

  • Re: Unhappy with the stdlib

    by Nikolay Kolev,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I agree on the challenges, but I think most people's expectation is to find something closer to JSON than to Python. For example, instead of using the 'local' keyword, using 'let' would have been a more familiar choice. The function names, arguments, etc. should have been closer to the most popular language in the world - JavaScript. Mixing code with configuration data is useful for developers, but not very readable. I like the approach taken by uson (github.com/burningtree/uson), which is not perfect either, of course.

  • Re: Unhappy with the stdlib

    by David Cunningham,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    So the rationale for "local" over "let" is that when you put it inside an object (which most languages do not allow) it takes a role more similar to a private field (Java terminology) than a variable. So the semantics being subtly different to Javascript meant using a different keyword made sense. The keyword 'local' was taken from the configuration language Lua (as was the syntax for computed field names in objects). We curated from a variety of places to create something we think is nice, and didn't just make up a brand new thing. The same applies to 'self' over 'this', since Javascript 'this' does not have desirable semantics. In both cases, the deviation in semantics was to improve the language when used to write configurations, and the deviation in syntax is just to avoid confusion with Javascript (JSON's parent language, if you like).

    In other cases (where we could have gone in any direction and it wouldn't have made much difference for configuration use cases), whether to be similar to one language or another is just politics... We went with Python more often than not because a lot of configuration is for backends, and a lot of backend development is in Python. If you look at langpop.com you see it's hard to determine which is most "popular" anyway.

    As for mixing code with configuration data, Jsonnet is designed to ensure that it *is* readable, among other usability benefits. To demonstrate otherwise, you'd need a concrete counter-example :)

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT