tbl = {
hello = "world",
}
All the examples in the issue you linked should work.now if you see "config in yaml" you know nothing, zero, nada, about the format because all versions are so different and everyone implemented the version at the time and didn't bother to mention version. not to mention you can use a dozen syntaxes for yaml/toml and each application may not understand them all.
all this is so silly. we will stick with json and informal-ini forever one way or another.
Many commonly-used standards today weren't created by a bunch of wise men in a room thinking how to bestow their wisdom upon the rest of us, they often originated in real-world applications, were refined over a period of time based pn real-world experience, and then became a standard.
TOML is the same. I hope it will become an RFC some day. We just need to fix a few outstanding issues first.
Most commonly used TOML parsers support 1.0; adding 1.1 support should be pretty easy as the changes aren't that large (I did it in the parser I maintain, and it's 10 lines of code or so that had to be changed, most of them quite trivial).
Without that your config file is a boobytrap, with it everything is fine and your parsing libraries can even be backwards compatible.
(and mentioning version could be a requirement in a future version)
TOML went through some substantial changes in the past with 0.4, 0.5, and 1.0. As I mentioned in my other comment[1], it's not ideal, but it is what it is.
I wouldn't be surprised if 1.1 would be the last version. Maybe there will be a 1.2 to clarify some things, but I wouldn't expect any further major changes.
Great. Very obvious.
In fairness it's probably not too bad as long as everyone actually migrates to the newest version eventually... But that isn't guaranteed - look at YAML. Or even JSONC. VSCode has a hard-coded lists of which `.json` files are actually JSONC. Gross.
Until you realize you can't actually store real integers because every number in js is a float...
It’s in the name, but be careful not to get confused with JSON being JavaScript.
Not following a set standard is undefined behaviour, leaving it up to the implementation is a large problem in other areas of computer science. Such as C compilers.
Heck, some of them will even choose different endian-ness and sometimes it will matter.
I still remember the first time I dealt with a Java developer who was trying to send us a 64-bit ID and trying to explain to him that JavaScript only has 52-bit integers and how his eyes widened in such earnest disbelief that anybody would ever accept something so ridiculous. (The top bits were not discardable, they redundantly differentiated between environments that the objects lived in... so all of our dev testing had been fine because the top bits were zero for the dev server in Europe but then you put us on this cluster in your Canadian datacenter and now the top bits are not all zero. Something like a shard of the database or so.) We have bigints now but JSON.parse() can't ever ever support 'em! "Please, it's an ID, why are you even sending it as a number anyway, just make it a string." But they had other customers who they didn't want to break. It was an early powerful argument for UUIDs, hah!
Edit: Omg that story. Eep. I guess if someone provided too-large numbers in a JSON format, you could use a custom parser to accept them as strings or bigints. Still, that must have not been a fun time.
I wonder how many times this gets violated though, and how many times this “I dunno… you decide” approach causes problems.
You could declare your own "int32" type[2] for example, and use that. Then validate the input JSON against the schema before parsing it further.
[1]: https://datatracker.ietf.org/doc/html/draft-bhutton-json-sch...
[2]: https://json-schema.org/draft/2020-12/json-schema-core.html#...
So either you don't target javascript (which would be a bit silly in the case of JSON), or you go the other way and forbid integers, even in languages that do support them. Which is also kind of silly.
Ultimately the real issue is that javascript doesn't have integers and if you're interacting with it, you need to be aware of that, JSON or not.
The baseline is anything written in C and C++, which don't have bignum or decimal types and so more or less always parse JSON numbers to either int64 or double, at best.
That's what standards are for, isn't it?
In my experience, violating type constraints causes problems in downstream systems (usually with parsing or trying to operate on invalid values).
Number, as defined by the JSON Schema spec. A 32-bit signed integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647
BigInt is defined by various (MSFT, MySQL, etc): -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Most systems use a JSON String for large numbers, out of necessity, not JSON Number.
- Separate int / float types
- A binary blob type
- Dates
- Maps with non string keys.
Even javascript supports all this stuff now at a language level; it’s just JSON that hasn’t caught up.
It's like API's that mess up the semantics of PUT/GET so implementing idempotency is extra annoying.
One of JSON's biggest benefits is that you don't need to know the shape of the data when you parse. JSON's syntax tells you the type of all of its fields. Unfortunately, that stops being true with numbers as soon as double precision float isn't appropriate. If you use more digits in a JSON number, you can't decode your JSON without knowing what precision you need to decode your data.
Even javascript has this problem if you need BigInts, since there's no obvious or easy way to decode a bigint from JSON without losing precision. In the wild, I've seen bigints awkwardly embedded in a JSON string. Gross.
Putting responsibility for knowing the number precision into the language you're using to decode JSON misses the point. Everywhere else, JSON tells you the type of your data as you decode, without needing a schema. Requiring a schema for numbers is a bad design.
It’s not ideal, but 2^64 integers is also finite.
(in practice for config it usually is but enforcing it is horribly patchy)
JSON !== JS
I agree, especially in regards to the comments, because sometimes the data itself isn't enough and additional human-readable context can be really useful!
In that regard, JSON5 is a wonderful idea, even if sadly it isn't widespread: https://json5.org/
It also supports the trailing commas and overall just feels like what JSON should be, to make it better without overcomplicating it.
https://nigeltao.github.io/blog/2021/json-with-commas-commen... https://github.com/tailscale/hujson
But if you did want to fix JSON, the yes, trailing commas and comments are the absolute minimum bar, but single quote is actually probably the the third absolute must-fix.
The reason is just that so much JavaScript tooling is now configured to autoformat code (including the JSON bits) to swap " to ', thanks in large part to Prettier (which also should almost never be used, sigh, but that's a topic for another HN bikeshed...)
hexadecimal identifiers, yeah, nah
I'm curious what you have against Prettier.
{name: "value"}
And then maybe 123_456 syntaxIt's a slippery slope ... pretty soon it's hard to write a JSON parser, and there are more bugs
The trailing comma one is trivial, I'll grant that
The 123_456 syntax comes close to that, but is much less impactful.
None of those will make the language hard to parse.
print("{")
for elem in list:
print('"key": "value",')
print("}")
seems like immediate worth. print("{")
contents = ""
for elem in list:
contents += '"key": "value",'
print(contents[:-1])
print("}")Apple's XML plist format seems like a mistake, though maybe the newer JSON format is OK.
> JSON is basically perfect if it allowed trailing commas and comments
Apparently Apple actually supports JSON5, an extended JSON based on ES5 that allows trailing commas, comments, and (my favorite!) unquoted key names, among other convenient features.
https://github.com/avakar/pytoml/issues/15#issuecomment-2177...
Datetimes were clearly a mistake to include too. It took the M out of TOML.
Here's the toml.io example in perfectly legal YAML but using only YAML's nicer, JSON-like, compatibility grammar:
title: "TOML Example"
owner: {
name: "Tom Preston-Werner",
dob: 1979-05-27 07:32:00 -08:00
}
database: {
enabled: true,
ports: [8000, 8001, 8002],
data: [
["delta", "phi"],
[3.14]
],
temp_targets: { cpu: 79.5, case: 72.0 }
}
servers: {
alpha: { ip: "10.0.0.1", role: "frontend" },
beta: { ip: "10.0.0.2", role: "backend" },
}
If I were on the YAML board (?) I would push this or a similar subset (JAML? DUML? DUMBL?) to be implemented by parsers in every language: yaml.parse(yamlString, { jamlMode: true }). But it already works today anyway if you stick to the format. And that's what I use for my apps.Multi-line strings in YAML are also very similar to TOML and you can ignore all different character mixups and stick to '|' (w/ newlines) and '"' (no newlines).
# same as " hello world! "
str1: "
hello
world!
"
# same as "apples\noranges\n"
str2: |
apples
oranges
Most numeric TOML examples work too, minus a few bells and whistles like numeric separators '_': # integers
int1: +99
int2: 42
int3: 0
int4: -17
# hexadecimal with prefix `0x`
hex1: 0xDEADBEEF
hex2: 0xdeadbeef
# octal with prefix `0o`
oct1: 0o01234567
oct2: 0o755
# fractional
float1: +1.0
float2: 3.1415
float3: -0.01
# exponent
float4: 5e+22
float5: 1e06
float6: -2E-2
# both
float7: 6.626e-34
# infinity
infinite1: .inf # positive infinity
infinite2: +.inf # positive infinity
infinite3: -.inf # negative infinity
# not a number
not1: .nan[1]: https://json5.org/
Hence the "O" in "TOML" ("Obvious"). And this is the use case for TOML, simple user facing configuration that they are very likely to just get right.
JSON is fine for more intricate data structures or very complex configuration, but if you just need them to enter a few numbers and booleans it is overkill.
In such a hypothetical format, eliminating nulls entirely should Also be considered, the difference between a missing key (undefined) and a null value is significant in JS, but other (particularly statically-typed) languages struggle with differentiating those two cases, and this leads to `serialize(deserialize(a))` representing a different document than `a`.
I'm unconvinced.
YAML is a proper superset of JSON.
edit: just found https://github.com/toml-lang/toml/discussions/915#discussion..., super happy to be able to rest this out early