| ▲ | eadmund 8 months ago |
| > I feel like not understanding why JSON won out is being intentionally obtuse. I didn’t feel like my comment was the right place to shill for an alternative, but rather to complain about JSON. But since you raise it. > JSON can easily be hand written, edited, and read for most data. So can canonical S-expressions! > Canonical S-expressions are not as easy to read and much harder to write by hand; having to prefix every atom with a length makes is very tedious to write by hand. Which is why the advanced representation exists. I contend that this: (urn:ietf:params:acme:error:malformed
(detail "Some of the identifiers requested were rejected")
(subproblems ((urn:ietf:params:acme:error:malformed
(detail "Invalid underscore in DNS name \"_example.org\"")
(identifier (dns _example.org)))
(urn:ietf:params:acme:error:rejectedIdentifier
(detail "This CA will not issue for \"example.net\"")
(identifier (dns example.net))))))
is far easier to read than this (the first JSON in RFC 8555): {
"type": "urn:ietf:params:acme:error:malformed",
"detail": "Some of the identifiers requested were rejected",
"subproblems": [
{
"type": "urn:ietf:params:acme:error:malformed",
"detail": "Invalid underscore in DNS name \"_example.org\"",
"identifier": {
"type": "dns",
"value": "_example.org"
}
},
{
"type": "urn:ietf:params:acme:error:rejectedIdentifier",
"detail": "This CA will not issue for \"example.net\"",
"identifier": {
"type": "dns",
"value": "example.net"
}
}
]
}
> for an Canonical S-expression, you have to count how many characters you are typing/deleting, and then update the prefix.As you can see, no you do not. |
|
| ▲ | thayne 8 months ago | parent | next [-] |
| Your example uses s-expressions, not canonical s-expressions. Canonical s expressions[1] is basically a binary format. Each atom/string is prefixed by a decimal length of the string and a colon. It's advantage over regular s expressions is that there is no need to escape or quote strings with whitespace, and there is only a single possible representation for a given data structure. The disadvantage is it is much harder to write and read by humans. As for s-expressions vs json, there are pros and cons to each. S-expressions don't have any way to encode type information in the data itself, you need a schema to know if a certain value should be treated as a number or a string. And it's subjective which is more readable. [1]: https://en.m.wikipedia.org/wiki/Canonical_S-expressions |
| |
| ▲ | eadmund 8 months ago | parent | next [-] | | > Your example uses s-expressions, not canonical s-expressions. I’ve always used ‘canonical S-expressions’ to refer to Rivest’s S-expressions proposal: https://www.ietf.org/archive/id/draft-rivest-sexp-13.html, a proposal which has canonical, basic transport & advanced transport representations which are all equivalent to one another (i.e., every advanced transport representation has a single canonical representation). I don’t know where I first saw it, but perhaps it was intended to distinguish from other S-expressions such as Lisp’s or Scheme’s? Maybe I should refer to them as ‘Rivest S-expressions’ or ‘SPKI S-expressions’ instead. > S-expressions don't have any way to encode type information in the data itself, you need a schema to know if a certain value should be treated as a number or a string. Neither does JSON, as this whole thread indicates. This applies to other data types, too: while a Rivest expression could be (date [iso8601]2025-05-24T12:37:21Z)
JSON is stuck with: {
"date": "2025-05-24T12:37:21Z"
}
> And it's subjective which is more readable.I really disagree. The whole reason YAML exists is to make JSON more readable. Within limits, the more data one can have in a screenful of text, the better. JSON is so terribly verbose if pretty-printed that it takes up screens and screens of text to represent a small amount of data — and when not pretty-printed, it is close to trying to read a memory trace. Edit: updated link to the January 2025 proposal. | | |
| ▲ | antonvs 8 months ago | parent [-] | | That Rivest draft defines canonical S-expressions to be the format in which every token is preceded by its length, so it's confusing to use "canonical" to describe the whole proposal, or use it as a synonym for the "advanced" S-expressions that the draft describes. But that perhaps hints at some reasons that formats like JSON tend to win popularity contests over formats like Rivest's. JSON is a single format for authoring and reading, which doesn't address transport at all. The name is short, pronounceable (vs. "spikky" perhaps?), and clearly refers to one thing - there's no ambiguity about whether you might be talking about a transport encoding instead, I'm not saying these are good reasons to adopt JSON over SPKI, just that there's a level of ambition in Rivest's proposal which is a poor match for how adoption tends to work in the real world. There are several mechanism for JSON transport encoding - including plain old gzip, but also more specific formats like MessagePack. There isn't one single standard for it, but as it turns out that really isn't that important. Arguably there's a kind of violation of separation of concerns happening in a proposal that tries to define all these things at once: "a canonical form ... two transport representations, and ... an advanced format". |
| |
| ▲ | dietr1ch 8 months ago | parent | prev [-] | | The length thing sounds like an editor problem, but we have wasted too much time in coming up with syntax that pleases personal preferences without admitting we would be better off moving away from text. 927 can be avoided, but it's way harder than it seems, which is why we have the proliferation of standards that fail to become universal. |
|
|
| ▲ | eximius 8 months ago | parent | prev | next [-] |
| For you, perhaps. For me, the former is denser, but crossing into a "too dense" region. The JSON has indentation which is easy on my poor brain. Also, it's nice to differentiate between lists and objects. But, I mean, they're basically isomorphic with like 2 things exchanges ({} and [] instead of (); implicit vs explicit keys/types). |
| |
| ▲ | josephg 8 months ago | parent | next [-] | | Yeah. I don’t even blame S-expressions. I think I’ve just been exposed to so much json at this point that my visual system has its own crappy json parser for pretty-printed json. S expressions may well be better. But I don’t think S expressions are better enough to be able to overcome json’s inertia. | |
| ▲ | em-bee 8 months ago | parent | prev [-] | | even as a fan of s-expressions (see my other comment), i have to agree. but the problem here is the formatting. for starters, i would write the s-expression example as: (urn:ietf:params:acme:error:malformed
(detail "Some of the identifiers requested were rejected")
(subproblems ((urn:ietf:params:acme:error:malformed
(detail "Invalid underscore in DNS name \"_example.org\"")
(identifier (dns _example.org)))
(urn:ietf:params:acme:error:rejectedIdentifier
(detail "This CA will not issue for \"example.net\"")
(identifier (dns example.net))))))
the alignment of the values makes them easier to pick out and gives a visual structurebut, i would also argue that the two examples are not equivalent. what is explicitly specified as "type" and "value" in the json data, is implied in the s-expression data. either format is fine, but it would be better to compare like for like: an s-expression equivalent for the json example would look like this: ((type urn:ietf:params:acme:error:malformed)
(detail "Some of the identifiers requested were rejected)
(subproblems
((type urn:ietf:params:acme:error:malformed)
(detail "Invalid underscore in DNS name \"_example.org\"")
(identifier
(type dns)
(value _example.org)))
((type urn:ietf:params:acme:error:rejectedIdentifier)
(detail "This CA will not issue for \"example.net\"")
(identifier
(type dns)
(value example.net)))))
or the reverse, a json equivalent for the s-expression example: {
"urn:ietf:params:acme:error:malformed":
{
"detail": "Some of the identifiers requested were rejected",
"subproblems":
[
"urn:ietf:params:acme:error:malformed":
{
"detail": "Invalid underscore in DNS name \"_example.org\"",
"identifier":
{
"dns": "_example.org"
}
},
"urn:ietf:params:acme:error:rejectedIdentifier"
{
"detail": "This CA will not issue for \"example.net\"",
"identifier":
{
"dns": "example.net"
}
}
]
}
}
a lot of the readability depends on the formatting. we could format the json example more dense: {"urn:ietf:params:acme:error:malformed": {
"detail": "Some of the identifiers requested were rejected",
"subproblems": [
"urn:ietf:params:acme:error:malformed": {
"detail": "Invalid underscore in DNS name \"_example.org\"",
"identifier": {
"dns": "_example.org" }},
"urn:ietf:params:acme:error:rejectedIdentifier": {
"detail": "This CA will not issue for \"example.net\"",
"identifier": {
"dns": "example.net" }}]}}
doing that shows that the main problem that makes json harder to read is the quotes around strings.because if we spread out the s-expression example: (urn:ietf:params:acme:error:malformed
(detail "Some of the identifiers requested were rejected")
(subproblems
((urn:ietf:params:acme:error:malformed
(detail "Invalid underscore in DNS name \"_example.org\"")
(identifier
(dns _example.org)
)
)
(urn:ietf:params:acme:error:rejectedIdentifier
(detail "This CA will not issue for \"example.net\"")
(identifier
(dns example.net)
)
)
)
)
)
that doesn't add much to the readability. since, again, the primary win in readability comes from removing the quotes. |
|
|
| ▲ | eddythompson80 8 months ago | parent | prev | next [-] |
| > is far easier to read than this (the first JSON in RFC 8555): It's not for me. I'd literally take anything over csexps. Like there is nothing that I'd prefer it to. If it's the only format around, then I'll just roll my own. |
| |
|
| ▲ | NooneAtAll3 8 months ago | parent | prev | next [-] |
| > I contend that this is far easier to read than this oh boi, that's some Lisp-like vs C-like level of holywar you just uncovered there and wooow my opinion is opposite of yours |
|
| ▲ | remram 8 months ago | parent | prev | next [-] |
| This doesn't help with numbers at all, though. Any textual representation of numbers is going to have the same problem as JSON. |
|
| ▲ | michaelcampbell 8 months ago | parent | prev [-] |
| > is far easier to read than this Readability is a function of the reader, not the medium. |