The canonical S-expression representation solves some of the problems JSON has, true, but the example you provided is not a canonical S-expression. It wouldn't make sense for it to have been, because canonical S-expressions are a binary format and not comparable in this context to JSON or XML.
Application developers voted with their feet for serialization formats with native representations of common data types (strings, numbers, lists, maps, booleans, null). There's a lot of reasons that JSON has supplanted XML, but one of them is that JSON has these types built in and XML does not. A lot of real-world data interchange and storage can make good use of those primitives. Many problems boil down to "how do I pass around a list of key/value records". There is a lot to say for not having to renegotiate that kind of basic detail every time two applications need to communicate.
You can represent S-expressions as JSON strings and arrays. I've done it. It was the best way to represent the data I was trying to store, but that's because the data was already represented as S-expressions. I've never seen anyone else do it, and that doesn't surprise me. For most purposes JSON is used for, it is more useful than S-expressions -- not necessarily more powerful, but more useful.
In an important sense, then, I'd claim that it is a "canonical S-expression".
The reason this works is because SPKI S-expressions aren't just a grammar for a syntax, they also come with [3] a total /equivalence relation/, which is exactly what JSON lacks and which is what makes JSON such a pain to work with.
In other words, SPKI S-expressions have a semantics. JSON doesn't.
Lots of other "modern" data languages also lack equivalence relations, making them similarly difficult to use at scale.
[ETA: Of course, your point about lacking common data types is a good one! My fantasy-land ideal data language would be something drawing from both SPKI S-expressions and BitTorrent's "bencoding", which includes integers and hashes as well as binary blobs and lists.]
---
[1] Section 6.3 of http://people.csail.mit.edu/rivest/Sexp.txt
[2] Section 6.1 of http://people.csail.mit.edu/rivest/Sexp.txt
[3] The SPKI S-expression definition is still a draft and suffers a few obvious problems - ASCII-centrism and the notion of a "default MIME type" being two major deficits. Still, I'd love to see the document revived, updated, and completed. Simply having an equivalence relation already lifts it head and shoulders above many competing data languages.
It's a sequence of bytes — a string, if you like.
> How do I know when parsing the 'entry' field that what follows is going to be a list of key/value pairs without parsing the whole expression?
You wouldn't, and as a parser you wouldn't need to. The thing which accepts the parsed lists of byte-sequences would need to know what to do with whatever it's given, but that's the same issue as is faced by something which accepts JSON.
> Is 'see-also GML XML' parsed as a list?
(see-also GML XML) is a list.
> How do we distinguish between single element lists and scalars?
'(single-element-list)' is a single-element list; 'scalar' is a scalar. Just like '["single-element-list"]' & '"scalar"' in JSON.
> Is it possible to express a list at the top level, like JSON allows?
That whole expression is a list at top level.
> How do you express a boolean, or null?
The same way that you represent a movie, a post or an integer: by applying some sort of meaning to a sequence of bytes.
> They do not solve questions of maximum levels of nesting.
They don't solve the problem of finite resources, no. It'll always be possible for someone to send one more data than one can possibly process.
> They have the same potential pitfalls with whitespace.
No, they don't, because Ron Rivest's canonical S-expression spec indicates exactly what is & is not whitespace.
> They have exactly the same problems with parsing strings and numbers.
No they don't, because they don't really have either strings or numbers: they have lists an byte-sequences. Anything else is up to the application which uses them — just like any higher meaning of JSON is up to the application which uses it.
> They have the same problem with duplicated keys.
No, they don't — because they don't have keys.
> My point is that in order to match what JSON can do, you have to create rules for interpreting the S-expressions, and those rules are the hard part.
My point is that JSON doesn't — and can't — create all the necessary rules, and that trying to do so is a mistake, because applications do not have mutually-compatible interpretations of data. One application may treat JSON numbers as 64-bit integers, another as 32-bit floats. One application may need to hash object cryptographically, and thus specify an ordering for object properties; another may not care. Every useful application will need to do more than just parse JSON into the equivalent data structure in memory: it needs to validate it & then work with it, which almost certainly means converting that JSON-like data structure into an application-specific data structure.
The key, IMHO, is to punt on specifying all of that for everyone for all time and instead to let each application specify its protocol as necessary. The reason to use S-expressions for that is that they are structured and capable of representing anything.
Ultimately, we can do more by doing less. JSON is seductive, but it'll ultimately leave one disappointed. It does a lot, but not enough. S-expressions do enough to let you do the rest.