📜 ⬆️ ⬇️

Google suggests strengthening JSON with Jsonnet

Google has opened the source code for its Jsonnet project, a configuration language that replaces standard JSON and adds new features without backward compatibility. Among such opportunities: comments, links, arithmetic and conditional operators, arrays and work with objects, import, functions, local variables. Jsonnet programs are translated into a JSON-compatible data format.

Comments Jsonnet accepts C (/ * ... * /) and C ++ (//) comments

References The self keyword can be used to reference the current object. The $ operator allows you to use the root object.
')
Arithmetic and conditional operators . The + operator can add numbers, strings, arrays, and objects. Operators == and ! = Return true or false. The if operator works like a ternary operator?: In C. Further, a few examples with language operators and the result. Examples are taken from the project page .
  // 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",
 }

Result:
  {
    "foo": 3,
    "bar": 6,
    "baz": "The value 6 is large.",
    "array": [1, 2, 3, 4],
    "obj": {a: 1, b: 3, c: 4},
    "equality": false
 }

Creating arrays and objects . To create arrays and objects, use the construction with the for operator, as shown in the example below:
  {
     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},
 }


Result:
  {
    "foo": [1, 2, 3],
    "bar": [4, 9],
    "baz": {
       "field1": 1,
       "field2": 2,
       "field3": 3
    },
    "obj": {"foobar": 3}
 }

Modularity Code written in Jsonnet can be split into several files and then merged using the import statement. Internal mechanics is simple gluing files.

Functions . Jsonnet values ​​may contain functions. They are marked as hidden fields and are not translated into JSON. An example of such a function is presented below:
  // bar_menu_utils.jsonnet
 {
     equal_parts (size, ingredients) ::
         if std.length (ingredients) == 0 then
             error "No ingredients specified."
         else [
             {kind: i, qty: size / std.length (ingredients)}
             for i in ingredients
         ],
     id :: function (x) x,
 }

Jsonnet also includes local variables, a method for inheriting objects by importing, calculated and optional fields.

The language engine is written in C ++ 11 with the provision of a C-style API wrapper for easier porting to other languages. The development team can immediately provide libraries for C and Python. The implementation for C ++ can be compiled in JS with Emscripten. An unofficial package for nodejs is still available.

Full specifications can be found on the specification page.

Some comparison with other languages.


Json Actually, JSON describes all the data literally. Jsonnet has more free syntax and comments to make it easier for people to read data.

Yaml It is also some JSON extension that allows you to generate the correct JSON. The syntax of the language is very compact and the files in YAML are much shorter than they are later in JSON format. Despite the fact that the language was created for the same purposes as Jsonnet, Jsonnet loses the creation, transmission and refinement of data. In particular, YAML and Jsonnet have different points of view on what should mean "1 + 1". YAML says that this is the string “1 + 1”, whereas Jsonnet believes that the result should be 2.

Other languages ​​with patterns. Jsonnet is a template language that generates data from algorithms with interleaving of literal data with computational structures. Most of these languages ​​consider programs and the result as plain text. This means that the output can get an incorrect result, if we are talking about JSON. Most of these template languages ​​do not have knowledge of the syntax of the output and cannot verify the result for correctness. Jsonnet lacks such a flaw, as it is a highly specialized tool.

Comparison with other tools and languages ​​such as Haskel, Nix, Coil, Pystachio and others can be found in detail in the Jsonnet manual.

Questions and answers


In the original topic appeared interesting questions and answers from the lead developer of the project David Cunningham (David Cunningham).

Q : Why not take advantage of the already existing open standard EDN ? In my opinion, it has all the same features and there are already ports for different languages.

Answer : Good question, but EDN is not very similar to Jsonnet. EDN is “data only”, it knows nothing about calculations or abstractions. It is expandable, and you can add the missing constructs, but then you will receive in fact a new language that will not be understood by other systems.

When we created Jsonnet, we thought that we needed to follow common standards. We chose JSON because of its popularity, but we also tried to follow existing programming models (mainly js and python) as closely as possible.

I also want to note that Jsonnet can be integrated into systems that work with EDN, because it is possible to generate EDN using our system. You only need to write a special function "manifest". This work has been done for INI files, Lua and Python configuration files.

Finally, Jsonnet is available for 3 languages ​​(C, Python, Javascript) and for any language that can work with the C interface. Ports to other languages ​​are scheduled, possibly via porting to Haxe.

Question I really like the project, but the developers had to use standard JavaScript functions, and not reinvent from in stdlib . The basic functions are missing and adding new ones is not an easy task, so this is a kind of limiter and I, unfortunately, returned to the old JSON preprocessor.

The answer is . Stdlib is definitely the weakest part of the project and what needs to be rewritten is improved and documented before we release version 1.0. We are looking forward to your feedback, especially with real-life examples.

In general, it is possible to extend stdlib yourself and write your own library for Jsonnet. The example below first uses a small trick to add the add2 method to 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 to copy functions from supported languages, since the semantics may not make sense in Jsonnet. However, we understand that to have unreasonable differences will not help anyone. And this is the main reason why the stdlib functions responsible for formatting text exactly match the% operator in Python.


Based on materials:


And again we want to draw your attention to the upcoming API & Backend (C #) conference. If you have something to tell about the details of the implementation and management of the API, the service on the backend. If you have interesting cases related to the generation of complex messages: headers and content - we are waiting for your stories !

Source: https://habr.com/ru/post/256363/


All Articles