Let me begin with a little story: About half a year ago I was inspired by TOML to make another simple language for storing structured data. I modified an existing TOML parser and even wrote a spec, but never actually used it... Until now. Recently I decided to reconsider using TOML, so I came here and reread the spec. It still doesn't have all the features that I need for more complicated structures, but it's much closer to my needs. So close, actually, that I decided to make my language a _strict superset of TOML_. Then I thought to myself: Why not just try to propose these changes to TOML itself? And here I am.
You can play with this web-based TOML<->JSON converter to test all of these features (multi-line strings and dates not yet implemented).
But first, take look at this:
# part of actual config for my RESTful API generator
[user.property.id]
type = str
validate.match = /[0-9A-Z_a-z]+/
normalize.strip_whitespace
[user.property.email]
type = email
[user.property.avatar]
type = picture
validate.filesize.max = 5M
normalize.transcode.small = { w=32, h=32, type="png" }
normalize.transcode.big = { w=64, h=64, type="png", no_zoom }
Here's a list of things that I'd like to add (ordered by importance, most needed first):
a.b.c = 42. Very useful when you need to define an object that just happens to have only one or two properties.validate_filesize_max) and split it on the application side, but I think it should be handled by the parser, so the example application can just take all the properties of the validate object (which is usually only one) and interpret them as it wishes.user.property.avatar.normalize.transcode in the example), that just can't be handled in TOML without repeating tons of variable names./s and "bare regex" would just be a full regex beginning with ^ and ending with $k, M, G and %, equivalent to e3, e6, e9 and e-2, respectively and ki, Mi and Gi, similar, but multiplies value by 2^10, 2^20 and 2^30 (more appropriate for file sizes). So, 1ki would mean 1024
set = { "foo", "bar", "quix" }
# when values are not unique we get error
Before somebody points out that it's not minimal: note that my parser is currently just 200 lines of code!
There are some good points you have made here but I think that it might be difficult to discuss your proposal as a whole.
Because your ideas are not directly related to each other and can be added independently I
suggest that you open an individual issue for each of them.
Inline tables are already discussed here: #235.
I'm currently writing a spec for my superset of TOML. Of course I'm gonna name it NOML (I'm so original, I know). I think that splitting some extra features into a separate language is actually a better idea. Leaving open for now.
Hey, @phaux, thanks for these thoughts. There are some interesting ideas in here. I'll address them each quickly and maybe explore some of them via PRs.
I vote for (1) and (2).
And (7): Allow value-less keys, but not for inline objects like @phaux said in (6). e.g.
key = #nothing, default: null or false or an empty object? or ignore the key?
Now I'm going to roll my own parser. :wink:
Please allow keys in key-value pairs to actually be paths. A the moment there is no readable syntax available for the case of multiple small tables embedded at deeper level of hierarchy:
Regarding (6) I would actually go with allowing the equals sign to be optional, i.e.
key
and
key=
would both result in the same thing.
Internally I would prefer an an empty or null or some such value. I find that config files do not always need the presence of an explicit true/false, in a flags file, for example, I would find it preferable to just check for the presence or absence of a flag. I do think it should not be the same as one of the other types, though, such as defaulting to false or true (I support keeping the keywords but allowing a value-less key).
I would not support having the absence of a value mean false, though, as there is a difference between a declaration of a value as false and the absence of a value (which would normally be interpreted as 'use the default value' which may be either false or true (or a non-Boolean value))
Introducing a new "null" value in TOML would open a huge can of worms. Let's never have nulls in configuration files.
I'd be open to hearing proposals to list keys in ways that would set them all true. Could be obvious, could be clear, could be useful, but could be taken up in the future.
Keys as paths would be neat. I'm a little worried what it says about your data model that you want it, though.
We've got inline objects now. 馃帀
Let's not require every implementation of TOML to incorporate a PCRE parser. You can't just parse the slashes, by the way, because these need to work:
re_a = /(/)/
re_b = /\//
re_c = /[/]/
re_d = /"/
(I know this reasoning also applies to dates/times)
Barewords would be nice, but I understand that they're not added because barewords make it hard to add new syntax without breaking existing files.
Suffixes are an example of the barewords problem. If barewords get turned into strings, then this file will be considered valid, but parsed differently, by a TOML implementation that supports magnitude suffixes and one that doesn't:
mst = 3k
mst = "3k"
mst = 3000
Let's not add null. Typically, you can just use false, or the absence of a key, to communicate the same thing.
I would really like the ability to have functionality that is enabled by default and the user can explicitly turn it off. So let's not remove explicit booleans (even if implicit ones are added). Besides, false makes a good stand-in for null where people need it.
I reckon this can be closed.
AFAICT, everything except 1 and 5 have been decided upon. 1 got #499 and 5 has #427 for discussion.
Most helpful comment
Introducing a new "null" value in TOML would open a huge can of worms. Let's never have nulls in configuration files.
I'd be open to hearing proposals to list keys in ways that would set them all true. Could be obvious, could be clear, could be useful, but could be taken up in the future.