toml-lang / toml

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

Proposal: Reference shortcut for nesting tables #744

Closed brunoborges closed 2 years ago

brunoborges commented 4 years ago

Consider the following exampe:

[servers]

  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

Idea: add a shortcut character to reference the outer table.

Example:

[servers]

  [#.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [#.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

The character # is illustrative and may have to be reconsidered giving it's used already for comments.

The proposal also considers multiple levels:

[servers]

  [#.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

[#.#.firewall]
inbound = "0.0.0.0/24" # this would become `servers.alpha.firewall.inbound`
outbound = "0.0.0.0/24" # similarly, `servers.alpha.firewall.outbount`

  [#.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

The multi-level indicator, e.g. #.#.#..., must match the current structure. For example, #.#.#.#.foo right below a single-level table [bar] must be considered invalid. IDEs and plugins for text editors should be able to provide tooltip to indicate the expanded name of the referenced tables, expanding the value.

The benefit of this feature is to simplify typing while keeping explicitly defined the level of the table, and also in reducing the chances of typos when nesting tables. Can also facilitate when copying/pasting snippets.

brunoborges commented 4 years ago

@marzer Alright, so proceeding with option [*.*.bar] then!

The next question then is: Should placeholders be allowed as part of keys in plain key/value pairs?

Example:

fruit.apple = 2
*.apple.smooth = true # Here, placeholder * references 'fruit' table
*.*.color = "red" # Here, placeholder * references 'fruit.apple' table.
*.orange = 2 # Here, placeholder * also references 'fruit' table

I personally dislike this as it would not encourage developers to better organize the structure with [tables], and the code would look very noisy:

foo.bar = true
*.option1 = true
*.option2 = false
*.*.suboption1 = false

So, my vote already is to only allow use of placeholders in keys for tables and arrays of tables.

marzer commented 4 years ago

The next question then is: Should placeholders be allowed as part of keys in plain key/value pairs?

Hmm. Personally I'm not fond of dotted key-value pairs at all since they already blur the lines between tables and values, so I think we'd only be adding further confusion by allowing this.

It also seems pretty noisy, visually speaking.

I can't say my aversion is a strong one, though, so take it with a grain of salt. Someone may present a compelling use-case for allowing it in dotted KVPs and I'd be on board.

ChristianSi commented 4 years ago

I agree with @brunoborges and @marzer on this one: placeholders should only be allowed in table headers (including array of table headers), NOT in dotted keys. If you feel the need to use placeholders in dotted keys, just use regular tables instead!

pradyunsg commented 4 years ago

Should placeholders be allowed as part of keys in plain key/value pairs?

No.

As everyone else has noted, if it feels like you need shorthands for dotted keys when writing a TOML document, switch to using a table for that bit.


PS: If someone still really really really wants to advocate for allowing shorthands in keys, that'll be an entirely separate discussion from this one -- please file a separate dedicated issue.

brunoborges commented 4 years ago

One final thought (it's late here, so please forgive me!) on the use of *.*.foo is that in the future, I feel it could be an interesting way to allow user to append a specific property that matches any table on that level.

Examples:

[featureA]
name = "Feature A"

[featureB]
name = "Feature B"

[featureC]
name = "Feature B"

# Append property 'disabled=true' to all tables above.
# This could actually appear anywhere in the document (before/after)
[*]
disabled = true

[foo.bar]
prop1 = "some value"

[foo.jay]
prop = "some other value"

# Append disabled to all tables defined as foo.<something>. foo.bar.disabled = true // foo.jay.disabled = true
# Does NOT include 3rd level tables as in foo.jay.mars
[foo.*]
disabled = true

# Append disabled to all 2nd level 'jay' tables. foo.jay.disabled = true
# Does NOT include any other level, such as foo.bar.jay
[*.jay]
disabled = true 

[foo.bar.earth]
name = "Earth"

[foo.jay.mars]
name = "Mars"

[foo.*.*]
disabled = true # disabled all matching 3 levels (foo.bar.earth and foo.jay.mars)

[foo.*.earth]
disabled = true # matches only foo.bar.earth

[*.*.mars]
disabled = true # matches foo.jay.mars only

Any thoughts?

eksortso commented 4 years ago

I can't object more strongly. You can only define the key-value pairs of a table in one place. That is a consistent rule, and using * in that way does violence to that rule.

The application that uses a config file ought to have an intelligent way to handle defaults for subtables. And I've defined such patterns for applications before. Cross-table definitions aren't necessary.

brunoborges commented 4 years ago

I'm glad we were able to stress out respectfully the use of * as a placeholder (pros/cons), and we can move forward with it.

Next, what would be the best terminology for this feature?

<mechanism>:

  1. Reference
  2. Placeholder
  3. Shortcut

And then,

<structure>:

  1. Table
  2. Outer Table
  3. Nesting Table

In other words, how do we best describe this? <structure> <mechanism>?

Any other way to frame this in a way that is easy to explain?

We can then go to writing down rules. But first setting the right terminology, would be very helpful.

eksortso commented 4 years ago

@brunoborges I do like hashing these things out ahead of time, just so long as we don't overdo them.

Let's not call these "references." The word suggests a concept in YAML that permits very complicated data structures and would be out of place in TOML. We can call them shortcuts, with the asterisks being explicitly called placeholders for table and subtable names. A shortcut would mean any header that uses placeholders. So we would have regular headers, followed by shortcut headers.

"Nested tables" are just subtables. "Outer tables," I would not use, because of its association with outer joins in SQL queries. I do need to draw a distinction between tables, table headers, and table sections (what part of the document defines a table), and all that's tied into the scope of dotted keys.

brunoborges commented 4 years ago

@brunoborges I do like hashing these things out ahead of time, just so long as we don't overdo them.

We can call them shortcuts, with the asterisks being explicitly called placeholders for table and subtable names. A shortcut would mean any header that uses placeholders. So we would have regular headers, followed by shortcut headers.

This is great wording, thanks for saying it so clearly.

I like the definitions you propose here.

How about this as definition goes:

--- draft

Table shortcuts

A table shortcut is a table header, used only in subtables, to give continuity of the parent table defined directly before, and therefore not requiring the full path of that table key to be repeated.

Table shortcuts use a placeholder * for each path.

Usage

Given the following example:

[servers]

  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

The subtables keys can be replaced with the following:

[servers]

[*.alpha] 
ip = "10.0.0.1" 
dc = "eqdc10"

[*.beta] 
ip = "10.0.0.2" 
dc = "eqdc10"

[*.*.ports]
inbound = [22, 80, 443]
outbound = [80, 443]

Restrictions

  1. A table shortcut must have each key of the parent table replaced with the placeholder.
  2. Quoted keys are supported just as in regular tables; placeholders must not be quoted.
  3. The position of the table influences the complete key of the table, by referencing the parent table last known prior to the table shortcut.
  4. Parsers must throw an error if the table shortcut does not match the level of a previously defined table.

This is a draft written on mobile. :-P

Kixunil commented 4 years ago

Firstly, I'd suggest not to indent the example as was pointed out elsewhere. I's confusing for people coming from Python/Yaml. Also, the example should contain deeply nested tables to show *.*.foo pattern.

Suggestions on restrictions (see rationale below)

  1. A table shortcut must have each path key of the parent table replaced with the placeholder.
  2. Quoted keys are supported just as in regular tables; placeholders don't have to must NOT be quoted

Rationale:

  1. I don't think path is a term used in Toml spec and it looks like it's the whole thing in [], so there's only one. Further, it was not clear that the meaning is each key of the parent table (even I, who watched this discussion, got confused about the meaning)
  2. Analogy with normal tables will make it easier to understand. Quoted asterisk is not a placeholder but a key, as such it must NOT be quoted.
pradyunsg commented 4 years ago
[servers]

  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

Since this example is the one we've hooked onto, I want to note that this is making a weak case for adding this shorthand.

  1. The indentation is unnecessary.
  2. The initial [servers] is unnecessary.
  3. This example, written "properly", is not "bad" without the shorthands being proposed/discussed here. (excuse the rough choice of words)
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
marzer commented 4 years ago

@pradyunsg Indeed. Here's a pair of extreme examples:

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_catus]
Name = "Domestic Cat"

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_silvestris]
Name = "European Wildcat"

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_chaus]
Name = "Jungle Cat"

versus

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]

[*.*.*.*.*.*.*.*.Felis_catus]
Name = "Domestic Cat"

[*.*.*.*.*.*.*.*.Felis_silvestris]
Name = "European Wildcat"

[*.*.*.*.*.*.*.*.Felis_chaus]
Name = "Jungle Cat"

(I could have folded the initial parent table into the Felis_catus definition but I think this illustrates it more clearly)

brunoborges commented 4 years ago

Looking at these large examples, I couldn't help but only see how difficult it became to count the * to confirm I was on the right level. I wonder if we should rethink, or add a second option, of how to match the parent table.

For short dotted keys, doing [*.*.subkey] is ok, but anything longer than 4, becomes error prone.

One idea that comes to mind is the ability to use numbers to express how many dotted keys (levels) we are talking about.

Example:

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]

