Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What to do when inline tables in heterogeneous arrays get too long? #762

Closed
LukasKalbertodt opened this issue Jul 14, 2020 · 6 comments
Closed
Labels

Comments

@LukasKalbertodt
Copy link

Hi there!

I searched for prior discussions about this topic but did not find anything. If I missed something or just didn't understand the specs: sorry!

So the example for arrays currently shows this:

contributors = [
  "Foo Bar <foo@example.com>",
  { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]

Heterogeneous arrays, yeah. But then I wondered: is the inline table still required to be on one line? And the answer appears to be: yes. So then the question becomes: how do I write that whole array with non-inline tables instead? One large reasoning behind disallowing line breaks in inline tables is that it's easy to write them as non-inline tables, right? But I don't think there is a reason to do that in the heterogeneous array case!

I know this syntax:

[[contributors]]
# what here?!?

[[contributors]]
name = "Baz Qux"
email = "bazqux@example.com"
url = "https://example.com/bazqux"

But that only works for array that only contain tables. What if I also want to have a string element?

So am I missing something or is it in fact true that (with 1.0.0-rc.1) heterogeneous arrays can only contain inline tables, not non-inline ones?

@eksortso
Copy link
Contributor

What you said is true. Heterogeneous arrays were a fairly late development in TOML's history, and inline tables, which are values as well as tables, can populate arrays but were designed to be small and to not span multiple lines. So the idea of packing both small values and large tables in the same array wasn't considered, until now.

For configurations, that's a small sacrifice, and configurations are TOML's primary use case. For general-purpose data definition, though, that's not something that TOML v1.0 will be addressing.

@eksortso
Copy link
Contributor

A number of different ideas that could permit full tables into heterogeneous arrays, including multi-line table values (which I'll admit I'm biased towards), were introduced on the way to v1.0 but were ultimately not picked up. But this does lead me to consider another idea, for post-v1.0, that could offer a solution to more than one perceived need.

What do folks think about this?

# We name an array "contributors".
[[contributors]]
# The first element will be a string.
# Asterisk assigns a value to an absolute key with
#   an erstwhile table's name.
# Must be specified alone. No other key/value pairs.
* = "Foo Bar Foo Bar <foo@example.com>"

[[contributors]]
# The second element will be a table.
name = "Baz Qux"
email = "bazqux@example.com"
url = "https://example.com/bazqux"

That would be equivalent to the first example @LukasKalbertodt provided:

contributors = [
  "Foo Bar <foo@example.com>",
  { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]

The syntax is nowhere near complete, but it's a start.

@ChristianSi
Copy link
Contributor

ChristianSi commented Jul 16, 2020

Tables can be, but they don't have to be heterogeneous; in cases such as this one, it should be possible to convert the array into a non-heterogeneous array of tables and use the corresponding syntax:

[[contributors]]
name = "Foo Bar"
email = "foo@example.com"

[[contributors]]
name = "Baz Qux"
email = "bazqux@example.com"
url = "https://example.com/bazqux"

If config file format designers feel generous, they might also provide for the option to use a single key/value pair as an alternative way of writing a non-table value. They'll have to decide how to name the key – let's say they choose value, that would give us two more ways of expressing the same data – either inline-style (somewhat pointless):

contributors = [
  { value = "Foo Bar <foo@example.com>" },
  { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]

Or array of tables–style (much more useful!):

[[contributors]]
value = "Foo Bar <foo@example.com>"

[[contributors]]
name = "Baz Qux"
email = "bazqux@example.com"
url = "https://example.com/bazqux"

I'm not in favor of @eksortso 's idea of building a special "non-key key" into TOML's syntax for this use case. That would lead to "arrays of tables that contain non-table elements" and that is IMHO too confusing a concept.

@eksortso
Copy link
Contributor

Tables can be, but they don't have to be heterogeneous; in cases such as this one

Was the notion of heterogeneous tables even brought up? The original question revolved around having different types in an array, which is a luxury provided by allowing arrays to be heterogeneous. But that depends on what all you would do with an array in your configuration.

I'm not in favor of @eksortso 's idea of building a special "non-key key" into TOML's syntax for this use case. That would lead to "arrays of tables that contain non-table elements" and that is IMHO too confusing a concept.

Fair criticism. but I would rather see double brackets as indicating an array and then subsequently an element inside that array, then as an abstract array-of-tables divorced from the array and table types. [[this]] is an array first.

@pradyunsg
Copy link
Member

pradyunsg commented Jul 18, 2020

@ChristianSi got it spot on. If you're mixing tables and strings, and it all starts getting too complicated, break it out into an array of tables.

To answer the question from OP "# what here?!?", I think the obvious answer is:

[[contributors]]
name = "Foo Bar Foo Bar"
email = "foo@example.com"

That's something that should be supported by the application. In other words, I think if you're allowing mixing tables with another data structure in an array, all the not-a-table values are a simplification -- there should be an equivalent representation via a table for all of them.

And if an application doesn't support this, well, point them to this comment and tell them to. :)


One large reasoning behind disallowing line breaks in inline tables is that it's easy to write them as non-inline tables, right?

The main reason inline tables do not allow line breaks is to prevent arbitrary nesting of tables in that form. [lots.of.dots.in.table.name] and dotted.keys should be how you preform nesting in TOML, not { one = { two = [{ three = "four", five = "six" }, { seven = "eight", nine = "ten" } ] } }.

Inherently, TOML pushes folks to declare things across multiple lines when there's a lot of information, and that's important part of the design IMO.

@pradyunsg
Copy link
Member

Closing since I think the question has been answered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants