Hacker News new | ask | show | jobs
by nishs 1229 days ago
TOML is a bad file format for human configuration.

For example, in the following file

  [hosts]
  "example.org" = "localhost:8000"
  "foo.com" = "localhost:9000"
  "sub.example.com" = "localhost:9002"

  certfile = "path/to/cert.pem"
  keyfile = "path/to/key.pem"
Ordinary human readers would generally think that the hosts table has 3 entries. But TOML considers certfile and keyfile to also be entries in the hosts table.

TOML has no way to end a [table] on its own; tables continue until EOF or until the next [table].

3 comments

It's weird that the only way to get the following structure:

  {
    "hosts": {
      "example.org": "localhost:8000",
      "foo.com": "localhost:9000",
      "sub.example.com": "localhost:9002"
    },
    "certfile": "path/to/cert.pem",
    "keyfile":"path/to/key.pem"
  }
is to write the following toml:

  certfile = "path/to/cert.pem"
  keyfile = "path/to/key.pem"

  [hosts]
  "example.org" = "localhost:8000"
  "foo.com" = "localhost:9000"
  "sub.example.com" = "localhost:9002"
and other toml orderings, like in the parent comment, fail.
this is a tradeoff so that ini/toml can avoid braces and whitespace rules, which is actually a win for (non-programmer) human usability. to most users, fixing an "unbalanced braces" error is "programming", especially since that's exactly the kind of error that parsers can't give useful advice for in the error message.

the tradeoff is that your most general top-level settings must come before your category-specific settings, which is usually a pretty natural layout anyway.

Why would you want to require a specific order in the resulting object representation? If you need ordering, use arrays. And if you need to do stuff like content signatures, it makes sense to use some form of normalizer anyway (e.g. alphabetic key order).
There isn't a need for specific ordering of keys in the object representation. But I want to be able to write parts of the toml document in different orders (e.g. "hosts" table before "certfile"; or "hosts" table after "certfile") and still have the same effective object.
This is an advantage with sqlite as a config store as well - initial db config file augmented in-memory with secrets, accessible from all major languages, without relying on the vagarities of the filesystem (windows vs Linux tmp mount points) and easy to have multiple switchable configurations depending on environment, test mode (integration tests after deployment etc.) or customer.
Good point, but on the other side a clear visual enforcement between global and section specific stuff makes sense as well.

Apache configs are my personal favourite hate subject here.

The "global" and "section specific" stuff stops being so clear once you need to have subsections. And the "clear visual enforcement" can also lead to forced unreadability, when the ordering forced on you doesn't match the most sensible/readable order for a human reader.

This is repeating the same mistake I see all the lightweight markup formats (Markdown, Org Mode, etc.) do - using implicit terminators for hierarchy nodes. It's a superbly annoying feature of outliner tools (including the one I otherwise love: org mode) that forces you to create extra levels of structure just for the sake of being able to surround subtrees with context.

I'm an ordinary human and I disagree. I would not expect a blank line to end the [hosts] table. I find it nice that you can visually separate different categories of entries under a table. I also find it nice that global entries must be at the top of the file – more organized and fewer opportunities for such global entries to get lost.
I’ve always liked yaml but I feel the world is moving towards toml. Keen to see more of toml issues to build a fair comparison
It doesn’t help that YAML has footguns. I love it as an editable format, especially compared to JSON, but for library writers, supporting the whole spec (safely) tends to not be possible; Some even go as far as having a “safe load” function that purposefully violates the spec to remove footguns.
If you use "NO" it gets parsed as norway
The whole "`NO` is Norway" thing is indeed one of the footguns people love to bring up. However, as someone who is writing the YAML manually, and has a syntax highlighter, these issues don't manifest.
I dunno, this is where I said fuck it and never used it again.

I don't know what kind of mind will that as an OK reserved word for a programming language. but OK..

I guess I'm lucky I didn't need to use yaml for my work.

I thought it was the other way around? i.e. "NO", in a document that intends "NO" to mean "Norway", is parsed as "False".
I really like the Gura format (https://github.com/gura-conf/gura). Seems to combine the best of yaml, json, and toml for the use case of human created configuration files.
I've also seen the Dhall configuration language (https://dhall-lang.org/) mentioned.