[*8.Felis_catus]
Name = "Domestic Cat"

Which I think it's actually nice.

What do others think?

// Draft updated in the previous comment, thanks @Kixunil, @pradyunsg and @marzer

marzer commented 4 years ago

@brunoborges you're right that after 4 levels it gets visually messy, though my gut feel is that 5+ levels of nesting is going to be relatively uncommon (my example was deliberately very extreme).

Methinks it could be revisited in a later proposal if it ends up being a genuine problem for people, since it would be a straightforward, backwards-compatible supplement to the syntax.

brunoborges commented 4 years ago

@marzer What I like about the [*N.<key>] format is that the number itself is a subleveling format, like H1, H2, etc...

Since this proposal is definitely not going to make TOML 1.0 spec, I'd rather spend time in sharpening the idea and get it right from day one rather than iterate it over multiple TOML spec versions.

pradyunsg commented 4 years ago
[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_catus]
Name = "Domestic Cat"

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_silvestris]
Name = "European Wildcat"

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_chaus]
Name = "Jungle Cat"

[snip]

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]

[*.*.*.*.*.*.*.*.Felis_catus]
Name = "Domestic Cat"

[*.*.*.*.*.*.*.*.Felis_silvestris]
Name = "European Wildcat"

[*.*.*.*.*.*.*.*.Felis_chaus]
Name = "Jungle Cat"

Or... use dotted keys and write this as:

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]
Felis_catus.Name      = "Domestic Cat"
Felis_silvestris.Name = "European Wildcat"
Felis_chaus.Name      = "Jungle Cat"

I'd personally push to get the underlying application to let me drop the .Name in this case, mostly because it seems redundant if this is a format designed for human-managed configuration.

brunoborges commented 4 years ago

@pradyunsg This does not eliminate the value added by table shortcuts.

marzer commented 4 years ago

@pradyunsg

Or... use dotted keys and write this as:

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]
Felis_catus.Name      = "Domestic Cat"
Felis_silvestris.Name = "European Wildcat"
Felis_chaus.Name      = "Jungle Cat"

True, though my example was only intended to be illustrative of the proposal's effect. If it truly was a dataset containing information about animal species it'd likely contain more values than just Name, so in your re-write it would become inline tables, which are cumbersome at best.

sgarciac commented 4 years ago

I think it might be more useful to see examples closer to a real configuration file. Let's not forget TOML is not intended to serialize any arbitrary dataset.

marzer commented 3 years ago

Alright then, Here's an example derived from a real file on my machine:

[Importers.Images]
CreateMips = true
Compress = true

[Importers.Images.Normals]
ColourSpace = 'TreatAsLinear'
AllowedChannels = 'rgb'

[Importers.Images.HDR]
CreateMips = false
Compress = false
ColourSpace = 'TreatAsLinear'

versus

[Importers.Images]
CreateMips = true
Compress = true

[*.*.Normals]
ColourSpace = 'TreatAsLinear'
AllowedChannels = 'rgb'

[*.*.HDR]
CreateMips = false
Compress = false
ColourSpace = 'TreatAsLinear'
sgarciac commented 3 years ago

Personally, I find that 1) the proposed feature is not human friendly when the fields list is so large that the referenced parent table is out of sight. 2) when the fields list is short, there's no big benefit over writing something like this, as it has been pointed out:

[Importers.Images]
CreateMips = true
Compress = true

Normals.ColourSpace = 'TreatAsLinear'
Normals.AllowedChannels = 'rgb'

HDR.CreateMips = false
HDR.Compress = false
HDR.ColourSpace = 'TreatAsLinear'
marzer commented 3 years ago

@sgarciac Personally I think dotted key-value-pairs are ugly and repetitive, while [headers] are clean and declarative. Being able to replace dotted KVP's with headers in more places would be great.

Besides, suggestions of header shortening and/or 'references' is something that has come up quite a bit in TOML's history:

These are the few that I found from a quick skim of the issue list, though there's likely others. It being a repeat suggestion indicates there's an opportunity in this space.

brunoborges commented 3 years ago

Dotted keys in KV pairs are explicitly discouraged in the documentation.

Besides, the idea of a table shortcut is to keep the file DRY while still clear and structurally cohesive. The addition of table shortcuts would not take away the ability of repeating the full key in table headers.

I'd still like to debate the value of using the [*NN.subkey] notation for long keys.

sgarciac commented 3 years ago

My gripe against this feature is that the syntax is far from being obvious, which is the main goal of the language (it's even in its name). But, in particular, [*NN.subkey] is definetly anything but obvious and it doesn't belong in a minimalistic language, I oppose it strongly.

If I have never heard of TOML and I read an example of a TOML file (version 1.0), I can pretty much guess with good accuracy what kind of data structure is representing, and I can even modify it without having to read the spec. This is a huge advantage of TOML over, say, a complex YAML file. I think any feature that goes against this really need to be worth it.

marzer commented 3 years ago

@sgarciac

I can pretty much guess with good accuracy what kind of data structure is representing, and I can even modify it without having to read the spec. This is a huge advantage of TOML over, say, a complex YAML file. I think any feature that goes against this really need to be worth it.

This is indeed a good point. Consider, though, that there's a number of features already in TOML with nuances that aren't necessarily immediately obvious:

If I were totally new to TOML and hadn't encountered analogous concepts in other contexts they'd be confusing to me. The "obviousness" here comes with a quick glance at the spec; given a few clear examples these things all click pretty quickly, the "ah-ha!" moment is never very hard-won.

That's also what I like about this particular proposal over some of the others; it still maintains the core structure and simplicity of TOML, while also providing a simple sanity-saver as an almost-advanced feature for those who want it. A clear, simple example (like mine above) explains it pretty much in its entirety.

Incidentally @brunoborges, that it's an almost advanced feature is why I think the additional idea of adding some numbered abbreviation notation to the thing ([*NN.subkey]) isn't a good idea at this stage. That feels like a bridge of complexity too far for TOML.

eksortso commented 3 years ago

@brunoborges I hate being that guy, but...

Dotted keys in KV pairs are explicitly discouraged in the documentation.

Where? Which documentation? I don't see that in the specification at all. There are notes about using inline tables sparingly, but there is no such advice for dotted keys.

Besides, the idea of a table shortcut is to keep the file DRY while still clear and structurally cohesive. The addition of table shortcuts would not take away the ability of repeating the full key in table headers.

Let's not confuse code with configuration. Clarity and cohesiveness are good principles for writing configuration files, but DRY is a coding principle. We're not necessarily introducing shortcuts to cut down on maintenance, nor to reduce the number of tests that would need to be written.

I'd still like to debate the value of using the [*NN.subkey] notation for long keys.

Personally I find the number to be confusing. It is possible to end with more than just a single specified key, and the number doesn't help to show the absolute depth of the keys, only how deep the unspecified keys go.

# The following table names would be identical in context:
[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_silvestris]
[*8.Felis_silvestris]  # EIGHT?
[*6.Felinae.Felis.Felis_silvestris]  # SIX?
[*2.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_silvestris]  # TWO?

An infix variant, like say [Animalia.*7*.Felis_silvestris], may be appealing. Including the first key, that may be appealing. But these patterns would be subjected to the same criticism: is this convenient, or just confusing?

Then again, if we were modeling a real-world configuration, would we need anything more succinct than, say, [*.*.HDR] in practice? Perhaps shortening shortcuts needs to wait.

The "obviousness" here comes with a quick glance at the spec; given a few clear examples these things all click pretty quickly, the "ah-ha!" moment is never very hard-won.

@marzer A core guiding principle, nicely stated.

pradyunsg commented 3 years ago

I just filed #781, for exploring "do we need this?" since that overlaps with #516. :)

brunoborges commented 3 years ago

@eksortso my apologies mate. I got confused with this segment in the toml.io website:

image

Reading through your examples, indeed the use of [*NN.key] could be confusing.

I was just stressing the idea as a mechanism to solve [long.keys.with.several.paths.in.table.headers], but I guess this is unlikely to exist in real config files.

eksortso commented 3 years ago

I was just stressing the idea as a mechanism to solve [long.keys.with.several.paths.in.table.headers], but I guess this is unlikely to exist in real config files.

@brunoborges No worries, it's cool. Actually, we could probably use your insight in #781. We already see uses of TOML in the wild that go beyond config files, and deep nesting could have a definite purpose in the context of TOML and its future. I'm not sure how that will all shake out, but maybe you see some emerging trends.

brunoborges commented 3 years ago

Hey friends, coming back to this with a new proposal: the diamond character as the placeholder.

[servers]

[<>.alpha] # servers.alpha
ip = "10.0.0.1"
dc = "eqdc10"

[<>.beta] # servers.beta
ip = "10.0.0.2"
dc = "eqdc10"

Actually, two characters: < and >.

Diamonds are used for generic types in certain languages, where the type is inferred, so you don't need to repeat that.

List<String> list = new Array list<>();

The benefit here over * is that <> is more prominent and easier to spot when glancing over the document, in a variety of fonts.

Thoughts?

Kixunil commented 3 years ago

I'd suggest for people discussing alternative placeholders to provide some argument for why it should be a good idea, instead of vague question. My argument to prefer * is that it's more well-known to mean "anything".

brunoborges commented 3 years ago

@Kixunil fair point. I updated my comment with more reasoning.

eksortso commented 3 years ago

@brunoborges The diamond <> does stand out. Not unlike XML, lol. It's very visible. And the dots are left in place, so that's pretty good. And the angle brackets being placeholders for types, à la generics, has its appeal, though it may be an appeal lost on non-programmers.

@Kixunil That's my argument for using the asterisk *. It means "anything," but it's anything within context. In the context of absolute table headers, though, it necessarily requires that a context be defined. Its advocates here defined it as the equivalent table name in the same part of the previous header. It's not all previous headers, though, because to date there is no appealing call to blanket-assign items to multiple tables at once.

I'm hard-pressed to recall a precedent for something like this. All I can think of is, in bash, pressing Alt-. brings back the previous command's last argument. That doesn't translate to a character really, though, because periods already have well-defined meanings.

marzer commented 3 years ago

[<>.alpha]

Please no. I spend most of my day writing C++ template code; I could do with typing <> less often as it is. You could argue that in C++ the same is true of *, but it's only a single character and the general connotation of * meaning "anything" far outweighs that complaint.

The benefit here over * is that <> is more prominent and easier to spot when glancing over the document, in a variety of fonts.

I disagree. <> are just visual noise to my eyes. Again, you can blame C++ for that.

marzer commented 3 years ago

Also consider that a standard keyboard only has a finite set of bracket types:

Since two are used in TOML already, we only have two lives left. We should think very carefully about adding bracket-based syntax! Using a type of bracket on a construct that does not expect anything in between the opening and closing brackets, and thus treats them as a single semantic token, would be a waste.

Kixunil commented 3 years ago

I don't think that [*.foo] can be easily mistaken for [foo], thus I don't see a benefit of <> when it comes to readability.

Looking like generics doesn't make sense at all, since generics are about types, toml has values. Completely different things. Further generic syntax for languages differs. E.g. as someone who writes mostly Rust these days, <> did not look look like generics to me at all. And I use generics a lot.

Finally, note that <> symbol is sometimes used as profanity in my native language. Using it could look unprofessional.

brunoborges commented 3 years ago

@marzer you provide a good feedback regarding the limitation of characters that may be used for other features in the future, but are we really considering that once <> is used in a table header, it cannot be used elsewhere outside table headers? The other comment on your personal trauma from C++ is understandable, but IMHO not relevant.

@Kixunil I'd appreciate if we left out comments such as your note out of the technical discussion. <> is a combo used in programming languages (C# and Java for a start), and in mathematics [1]. Just because some silly person thought it could be used as profanity in a specific native language, doesn't turn it forbidden for usage in other completely different, unrelated contexts.

The suggestion of the diamond here was to provide another option to be considered and discussed, with technical merits, not to be a reason for subjective debates.

Please continue with the [*.alpha] proposal.

[1] https://en.wikipedia.org/wiki/Diamond_operator

marzer commented 3 years ago

@brunoborges

but are we really considering that once <> is used in a table header, it cannot be used elsewhere outside table headers?

That's not what I'm suggesting at all. Of course we could re-use brackets! TOML does this already for []. What I'm saying is that we should think very carefully before adding any new brackets, because the 'M' in TOML stands for "Minimal"; any new syntax should be as minimal as possible. Introducing a new pair of brackets only for them to be treated as one single semantic token seems decidedly not minimal.

The other comment on your personal trauma from C++ is understandable, but IMHO not relevant.

OK, I've been with you up until this point, but come on man, that's BS. You asked for our thoughts, I gave mine. That makes them relevant by definition.

Besides that, my point about C++ is extremely relevant from a language user-experience perspective. Have you written any C++? If not, ask your friendly neighbourhood C++ dev what it's like swimming through a sea of <>, they'll tell you that it can get noisy fast. I've no doubt when templates were added to the language their use was much simpler, but scope creep is a helluva drug, and now they're everywhere. Brackets are a syntax abuse gateway drug wherever they're used, so I've no doubt if that syntax found its way into TOML that a similar thing would happen.

Kixunil commented 3 years ago

@brunoborges definitely let's focus on technical discussion. The cultural properties of various symbols can be used to decide in case there's no clear cut. There's a reason I put my note at the end, not beginning. :)

eksortso commented 3 years ago

Just had a thought about this, but it may be impractical. What do you all think?

Ditto marks are used by people in lists as a shortcut for something previously mentioned. It's normally two quote marks put together.

Here's a simple example. See how Doctor is dittoed.

To Do Today
-----------
_ Grocery: Buy eggs
_ Doctor: Get checkup
_    "" : Get Rx refills
_ Post Office: Mail out cards

If we didn't allow zero-length strings for table names, we could have used "" or '' or something instead of an asterisk to stand in for a previously mentioned table. It's two characters, but it's a recognized (albeit old-fashioned) way to reference something again.

But v1.0.0 is out already, and since banning empty-string table names would break the API, so to speak, then we could not use ditto marks in this way before a new major release, a v2 or higher, came out.

jeff-hykin commented 2 years ago

On the idea of [NN.subkey] notation I did want to point out that a glob style syntax might handle those cases (and some of the other cases) fairly well, while being intuitively similar to the ``.

Current * syntax examples

[Importers.Images]
CreateMips = true
Compress = true

[*.*.Normals]
ColourSpace = 'TreatAsLinear'
AllowedChannels = 'rgb'

[*.*.HDR]
CreateMips = false
Compress = false
ColourSpace = 'TreatAsLinear'

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]

