Looking back to the last decade, I cannot remember a single project I worked in that relied on YAML that didn't have at least one incident from its users or developers dealing with the files and messing up. Just some months ago a team I was working with lost almost a day on a misbehaving software module. After serious detective work it all came down to whitespace in a YAML configuration file.
I remember being pretty excited when I discovered YAML and even pushed its use in some projects trying to avoid the verbosity of XML. These days I will never trade accuracy for conciseness, in particular if its form relies on whitespace and there is not enough redundancy in the specs for consistency checks. Yes, syntax matters.
Yes. It was an indentation issue. It turned that the parent list accepted an item with the same id, so it was a valid statement and the full thing seemed OK. However the data ended up missing from where it was supposed to be.
Thanks for the suggestion. Last time I had to use YAML I used StrictYAML instead which gave me more peace of mind. I knew that there were schema tools around, however I just put more checks in the validator to avoid adding extra dependencies. Next time I will definitely look into those.
How much of this can be solved by using a linter like yamllint, or a a mode that validates the data via a schema or dry-run mode? I'd think it would knock out most of the low hanging fruit.
TOML remains severely underrated, for some reason.
It's easy to read, easy to write, trivial to map onto JSON, and refreshingly clear of footguns. There are comments!
If you get to pick your format for a configuration language, start by trying to talk yourself out of TOML. You'll probably fail; I'm interested to hear if folks out there have examples of something TOML is bad at, because I didn't come up with any when I was doing this evaluation for my own project.
It’s a bit too strict for configuration files and too verbose for an interchange format. It’s an improvement over JSON and arguably yaml but it won’t beat actual syntax.
Another comment brought up StrictYAML, and they have a good dissection of the problems with TOML[1].
Personally, after doing a few pyproject.toml files, I still find it confusing and awkward as soon as you get past simple headers and key-values.
TOML is like YAML, it translates to "jsonic" types, but JSON's virtue is that simple 1:1 mapping between syntax and data.
TOML and YAML both have non-obvious syntax and there's a layer of translation you have to do to understand what you're actually generating.
But I don't really want to generate a big blob of objects, arrays and such, I want to configure something. I think that's why none of these languages work very well.
IMHO the arguments in your link aren't particularly convincing. The three main points seem to be verbosity (defined in terms of total number of characters for a given file, which is not nearly as important to me as readability), not having indentation be significant (which might be downside to a Python programmer but feels like a win to me), and having explicit syntax to distinguish between types (e.g. strings being quoted, which is preferable to me, since it makes them stand out as values compared to the keys). If these are the strongest arguments against TOML, I find myself fairly convinced that TOML is probably the format I'd like to use most even though I was I different towards it before clicking the link.
I would be very interested in an experiment in which participants are required to write Kubernetes manifests in YAML or TOML, and what the analysis suggests they prefer (after controlling for the right set of variables). I don’t like YAML, but TOML stops being nice very quickly as the size or complexity of the data increases IMO.
That's not a bad argument against using TOML, and I'm inclined to agree that TOML is more verbose than it has to be for heavily-nested maps-of-maps-of-maps.
Which you can pretend is a strength, since I consider doing that an anti-pattern. But it is a valid critique.
However, the TOML they offer as a comparison to the StrictYAML is probably auto-generated (they do say "serialized TOML equivalent") and it's quite a bit noisier than it has to be.
TOML deliberately has a couple of ways of writing arrays, and a one-line short format for maps: you're supposed to alternate these, and this technique could eliminate most of the repetition in that particular file.
I still wouldn't choose TOML for a complex tree of user stories where the keys are all long strings of English: that's an example of the kind of thing where you might talk yourself out of using it!
Here's the counterpoint I want to offer: stories of YAML "configuration languages" escaping confinement and becoming headache-inducing repositories of monstrous complexity are practically cliche at this point.
Part of why that is, is that you don't pay for that complexity "up front": It's just a nice list! It's easy to read!
I would add one thing to TOML if I could: it should default to a string for the value part of a key-value pair, if it can't make anything else. So
my_val = 42
Makes a number,
my_string = "42"
Gives you a string, and
my_regex = ^\"(\\.|[^\"])*\"
lets you handle regexes without the obnoxious double-quoting problem, while removing a lot of the verbosity and ceremony from the format.
> TOML deliberately has a couple of ways of writing arrays, and a one-line short format for maps: you're supposed to alternate these, and this technique could eliminate most of the repetition in that particular file.
Could you provide an example of what you mean, or point to some such? We're having a spot of trouble with arrays of maps ourselves.
I like TOML too, but speaking of footguns, there is one where it comes to serialization. If you have something like:
struct Foo {
int bar;
Baz baz;
int quux;
}
... you can't naively serialize this like:
[foo]
bar = 5
[foo.baz]
...
quux = 6
because that makes `quux` a property of `foo.baz`, not of `foo`.
The serializer has to be smart enough to recognize that primitive fields have to be serialized before object fields. As a practical example, Rust's TOML library is not smart enough to do so, though it does at least detect when this would happen and fails with a runtime error. (The workaround is to change your type definition to reorder the fields yourself.)
Yeah, I never liked how in TOML once you start a [table], you can never go back to the top level, just start more [tables].
What it means in practice is that if you want to use [table] syntax because it's more readable for this one key, you have to move it to the very end, away from the keys it was related to.
I love TOML for simple data but it starts to have problems with complex data or data in cettain workflows (I can't imagine a Gitlab or Azure Pipelines file in TOML).
However, a benefit to TOML's weakness with complex data is it encourages developers to keep things simple.
I love toml and used it extensively, but there are definitely warts. Arrays of objects are particularly painful[0]. If you decide that a first-level singleton non-object parameter semantically belongs after a first-level object parameter, you can't do it. Which is kind of no-duh, but TOML is simple enough that you might forget that you can't do that
Dhall is going to be better than writing an inner-language monster of a config language, in YAML, TOML, or JSON. Let someone else do the work, I agree.
But if the goal is to have a human-editable file that loads a few values into a map, and it often is, TOML is pretty nice.
I think we've all been burned by 'configuration languages' which take on the complexity of a full programming language, in a worst-of-both-worlds sort of way. But sometimes you just want to change a font, or specify tabs-or-spaces, or set a non-default remote.
I have never been burned by the configuration language complexity. I'm constantly being burned by its limitation. You are right that for configuration TOML is OK. But the linked article talks about YAML in context of stuff like Ansible or K8s, where usually plain and simple imperative programming is coerced in YAML syntax.
I’d say yaml itself is the smaller part of the problem. The real fun starts when its obvious shortcomings (for use cases it’s being attempted to fulfill) are being papered over with jinja2, code in nondescript languages embedded in string values and css-like composition rules for multiple files.
An interesting candidate in the other end of the spectrum is Dhall, https://dhall-lang.org. If I was working in one of the languages with current implementations I would no doubt try it out.
Edit: I will also add that dhall will export to YAML/JSON etc, however I'm not a fan on intermediary config file processing.
We were editing a 2000 node Ant Config file by hand when the drugs began to take hold. I remember saying something like "I feel a bit lightheaded; maybe all configuration should be done in YAML from now on..."
I wonder why IDE-enforced markup-schemas haven't caught on. Like a static type system for your markup (i.e. Kubernetes could declare your "types" and your editor could ensure the config fits them).
VSCode has something along these lines for JSON - at least on its own settings configuration - but somehow the approach hasn't become prevalent. Are we lacking a standard? Motivation?
There's a Kubernetes plugin/package for Dhall [0] that can do this [1], it's very neat. I've played with it briefly, and whilst a tiny bit verbose (mostly as a function of the K8s specs themselves I suspect), the ability to have it validate everything before you even touched K8s was worth it imo.
I had this exact problem a while ago when trying to have static types for blog entries. I ended up using a strategy where I would write the config in the language that I would eventually use it in (for my blog, my entries became typescript files).
I think perhaps protobufs (specifically text format protos) are a potentially really nice solution, since you get to leverage the protobuf type system. Unfortunately the support for them is a bit lacking.... (afaik, no formal spec - there’s a canonical implementation in C++; no editor support for things like linting and completions).
> there was something off-putting about YAML. It was a markup language claiming not to be a markup language.
The acronym literally stands for "Yet Another Markup Language".
Edit: To comment something less pedantic, the article doesn't really go into anything specific it doesn't like about it. It's sort of like when my brother comments about how awful the vim home web page looks. It's still a good web page. I don't know why people are commenting about aesthetics in YAML if they can't pinpoint a particular functionality problem.
That said, I'm not blind to the many warts and weird edge cases and dozens of different ways you can specify a string in YAML. I hope something more elegant comes along that's still not as draconian as JSON (simple, elegant, hard to write strings, no comments).
However I must admit some surprise at learning that even before 2010 they changed to the recursive acronym. I was still calling it yet another markup language even back then. I thought anything back then was yet another if it started with ya, like YaST from SuSE (yet another setup tool).
Wow I always thought it was "Yet Another Markup Language". It's crazy that they would change to be literally opposite of the original name.
From the wikipedia article:
> but it was then repurposed as YAML Ain't Markup Language, a recursive acronym, to distinguish its purpose as data-oriented, rather than document markup.
I mean couldn't it be both data-oriented and a markup language?
In a world where there's only a few primitive types no one can share uuids or dates across the wire without both sides knowing which fields are dates or uuids ahead of time
JSON is too simple we need more primitive types and an extensible data notation to formalise data sharing of unknown types
That's one way to go, but there are other options. You want inline annotation of types. On the other side you can have an external jsonschema which provides the same information.
Realistically, you can't do "data sharing of unknown types" - at that point you're just sharing binary blobs.
I don't know much corba, but in asn.1 it's basically "a field tag and a binary blob". It could be also a standard structure tagged with an unknown id, but either way I don't really see it as much more than json `{"uid": "blob-data"}` in practice. If it's unknown data, you can do almost nothing with it apart from passing it on. If I recall correctly, x509 doesn't even want to deal with any complicated tagging and embeds each extension value as a serialised DER itself.
The thing I don't like about YAML is the strict meaningful indentation. It's fine once you install an extension that won't let you do anything other than two spaces, but it's pretty horrific if you try to edit a yaml file in a virgin text editor when you aren't super familiar with the format, especially if you try to copy paste things.
I think I would genuinely be pretty happy with a well-supported extension of the JSON spec that allows comments. Even if it required an explicit start and end of the comment (/* ... */). I also can't say I want or need anchors/references from YAML, so I think that helps me be quite OK with using JSON.
I appreciate the challenges of writing JSON, but also think it can be easier to spot issues if you have an editor that's doing magic indentation based on the JSON. Give me comments to help the humans, and I'm sold.
If you are using JavaScript you can use jsonc [0] it's exactly that just JSON with comments. VSCode and typescript config files already use it by default
Am I the only one who finds YAML much harder to write than JSON or XML?
It's not just the fact that I get the syntax for lists and maps confused all the damn time. The worst part is that I'm unable to use the keyboard shortcut for automatically formatting my document!
I love that keyboard shortcut! I hate being without it! I'm certain it represents more than half of my key presses in other languages!
I type a few characters and then I press the code formatting shortcut. That's what I do! That's my workflow!
I don't understand how people who work in whitespace-significant languages can stand being without it! ;-)
(I'm only half-joking - I do find it very frustrating)
Significant whitespace seems like a good idea and looks great in small examples but it has some very serious downsides in real use. Being able to reliably reformat hundreds of lines of code with a single keypress is far more valuable than a few saved braces.
The difference between Python and YAML is that Python doesn't have a semantically-equivalent, non-indentation-sensitive presentation style. How you choose to view and work with YAML is a choice that doesn't need to have any impact on what you share with others and how they choose to view and work with it.
While I'm not usually fond of “you're holding it wrong” arguments, that's pretty much the proper response to complaints about YAML’s indentation sensitivity, since you can work with YAML in a style which isn't indentation sensitive without anyone you share data with seeing anything different.
Python’s grammar is well defined and has far more validation. YAML has multiple ways to define the same output and since it makes almost anything legal there’s not a way for a tool to disambiguate.
For example, if you double-indent something, YAML will just silently assume you wanted a nested data structure but Python will throw an indentation error. That causes issues in many editors when copy-and-pasting.
That pattern continues where Python uses indentation to force clarity and consistency but still has syntax which removes ambiguity. A key one is that Python requires quoting data, avoiding all of the common data loss in YAML when people happen to enter data with meaning in YAML (country=no, names with equal signs or colons, etc.), and you have to open and close structures with syntax rather than just indentation.
The most analogous Python bug is when a statement immediately after an if, nested def, etc. is one level of indentation than intended. That definitely happens but a fair fraction of the time it’s immediately obvious because it usually fails due to something like a variable not being in scope. YAML consumers are more likely to ignore extra elements so it’s easier to miss things like that for a while unless you have an unusually strict validation stage.
> Significant whitespace seems like a good idea and looks great in small examples but it has some very serious downsides in real use.
In some contexts, sure, which is one reason why YAML has two presentational styles with equal semantic power, between which a suitable tool can convert mechanically, and only one of those two styles features whitespace sensitivity.
> Being able to reliably reformat hundreds of lines of code with a single keypress is far more valuable than a few saved braces.
YAML gives you the ability to freely switch between a presentational style which provides the former and one which provides the latter, with no loss of semantic power, so it doesn't really matter which is better, since you don't have to choose between one and the other.
Yes, in whitespace significant languages whitespace is significant. I could complain that my editor doesn't figure out how to fix all of my braces if I hit a button, after all I got the indentation right and can visually see the structure of my code should be correct no sweat.
The issue is that in practice it’s quite difficult to reliably get whitespace correct all of the time, whereas braces seem quite easy to get right. If you’ve ever tried cutting and pasting a code block in python you know the pain of having to manually fix whitespace. The same operation in a brace-delimited language has a much smaller chance of going wrong, as the only thing you need to get right is the endpoints of the cut selection.
{ "key1": values, “key2”: value2 } is valid YAML with the same sematics as it has in JSON; if you have a YAML-aware editor (or editor mode) it will probably format that just as easily as in JSON.
JSON is a subset of YAML, so if you want to write YAML like JSON you can, and you can even automatically convert from JSON style to more idiomatic YAML, or vice-versa, with appropriate tooling.
What Drew is saying is absolutely correct though. YAML was specifically designed to be a superset of JSON. Conversely, when JSON was designed, YAML did not exist, so it only became a subset of YAML when the latter was introduced.
That works if all your YAML authors are carefully avoiding any use of the features JSON can’t represent, like multiple documents, non-string map keys, and application-defined type tags.
> That works if all your YAML authors are carefully avoiding any use of the features JSON can’t represent, like multiple documents, non-string map keys, and application-defined type tags.
That's true if you want round-trip conversion to and from JSON, but you don't need that for automated round-trip conversion between JSON-style (delimited, or, in the language of the YAML spec “flow style”) YAML and the somewhat more idiomatic for most uses indented, (or, in the spec language, “block style") YAML, e.g., if you find it easier to edit in flow-style but you are in an environment that wants the end product delivered in block style.
Notably, whitespace sensitivity is a feature of block style, but not flow style.
despite how popular this claim is, it is not true.
The following is a valid JSON document according to the spec[1]:
{ "key": "value", "key": "otherValue" }
But is not a valid YAML document[2], something addressed in the spec itself. The JSON spec says
> The names within an object SHOULD be unique.
And `SHOULD` is defined by RFC 2119[3] as
> This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.
Also note that popular JSON validators exist which will accept the above example as completely valid[4]. Also note that Javascript's JSON.parse[5] will accept the above as valid, as does JavaScript itself for object keys (which, yes, is not JSON).
Yes, I know about RFC 8259 vs ECMA 404. The real world examples noted above, though, speak for themselves.
JSON is not 100% a subset of YAML, this is true; that's slightly a simplification of the truth that is commonly echoed. It is a syntactically a subset of YAML, and for anything representable in JSON you can still do a functionally-lossless translation* from JSON to YAML and back again. This is because:
> In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.
So,
{ "key": "value", "key": "otherValue" }
becomes
{ "key": "otherValue" }
in a round trip, but represents the same thing, going by ECMA262 rules.
These are definitely distinct snippets of JSON and if you only use RFC4627 then it doesn't define anything about how to parse the JSON beyond the syntax, whereas the YAML spec is a bit more complete in regards to specifying semantics probably partly since it's a more complicated language. Thankfully in the common case most JSON parsers do as specified in ECMA262 (which makes sense since that's where this format came from anyways) and use the latest key. You can see this in Go's "encoding/json" for example. So this property is still meaningfully true, I'd argue, even if it is more nuanced than commonly believed.
tl;dr: It is true that not all valid JSON is valid YAML. However, automatic translation between the JSON and YAML is still possible if you are going by ECMA262 JSON semantics.
P.S.: In practice, YAML parsers do actually often take the liberty of interpreting YAML to be a proper superset. This isn't too surprising since most YAML parsers take a lot of liberties that are/were outright spec violations, but just as an example, here's PyYAML:
>>> from yaml import load
>>> load('{"a":"1","a":2}')
{'a': 2}
When I read this, I didn't believe it. I needed to prove this to myself!
I've seen and used YAML files for configurations in many places and I've always found editing YAML files by hand too much of a pain. It's very easy to miss a space and screw everything up. However, writing JSON directly into a plain text file is totally easy.
So, I created a normal text file named 'array_of_objects.json' like this -
[
{
"first": "one"
},
{
"second": "two"
}
]
And then I wrote a ruby program to read it -
require 'json'
require 'yaml'
array_of_objects = YAML.load_file 'array_of_objects.json'
p array_of_objects
And I see the output as -
[{"first"=>"one"}, {"second"=>"two"}]
I still can't get over it. I'm thinking of the countless hours wasted!!
I hate this sort of article. Lots of griping about the problems with YAML, but no solutions. What does the author think is better? XML doesn't map to the same data structures as YAML, JSON, and TOML, so it's not really a comparable beast.
The author mentions a desire to be able to teach a data format to people in the way someone can comprehend HTML or Markdown easily. But the formats have different goals.
The goal of HTML and Markdown are to provide a way to encode document formatting in a simple text syntax. There's not one single correct way to format a document intended for presentation to and consumption by humans. Pretty much anything goes, HTML and Markdown just provide some decoration.
But the purpose of YAML (and JSON and TOML) is to provide a way to represent strictly defined data structures for consumption by a computer. The reason YAML is frustrating is because you can't fudge the result; you can't be sloppy or inexact; YAML operates at the boundary between the human and the computer program, and just like any HCI, it's going to be frustrating and error-prone.
Now, would it be possible to come up with a better format than YAML or JSON or TOML that does the same thing? Maybe. But the facts that tools exist to search and manipulate these formats and that we'll probably still be using them in 2030 isn't evidence that they are bad. The fact that yq can exist and is useful is a point in favor of YAML, imo. If simple tools can be written to do useful things with a data format, that makes the format more useful.
After working with YAML and JSON (and XML and INI and CSV and so on), it seems like a) JSON is equivalent and simpler for basic structures, b) JSON + jq or a language library is better than YAML's complex syntax (like not being able to merge lists[1]), and c) YAML has too many ways to express the same thing. Writing YAML is basically trial and error.
I used to like Python, but the whitespace stuff irritates me more and more. Sure, it's easy to read, but having those braces also makes code easier to read.
Maybe not opening braces, they're sorta redundant, but closing braces allow me to "pop stack" when I read them.
Yaml combines the worst of whitespace with the use of whitespace without keywords, which makes things even harder.
JSON is ok, particularly if your editor auto-quotes things, I wish it had comments, but having something that strips comments is a single sed pre-processing line.
Neither are great for human generation or consumption, but at least JSON is only trying to be a serialize/deserialize syntax and doesn't claim to be more.
YAML truly lives up to the "YA" part. It's trying to be the COBOL of configuration, able to be read and written by anyone. But no one needs that.
Today I edited a Docker Compose YAML configuration file. The network configuration has "ports" sections, such as
ports:
- "8080:80"
Which (assuming some other network configurations) means that whatever answers to port 80 in the container can be reached at port 8080 of the host running Docker.
Simple syntax and straightforward semantics, but port numbers are integers: why strings? Because, as the Docker manual warns, YAML is clever.
> When mapping ports in the HOST:CONTAINER format, you may experience erroneous results when using a container port lower than 60, because YAML parses numbers in the format xx:yy as a base-60 value. For this reason, we recommend always explicitly specifying your port mappings as strings.
Like perl is a "write-only" language, YAML is a "read-only" format. Humans should not be manually editing YAML, there are way too many caveats.
(my favorite being the country code for Norway "NO" being a boolean-false, if not quoted)
We should all just write our config in JavaScript or TypeScript because then we can standardize around a common interface language.
It’s simple, widely known, has comments, not dependent on white space, JSON has the right types we need program (and can be validated, with JSON Schema).
Critically, to generate configs, we can write loops, conditions, ternaries, functional programs with Ramda, classes/OOP, and even fancy GUIs. Simple English JavaScript is powerful and readable.
.js is the move here... especially once node supports immutable data structures
This is why stuff like AWS CDK and Pulumi are legit. Configure your stuff with actual code.
All we gotta do is fill the gap between JS and Python in terms of scientific computing, and we’re set. Typescript->WASM could be interesting.
I’m sure there are some details that make this difficult but, what do you guys think about standardizing around JS/TS?
106 comments
[ 3.1 ms ] story [ 191 ms ] threadI remember being pretty excited when I discovered YAML and even pushed its use in some projects trying to avoid the verbosity of XML. These days I will never trade accuracy for conciseness, in particular if its form relies on whitespace and there is not enough redundancy in the specs for consistency checks. Yes, syntax matters.
So git merge will say "no merge conflicts", but actually there were whitespace changes.
You can still omit quotes around strings, use comments and add trailing commas after the last element of collections.
A configuration file written in that style is actually pretty nice. I’ve never understood why people don’t use this.
But you can write Python (or pretty much any other tool) and have it emitted as JSON.
[0] - https://json5.org/
It's not a panacea, but it can help avoid those long debugging sessions.
[0]: https://json-schema-everywhere.github.io/yaml
[1]: https://marketplace.visualstudio.com/items?itemName=redhat.v...
Also most editors have indentation guides, which help a lot with indentation issues.
You may not agree with all their conclusions, you may have another use case, but you ought to make sure you're addressing all those points.
It's easy to read, easy to write, trivial to map onto JSON, and refreshingly clear of footguns. There are comments!
If you get to pick your format for a configuration language, start by trying to talk yourself out of TOML. You'll probably fail; I'm interested to hear if folks out there have examples of something TOML is bad at, because I didn't come up with any when I was doing this evaluation for my own project.
Personally, after doing a few pyproject.toml files, I still find it confusing and awkward as soon as you get past simple headers and key-values.
TOML is like YAML, it translates to "jsonic" types, but JSON's virtue is that simple 1:1 mapping between syntax and data.
TOML and YAML both have non-obvious syntax and there's a layer of translation you have to do to understand what you're actually generating.
But I don't really want to generate a big blob of objects, arrays and such, I want to configure something. I think that's why none of these languages work very well.
[1]: https://hitchdev.com/strictyaml/why-not/toml/
specifically TOML supports a syntax that allows to write documents like: (not actual syntax)
that would translate to {a:{b:1,c:2,e:4},d:3}.So the criticism is that (in various cases) you need to read the entire document to be sure to have fully parsed one subtree of the document.
Which you can pretend is a strength, since I consider doing that an anti-pattern. But it is a valid critique.
However, the TOML they offer as a comparison to the StrictYAML is probably auto-generated (they do say "serialized TOML equivalent") and it's quite a bit noisier than it has to be.
TOML deliberately has a couple of ways of writing arrays, and a one-line short format for maps: you're supposed to alternate these, and this technique could eliminate most of the repetition in that particular file.
I still wouldn't choose TOML for a complex tree of user stories where the keys are all long strings of English: that's an example of the kind of thing where you might talk yourself out of using it!
Here's the counterpoint I want to offer: stories of YAML "configuration languages" escaping confinement and becoming headache-inducing repositories of monstrous complexity are practically cliche at this point.
Part of why that is, is that you don't pay for that complexity "up front": It's just a nice list! It's easy to read!
I would add one thing to TOML if I could: it should default to a string for the value part of a key-value pair, if it can't make anything else. So
Makes a number, Gives you a string, and lets you handle regexes without the obnoxious double-quoting problem, while removing a lot of the verbosity and ceremony from the format.Could you provide an example of what you mean, or point to some such? We're having a spot of trouble with arrays of maps ourselves.
This breaks down when things get really branchy. TOML really expects keys to be symbols rather than strings.
The serializer has to be smart enough to recognize that primitive fields have to be serialized before object fields. As a practical example, Rust's TOML library is not smart enough to do so, though it does at least detect when this would happen and fails with a runtime error. (The workaround is to change your type definition to reorder the fields yourself.)
Ref: https://play.rust-lang.org/?version=stable&mode=debug&editio...
What it means in practice is that if you want to use [table] syntax because it's more readable for this one key, you have to move it to the very end, away from the keys it was related to.
Wasn't impressed.
However, a benefit to TOML's weakness with complex data is it encourages developers to keep things simple.
[0] i mean this:
Edit: ok, just read the sibling comments and they totally echo my gripes. So there's something about our common issues.Dhall is going to be better than writing an inner-language monster of a config language, in YAML, TOML, or JSON. Let someone else do the work, I agree.
But if the goal is to have a human-editable file that loads a few values into a map, and it often is, TOML is pretty nice.
I think we've all been burned by 'configuration languages' which take on the complexity of a full programming language, in a worst-of-both-worlds sort of way. But sometimes you just want to change a font, or specify tabs-or-spaces, or set a non-default remote.
Edit: I will also add that dhall will export to YAML/JSON etc, however I'm not a fan on intermediary config file processing.
VSCode has something along these lines for JSON - at least on its own settings configuration - but somehow the approach hasn't become prevalent. Are we lacking a standard? Motivation?
[0] https://dhall-lang.org/ [1] https://github.com/dhall-lang/dhall-kubernetes
K8s will accept a cpu value of 0.1, but the plugin marks it as an error, it wants the millicpu version 100m instead.
I think perhaps protobufs (specifically text format protos) are a potentially really nice solution, since you get to leverage the protobuf type system. Unfortunately the support for them is a bit lacking.... (afaik, no formal spec - there’s a canonical implementation in C++; no editor support for things like linting and completions).
The acronym literally stands for "Yet Another Markup Language".
Edit: To comment something less pedantic, the article doesn't really go into anything specific it doesn't like about it. It's sort of like when my brother comments about how awful the vim home web page looks. It's still a good web page. I don't know why people are commenting about aesthetics in YAML if they can't pinpoint a particular functionality problem.
That said, I'm not blind to the many warts and weird edge cases and dozens of different ways you can specify a string in YAML. I hope something more elegant comes along that's still not as draconian as JSON (simple, elegant, hard to write strings, no comments).
Source https://en.wikipedia.org/wiki/YAML. Also https://yaml.org/spec/1.2/spec.html.
However I must admit some surprise at learning that even before 2010 they changed to the recursive acronym. I was still calling it yet another markup language even back then. I thought anything back then was yet another if it started with ya, like YaST from SuSE (yet another setup tool).
From the wikipedia article:
> but it was then repurposed as YAML Ain't Markup Language, a recursive acronym, to distinguish its purpose as data-oriented, rather than document markup.
I mean couldn't it be both data-oriented and a markup language?
JSON is too simple we need more primitive types and an extensible data notation to formalise data sharing of unknown types
Realistically, you can't do "data sharing of unknown types" - at that point you're just sharing binary blobs.
ASN.1 and CORBA both let you share types that are unknown ahead of receiving.
I appreciate the challenges of writing JSON, but also think it can be easier to spot issues if you have an editor that's doing magic indentation based on the JSON. Give me comments to help the humans, and I'm sold.
https://github.com/microsoft/node-jsonc-parser
It has comments and accepts trailing commas.
I would like to mumble something about s-expressions and how this has been solved long ago but I lack the stamina after doing it so many times.
Let me go back to my job and my task of modifying a Helm chart which decided that string manipulation of yaml files is truly the way to go.
It's not just the fact that I get the syntax for lists and maps confused all the damn time. The worst part is that I'm unable to use the keyboard shortcut for automatically formatting my document!
I love that keyboard shortcut! I hate being without it! I'm certain it represents more than half of my key presses in other languages!
I type a few characters and then I press the code formatting shortcut. That's what I do! That's my workflow!
I don't understand how people who work in whitespace-significant languages can stand being without it! ;-)
(I'm only half-joking - I do find it very frustrating)
If it doesn't then I'm using the wrong editor.
In grammars that aren’t white space dependent (such as JSON), it’s clear what this means:
While I'm not usually fond of “you're holding it wrong” arguments, that's pretty much the proper response to complaints about YAML’s indentation sensitivity, since you can work with YAML in a style which isn't indentation sensitive without anyone you share data with seeing anything different.
For example, if you double-indent something, YAML will just silently assume you wanted a nested data structure but Python will throw an indentation error. That causes issues in many editors when copy-and-pasting.
That pattern continues where Python uses indentation to force clarity and consistency but still has syntax which removes ambiguity. A key one is that Python requires quoting data, avoiding all of the common data loss in YAML when people happen to enter data with meaning in YAML (country=no, names with equal signs or colons, etc.), and you have to open and close structures with syntax rather than just indentation.
The most analogous Python bug is when a statement immediately after an if, nested def, etc. is one level of indentation than intended. That definitely happens but a fair fraction of the time it’s immediately obvious because it usually fails due to something like a variable not being in scope. YAML consumers are more likely to ignore extra elements so it’s easier to miss things like that for a while unless you have an unusually strict validation stage.
In some contexts, sure, which is one reason why YAML has two presentational styles with equal semantic power, between which a suitable tool can convert mechanically, and only one of those two styles features whitespace sensitivity.
> Being able to reliably reformat hundreds of lines of code with a single keypress is far more valuable than a few saved braces.
YAML gives you the ability to freely switch between a presentational style which provides the former and one which provides the latter, with no loss of semantic power, so it doesn't really matter which is better, since you don't have to choose between one and the other.
Haskell does.
https://en.m.wikibooks.org/wiki/Haskell/Indentation
You just type [enter] instead of [space] between "value1" and "key2:" in your original example to get correct indentation.
That's true if you want round-trip conversion to and from JSON, but you don't need that for automated round-trip conversion between JSON-style (delimited, or, in the language of the YAML spec “flow style”) YAML and the somewhat more idiomatic for most uses indented, (or, in the spec language, “block style") YAML, e.g., if you find it easier to edit in flow-style but you are in an environment that wants the end product delivered in block style.
Notably, whitespace sensitivity is a feature of block style, but not flow style.
The following is a valid JSON document according to the spec[1]:
But is not a valid YAML document[2], something addressed in the spec itself. The JSON spec says> The names within an object SHOULD be unique.
And `SHOULD` is defined by RFC 2119[3] as
> This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.
Also note that popular JSON validators exist which will accept the above example as completely valid[4]. Also note that Javascript's JSON.parse[5] will accept the above as valid, as does JavaScript itself for object keys (which, yes, is not JSON).
Yes, I know about RFC 8259 vs ECMA 404. The real world examples noted above, though, speak for themselves.
[1] https://tools.ietf.org/html/rfc4627
[2] https://yaml.org/spec/1.2/spec.html
[3] https://tools.ietf.org/html/rfc2119
[4] https://www.freeformatter.com/json-validator.html
[5] https://www.ecma-international.org/ecma-262/#sec-internalize...
JSON is not 100% a subset of YAML, this is true; that's slightly a simplification of the truth that is commonly echoed. It is a syntactically a subset of YAML, and for anything representable in JSON you can still do a functionally-lossless translation* from JSON to YAML and back again. This is because:
> In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.
So,
becomes in a round trip, but represents the same thing, going by ECMA262 rules.These are definitely distinct snippets of JSON and if you only use RFC4627 then it doesn't define anything about how to parse the JSON beyond the syntax, whereas the YAML spec is a bit more complete in regards to specifying semantics probably partly since it's a more complicated language. Thankfully in the common case most JSON parsers do as specified in ECMA262 (which makes sense since that's where this format came from anyways) and use the latest key. You can see this in Go's "encoding/json" for example. So this property is still meaningfully true, I'd argue, even if it is more nuanced than commonly believed.
tl;dr: It is true that not all valid JSON is valid YAML. However, automatic translation between the JSON and YAML is still possible if you are going by ECMA262 JSON semantics.
P.S.: In practice, YAML parsers do actually often take the liberty of interpreting YAML to be a proper superset. This isn't too surprising since most YAML parsers take a lot of liberties that are/were outright spec violations, but just as an example, here's PyYAML:
I've seen and used YAML files for configurations in many places and I've always found editing YAML files by hand too much of a pain. It's very easy to miss a space and screw everything up. However, writing JSON directly into a plain text file is totally easy.
So, I created a normal text file named 'array_of_objects.json' like this -
And then I wrote a ruby program to read it - And I see the output as - I still can't get over it. I'm thinking of the countless hours wasted!!Thank you so much.
So far I have been mostly YAML safe and will try to keep it that way, but it is getting hard when having to deal with k8s.
I'm still regularly surprised by Markdown. I have to rely on previews and occasionally still need to check the docs.
My bulleted lists often break and I can never remember the syntax for links.
It's ok to like WYSIWYG even if you're a hacker.
The author mentions a desire to be able to teach a data format to people in the way someone can comprehend HTML or Markdown easily. But the formats have different goals.
The goal of HTML and Markdown are to provide a way to encode document formatting in a simple text syntax. There's not one single correct way to format a document intended for presentation to and consumption by humans. Pretty much anything goes, HTML and Markdown just provide some decoration.
But the purpose of YAML (and JSON and TOML) is to provide a way to represent strictly defined data structures for consumption by a computer. The reason YAML is frustrating is because you can't fudge the result; you can't be sloppy or inexact; YAML operates at the boundary between the human and the computer program, and just like any HCI, it's going to be frustrating and error-prone.
Now, would it be possible to come up with a better format than YAML or JSON or TOML that does the same thing? Maybe. But the facts that tools exist to search and manipulate these formats and that we'll probably still be using them in 2030 isn't evidence that they are bad. The fact that yq can exist and is useful is a point in favor of YAML, imo. If simple tools can be written to do useful things with a data format, that makes the format more useful.
If you treat XML attributes as @-prefixed variables in the set of json nodes and visa-versa, they're fully compatible.
[1] https://stackoverflow.com/q/24090177/96588
Maybe not opening braces, they're sorta redundant, but closing braces allow me to "pop stack" when I read them.
Yaml combines the worst of whitespace with the use of whitespace without keywords, which makes things even harder.
JSON is ok, particularly if your editor auto-quotes things, I wish it had comments, but having something that strips comments is a single sed pre-processing line.
Neither are great for human generation or consumption, but at least JSON is only trying to be a serialize/deserialize syntax and doesn't claim to be more.
YAML truly lives up to the "YA" part. It's trying to be the COBOL of configuration, able to be read and written by anyone. But no one needs that.
Simple syntax and straightforward semantics, but port numbers are integers: why strings? Because, as the Docker manual warns, YAML is clever.
> When mapping ports in the HOST:CONTAINER format, you may experience erroneous results when using a container port lower than 60, because YAML parses numbers in the format xx:yy as a base-60 value. For this reason, we recommend always explicitly specifying your port mappings as strings.
It’s simple, widely known, has comments, not dependent on white space, JSON has the right types we need program (and can be validated, with JSON Schema).
Critically, to generate configs, we can write loops, conditions, ternaries, functional programs with Ramda, classes/OOP, and even fancy GUIs. Simple English JavaScript is powerful and readable.
.js is the move here... especially once node supports immutable data structures
This is why stuff like AWS CDK and Pulumi are legit. Configure your stuff with actual code.
All we gotta do is fill the gap between JS and Python in terms of scientific computing, and we’re set. Typescript->WASM could be interesting.
I’m sure there are some details that make this difficult but, what do you guys think about standardizing around JS/TS?