toml-lang / toml

Tom's Obvious, Minimal Language
https://toml.io
MIT License
19.45k stars 847 forks source link

[Feature Request] add `root` keyword for referring to the top-level object #984

Closed alexmozaidze closed 1 year ago

alexmozaidze commented 1 year ago

Allowing to refer to the top-level object as root would allow users to define a top-level array. In other words, it would be possible to turn this JSON:

[
  { "name": "monky", "looks": "🐒" },
  { "name": "owl", "looks": "🦉" },
  { "name": "parrot", "looks": "🦜" }
]

Into the following TOML:

[[root]]
name = "monky"
looks = "🐒"

[[root]]
name = "owl"
looks = "🦉"

[[root]]
name = "parrot"
looks = "🦜"

Without changing anything on the backend.

It would also allow to define top-level parameters explicitly:

[root]
key = "value"
foo = "bar"

Though, I would discourage doing so.

Possible problems

What if someone decides it is a great idea to use both top-level parameters and [[root]]?

key = "value"

[[root]]
foo = "bar"

Simple, just error out. It doesn't make sense to have a value with 2 types at the same time.


What about having both top-level parameters and root object?

key = "value"

[root]
foo = "bar"

Error out. Having parameters outside of any object implies root. So, basically, the above boils down to

[root]
key = "value"

[root]
foo = "bar"

And redefining an object is not allowed.


root inside root

[root]
root = "haha, I made a paradox!"

Error out. root is reserved on top-level.


Using root for creating new tables on the top-level.

key = "value"

[root.numbers]
one = 1
two = 2

Allowed, but discouraged.


Using inline array syntax

root = [
  { name = "monky", looks = "🐒" },
  { name = "owl", looks = "🦉" },
  { name = "parrot", looks = "🦜" },
]

Error out, since root is reserved on top-level.

Perhaps, we could add the following syntax as an alternative?

[
  { name = "monky", looks = "🐒" },
  { name = "owl", looks = "🦉" },
  { name = "parrot", looks = "🦜" },
]

How is this useful for configs?

Not much; configs don't need top-level arrays that often. This is mainly useful for when one uses TOML as a data file.

Summary

Introducing root as a special object poses some potential problems with readability if the user decides to mix root with normal syntax, but it allows to create an array as the top-level structure (which is the only real benefit), making it possible to fully replace JSON with TOML.

arp242 commented 1 year ago

This isn't backwards-compatible: people may already have [root] or root = ... in their documents. This alone makes it a bit of a non-starter.

I also don't really like the proposal: it's not very obvious that "root" is something special, and as you mentioned it's not very useful for configuration files. If we really want to address this use case ("allow using an array at the top level") then there are probably better ways to do that, such as having [ as the first non-blank character:

[
    1,
    "val",
    {k = "v"},
]

Or maybe something else. This is compatible, and much more "obvious".

But it's not at all clear that we really need to do anything here in the first place. It's probably best to first discus if we want to address this use case at all rather than specific solutions.

marzer commented 1 year ago

This issue, and ones adjacent to it, have come up quite a few times (though yours is much better-presented than most). In no particular order:

Perhaps reviewing those discussions (focusing on the general sentiments within), and rebutting them here, would help your case.

Personally I'm opposed to this sort of thing - the ordering and un-nameable nature of root w.r.t. the rest of the document is a strength in my eyes. The whole "replace JSON with TOML" argument actually does you a disservice IMO - they're two separate languages, intended for two different purposes, and I'm in no hurry to see a change there.

alexmozaidze commented 1 year ago

I came to the conclusion that adding root would not only kill backwards compatibility, but also rob TOML of its simplicity. The only sane syntax for top-level arrays would be [ ... ], but that doesn't feel TOML.