[*.*.*.*.*.*.*.*.Felis_catus]
Name = "Domestic Cat"

[*.*.*.*.*.*.*.*.Felis_silvestris]
Name = "European Wildcat"

[*.*.*.*.*.*.*.*.Felis_chaus]
Name = "Jungle Cat"

# The following table names would be identical in context:
[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]
[*8.Felis_silvestris]  # EIGHT?
[*6.Felinae.Felis.Felis_silvestris]  # SIX?
[*2.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_silvestris]  # TWO?

Examples with **:

[Importers.Images]
CreateMips = true
Compress = true

[**.Normals]
ColourSpace = 'TreatAsLinear'
AllowedChannels = 'rgb'

[**.HDR]
CreateMips = false
Compress = false
ColourSpace = 'TreatAsLinear'

[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]

[**.Felis_catus]
Name = "Domestic Cat"

[**.Felis_silvestris]
Name = "European Wildcat"

[**.Felis_chaus]
Name = "Jungle Cat"

# The following table names would be identical in context:
[Animalia.Chordata.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis]
[**.Felis_silvestris]  # EIGHT?
# [*6.Felinae.Felis.Felis_silvestris]  #  -- Not possible with globbing --
# [*2.Mammalia.Carnivora.Feliformia.Felidae.Felinae.Felis.Felis_silvestris] # -- Not possible with globbing --
pradyunsg commented 2 years ago

Closing this as per discussion in #781 (closing note there: https://github.com/toml-lang/toml/issues/781#issuecomment-1056328195) -- I don't think this approach works well for various kinds of nested structures and going down a JSON-like approach for nesting would be better.