{ foo: 1, bar: 2 }
but JSON syntax insists on { "foo": 1, "bar": 2 }
This makes JSON less easily readable by humans, and harder to write or edit by hand.Anyone know why JSON was designed this way?
{ foo: 1, bar: 2 }
but JSON syntax insists on { "foo": 1, "bar": 2 }
This makes JSON less easily readable by humans, and harder to write or edit by hand.Anyone know why JSON was designed this way?
- Getting standards passed is hard (especially for popularly used standards), but can be supported by latent usage in the community. You can create a plugin for a few languages that automatically allows the timestamps and doesn't require commas. Get a bunch of people using it, and you'll be on your way to actually getting it in the standard in the future (still debatable in this specific example, but broadly, usage never hurts for getting something into a standard)
- If your concern is your own frustrations (rather than benefits of the vast majority of people) - I highly recommend a simple editor-level mapping that translates from your preferred DSL to the underlying standard
Per my other comment, there are a variety of plugins on the editor side that will make JSON look like this (e.g., vim-json ). To write out to JSON from that format, you can obviously just write a plugin (in JS this is one line).
But both optional commas and optional double-quotes are provided by Hjson <https://hjson.org/>. They do not advocate its use in protocols, however.
{ delete: "me" }
If you don't want to keep a list of known keywords around, just insisting on quotes is the easier way.[EDIT: See also this YouTube video, where Douglas Crockford explains it himself: https://youtu.be/-C-JoyNuQJs?t=5m]
JSON has the same thing going for it as the h.264 video codec - it may not be _the_ best/most open/etc. format around, but it is one of the few that is supported out the box by all major browsers and Just Works™ (with it's shortcomings).
- No support for comments.
- No support for NaN and Infinities (i.e. lack of full mapping to IEEE 754).
Also at least on Chrome, JSON.stringify(-0) gives 0, though JSON.parse("-0") does give -0. Weird..
As far as schemas are concerned, I find it nicer to not use schemas but access the JSON through an interface that checks things on the fly (types, existence), effectively verifying the JSON while you're examining it. E.g. things like x.get_int('name'), which throws exception if it doesn't exist or isn't an integer. Possibly even with an error message explaining where exactly and what is wrong (like: foo.bars[4].bazes["abc"]: attribute "qux" does not exist).
So this would also have to be legal:
{ "foo": "bar" "baz": "quux" }
I'm not sure that's better, personally. It's also syntactically invalid in Javascript: > "bar" "baz"
SyntaxError: Unexpected string
JSON is just javascript, and it leaves out everything else. That's its entire reason for existing, and it caught on because that's all that 99.44% of anyone needed.
Timestamps you can add today, without changing the protocol; just put them in your data if you need them. So I'm not sure what he's even proposing there.
Schemas: OK, he doesn't like JSON Schema's anyOf. Fair enough. There's no real proposal here for how to fix it, so not much to say here.
Replacing commas with whitespace sounds to me like replacing a very minor irritant with a constant full-body rash. Stuff like his example of "IDs": [ 116 943 234 38793 ] would lead to far more confusion and errors than the occasional stray trailing comma.
So I guess I pretty much vote no on this one thanks for asking
{ "key" "value" 42 37 }
It's a rhetorical question; I think removing the commas is a bad idea. Troubles while hand editing json shouldn't be an overriding use case that drives the syntax.All of those complaints about json and nothing about how you can't have comments?? I feel like Tim Bray and I aren't even on the same planet.
There are a couple of projects which extend JSON. I believe an ideal JSON superset would be compatible with ECMAScript 6 object literals, and have comments and trailing commas.
A standard date type would be huge however, and I'll add to that built-in support for comments. These two things would expand the scope of what you could do with JSON. JSON is already used in so many places for config files but without comments it can be a poor choice.
Breaking that would only lead developers to write code to unbreak it.
"I've been hearing, off in the distance, about something called JSON, that proposes to solve a problem that was neatly solved by XML-RPC in 1998, the encoding of arrays and structs in a format that could easily be processed by all programming languages. The advantage being that you could easily support the protocol in any language that supported XML and HTTP, which, at the time, was quickly becoming all languages."
http://scripting.com/2006/12/20.html
Then there was someone, much younger than Dave Winer, who wrote a response to this (during 2006), and who said (paraphrase) "When I'm older, I look forward to my XML moment; my horror at something that the young kids are doing."
I wish I could find that second quote, but I worry it is lost in the mists of time.
{ "884fbf28-b285-49c2-8335-e42aa3fc896d" "f08bc223-2b49-4d49-a308-7bb93691cef8" }
vs { "884fbf28-b285-49c2-8335-e42aa3fc896d", "f08bc223-2b49-4d49-a308-7bb93691cef8" }
Another example is long ids: { 214748364721474 89234789 7248374293843 23874827 }
vs { 214748364721474, 89234789, 7248374293843, 23874827 }
Should we take into account text format and things like font-spacing? I say yes, because user experience is what's valuable here.Edit: formatting
Timestamps are easily included when I want them, I tend to prefer UNIX time as it's just so much more impact proof. With this proposal can I use UNIX time if I want?
I don't have any problem with JSON. If I did I would have a problem with JavaScript itself, and while there's plenty to complain about I wouldn't propose mixing more formats into it as a solution. There isn't enough care being taken not to introduce additional complexity into the JavaScript world.
He is proposing to add a timestamp type to the grammar. This would have the advantage that there would be one canonical way to have timestamps in your JSON. It would also mean that the parser would already validate them for you and you would not have to do that yourself every time.
I definitely see value in that.
var config = HJSON.parse(fs.fileReadSync('config.hjson'))
Another more obscure, and more powerful serialization format that does away with commas (commas are treated as whitespace!), has a date type, and much more is Rich Hickey's (of Clojure fame) EDN. https://github.com/edn-format/edn
{:a 1, "foo" :bar, [1 2 3] four}
If editing JSON is your problem, use a better editor. If you really want to use JSON as a config file format, use something like YAML instead.
It is nearly a perfect spec for the role it plays. It has taken off because it is so simple. I am constantly amazed that something so simple keeps being jabbed at with more complexity by engineers.
The job of an engineer is to make things that are complex simple, JSON did just that. Make a new standard for your fixes and watch them spiral out of control like XML. Making a simple format that works is damn hard and JSON is a nearly flawless attempt. It is baked into the ecosystem so let's not break it. It was a response to XML complexity/verbosity for use in javascript first, it is so damn useful that it is used everywhere now, why? simplicity.
Everything you need can be done with current JSON. Dates in quotes or ticks (another key for offset if need be), comments in separate files (do you really want © Oracle or Microsoft in all your data files?), strong typing GTFO (use a schema if verbosity is needed -- it supports all needed base types string, numeric, list, object), and it is Javascript Object Notation so it's purpose was to tie to Javascript, don't even attempt to break it from Javascript. If you need more use YAML or XML or a new standard.
If you are trying to change JSON, back away slowly, go add your complexity for minimal or worse benefit elsewhere...
Take the JSON example:
{
"IDs": [116, 943, 234, 38793],
"Settings": { "Aperture": 2.8, "Shutter speed": "1/250" }
}
You could rewrite this as an S-expression as: ((IDs (116 943 234 3879))
(Settings
(Aperture 2.8)
("Shutter Speed" "1/250")))
My workaround is to use CSON, since I'm already using CoffeeScript. It add the syntactic sugar where I'm hand-editing JSON, yet it doesn't impose my tastes on the rest of the world.
In that case, the arguments in favor of breaking long-established compatibility for the sake of hand-editing should be particularly strong.
If personal forgetfulness about editing around commas or date strings are strong arguments, then they should surely also apply to every programming language that uses commas or lacks the concept of a date literal. After all, the code of programming languages exists to be edited, and JSON is merely a means of serialization.
Yeah, this is precisely the kind of stuff people said would cause JSON to "lose" to XML -- how could you ever build anything without schemas and types and bunches of metadata to ensure you were using it correctly?
And this debate is not new; it's been around a long time, and I wrote about it at length literally ten years ago: http://www.b-list.org/weblog/2006/dec/21/i-cant-believe-its-...
Both vivid and accurate.
In order to combat trailing commas I normally place the comma on the following line, e.g.
{ "time": "3 minutes past four"
, "age": 229
, "sex": "monoecious species"
, "appearance": "Tree-like. It's a tree."
}
uint8_t *data // Yada
, *buffer // Ya
;
var javascript
, variable = 6
, declarations = [ "This is taking too long", "Yep" ]
, mix = [ "Flour", "Sugar", "Water" ]
, types = { 'old' : (d) => { return d < new Date }
, 'new' : (d) => { return d > new Date }
, 'borrowed': (o) => { return false }
, 'blue' : (c) => { return true }
}
, regularly = new Date().toISOString()
;
With such a format there is only ever a problem deleting the first line, which I find is much much harder to do without also noticing what you've done to the larger statement.- JSON was never designed to be hand-editable. It's a lucky accident that it's more palatable to edit than XML, but there are other formats like YAML, TOML, and even .ini that fulfill that purpose.
- While JSON was originally envisioned as a subset of Javascript and intended to be materializable by JS eval(), this very quickly turned out to be a bad idea. Once we all switched to using parsers, there is no more compelling need to remain compatible with Javascript, other than human recognizability of syntax, and, y'know, compatibility with 'old' JSON; and
- JSON's greatest strength is that it has such a good impedance match to native 'abstract' data structures supported in just about every contemporary programming language: strings, numbers, lists, maps. When people say 'simple', I don't disagree, but I'm convinced they're actually referring to this feature. Adding additional types -- yes, even timestamps -- would break this property, as datetime handling in most languages leaves a lot to be desired.
There's not even a good reason to read HTML anymore. You hit Ctrl+Shift+C in Firefox (or I think it's J in Chrome) and you view the actual machine-parsed DOM structure. The only reason human-editable/readable formats were ever necessary is a lack of appropriate dev tooling.
There are better relaxed JSON's available than this one:
* https://hjson.org/ does not need those double quotes and can handle without commas just fine.
* https://github.com/phadej/relaxed-json also allows comments, trailing commas, simplier strings as in YAML.
* RJSON http://search.cpan.org/~miko/JSON-Relaxed-0.03/lib/JSON/Rela... is similar.
There is already a canonical way to have timestamps: encode them as defined in RFC 3339.
Done.
The proposals add nothing to JSON and don't make sense. I mean, screwing up with the language just to add a very specific data type that is used in only a specific corner case that isn't even supported in the use case that's provided as an example? Nonsense.
There are other formats for that, like YAML and TOML[1].
When JSON is needed for human-to-computer stuff, I'd say TOML is pretty much always a better choice. A common use case for TOML is config files. And I see a lot of config in JSON lately; this makes me sad. (Though not as sad as the config-in-XML thing the Java ecosystem suffered from.)
Yes, one of my main uses of JSON in my personal projects (and at one of my previous companies) is to serialize a Python dict to disk or network (and to read a Python dict from disk or network, of course). If I keep the members to int/float/str/dict/list, it works beautifully, and if I need to serialize anything more complex, I can always use jsonpickle.
If you want something optimized for human editing, such as for a configuration file or a DSL, we already have YAML for that. Hell, JSON is a valid subset of YAML, so you don't even need two parsers.
1) the author does not mention in his example the use of timezone offsets (which are a part of RFC3339), that's a bit irritating
2) Timestamp parsing and emitting sucks, no matter the language, because the format specifiers are wildly inconsistent across platforms. I prefer the good old UNIX timestamp, because with it there's no complex massaging needed in order to operate with the timestamp.
Also, the author is missing comments entirely - no matter if shorthand // or long-form /* */ gets included, JSON desperately needs commenting ability; but on the other hand I'm worried about compatibility with older systems...
> They’re inessential to the grammar, just there for JavaScript compatibility.
The entire article goes on to suggest extremely terrible solutions to the problems he is pointing out.
In order:
Commas: If comma's are an annoyance, is that to mean there is no annoyance with XML markup? You can forget a closing tag just as easily, probably more easily. Just get a JavaScript or JSON linter. Fixed. If you are really annoyed by commas, move to YAML or another format.
Datetimes: Just store your dates in a standardized timezone and format, how about [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). You can also use a [JSON-Schema](http://json-schema.org/) if you really want.
Schemas: There's lots of potentials here. However, again, if you're going to change JSON so much, why not just pick another data format that has better schema support.
Anyway this is why I think there should be a better way to move tech standards forward than leaving it up to some small number of people who are way too ahead of the curve that they think everyone else has the same problem they do.
In my opinion there is nothing wrong with commas. I am sure the OP had his own issues while working too much with JSON, but for the 90% of the population it's not a problem and even a better way to represent data.
As an example, [116, 943, 234, 38793] is 100% clear and intuitive. Anyone who has seen any array representation will get what this means. But change it to [116 943 234 38793]? There are so many ways you can interpret this. I guess the only people who would think this is better than the 100% intuitive [116, 943, 234, 38793] option are JSON nerds who think too much about this (and when I say JSON nerds I don't mean JSON "users", but people who try to come up with the standard)
As someone who really hates what's going on with javascript (with all the new syntax that needlessly sacrifices simplicity and intuitive nature for the sake of making things shorter), I can't really think nicely about these opinions.
I think these standards that are used by a huge population should move forward in a more democratic way. Or at least let more "normal" people make the decision.
On the JSON part, I agree with everyone, my go-to language for most things is JavaScript, and I'm okay with dates in JSON. I think it's RFC3336 as everyone says (2016-08-20T21:12:26.231Z).
Date parsing could be better when moving across languages, but I mostly prefer sending around millis since Epoch. Considering that people mainly look at their JSON for debug purposes, anyone seeing 1471727663538 should recognise that it's a date.
Other commenters put it well that the author should rather propose a new language, JSON is fine the way it is. Typed successors like Protobufs don't have native date parsing, but I guess being binary, they take away the commas too. I'm comfortable hand-writing JSON or editing it when needed. Most text editors help out by highlighting errors and keeping track of parentheses.
But this illustrates the point: datetime is hard and we don't agree, so even going so far as retrofitting a native RFC 3339 datatype into 'official' JSON is, in my opinion, too far.
The comment I replied to mentions Moment for JavaScript, which I would add to your list. It's beyond excellent, great documentation as with most good quality libs, and very intuitive.
I agree with your point and opinion. Someone mentioned on another thread that engineers are there to simplify things, 'official' JSON has done a darn good job at that, no surprises across languages there.
Tim's ideas are just dangerous - they ruin compatibility for questionable gains. Why not just invent his own standard and call it something else, rather then trying to bust what we have already.
If you are not suggesting that timestamp values be wrapped in quotes, then wouldn't you have to worry about every existing parser out there tripping on them?
Today json is not really tied to javascript that much, I deal with it all the time in python that doesn't include or interact with javascript. JSON is just dictionaries and lists (and strings and numbers and nulls) this is pretty easy to express in dynamically typed languages and not that hard in statically typed languages if you give up on a bit of (static) typing. I don't see any reason why it should be limited to a subset of javascript, there are some good reasons for not changing it all though.
Javascript compatibility is the least important part of json, lots of people use json with python or ruby or rust or java or c for things that will never interact with javascript, and anyways you don't want people to parse json with eval or confusing json with things that include string concatenation or function calls adding non javascript syntax helps make that clear.
There is a good reason to not change JSON(backwards compatibility, updating parsers, confusing formats, ect.), since you're not planning on parsing javascript with eval there is no good reason why any changes made in JSON 2.0 have to conform to a subset of javascript.
My own peeves:
* Numbers are stored in decimal but usually interpreted as binary with no guidance about rounding.
* The concatenation of valid JSON blobs is never valid JSON.
* The empty string is not valid JSON.
The last two can be "fixed" by a format called "arraySON" where the global blob represents not a JSON object (dictionary), but the contents of an array plus an optional trailing comma.
Or given some of the ideas on this thread, perhaps a manadatory leading comma.
Why does Javascript compatibility matter in 2016? The original idea for JSON might have been to parse untrusted data using js eval() but I'd hope that nobody is doing that anymore.
2) The JS Date type has a "toISOString" function that emits an ISO date time string like the ones used in the examples. Since everything else is already based on what JS does, why not just move that behaviour into the JSON spec as well?
The other suggestions are interesting, but rather distracting IMHO.
1. Trailing commas should be allowed. This would fix the entire comma ordeal the author is complaining about without introducing awkward whitespace logic.
2. Date time values should be a distinct type using the format of JS's Date.prototype.toISOString method. Had this been in the language when JSON was originally defined I'm sure it'd already be in JSON.
3. There should be a way to represent Infinity (for IEEE 754 compatibility) and possibly NaN.
4. Comments would be nice because JSON is often used for configuration and documenting JSON snippets can get awkward without them.
5. There's no real way to represent binary data other than base64 encoded strings. It would be nice if there was at least some hex format (e.g. `"blob": <dead beef cafe babe>` with optional spaces for readability) but I can see why some people might be opposed to the idea of adding this to the language
Even "obvious syntax" argument is wrong. "Key": value is not what comes to mind unless your parents spoke to you on js.
Why it is still here: legacy that was easier to read-write than sgml-flavoured monster. Other arguments are nonsense.
That's not canonical at all. It's not even a de facto use of timestamps in JSON; most specifications I see call for ISO 8601.
> Done.
Well no, not done, because you then have to wrap it in a string, which essentially hides it from the JSON parser altogether and moves responsibility for parsing it out of the JSON parser into your application. As far as the JSON parser is concerned, it could be any old string, not a timestamp.
> a very specific data type that is used in only a specific corner case
I don't see how you can call timestamps a corner case – the article says "Among the RESTful APIs that I can think of, exactly zero don’t have timestamps." – and my experience is the same. Pretty much every API I've worked with has used timestamps in some form or another. They aren't a corner case at all – aside links, they are probably the most common data type without direct support in JSON.
That's not the same thing at all. The commas in JSON are equivalent to the whitespace between attributes in XML. A missing closing tag in XML would be equivalent to forgetting to close an object literal or array in JSON. So no, there's no equivalent XML annoyance to what he's asking for, XML is already fixed in the manner he suggests.
You might want to check out JSON Lines:
I wrote a haiku some years back to demonstrate how broken the Ruby implementation was.
YAML:
takes a no for a 'no': no
spring,summer,fall,winter: 3,6,9,12
the game is: on
Running it through ruby 2.3.1 yields.. {"YAML"=>
{"takes a no for a 'no'"=>false,
"spring,summer,fall,winter"=>36912,
"the game is"=>true}}
Nonsense. ISO 8601 is an ISO standard that defines representations of dates and times.
Date and time representations aren't timestamps.
RFC 3339 is based on ISO 8601 but is designed specifically to handle timestamps by including provisions that tackle interoperability problems that ISO 8601 does not handle.
> Well no, not done, because you then have to wrap it in a string
Nonsense.
JSON is just the languge that is used as a superset for other domain-specific languages. How the other language defined (and parsed) isn't handled by the JSON parser, obviously.
Considering Tim Bray's example, If a domain-specific language specifies that a "Capture time" string is followed by a string storing an RFC 3339 timestamp, that's precisely what the parser for the domain-specific language is expected to parse. The document remains valid JSON, and the domain-specific language remains valid.
> I don't see how you can call timestamps a corner case
Because it is. It isn't a primitive data type, nor is it required to implement generic data structures. Hell, some programming languages don't even support any standard date and time container or aggregate data type. Timestamps are a very specific data type whose application is limited to very specific corner cases that are already handled quite well by other means.
e.g.
>>> load(x, Map({"YAML": MapPattern(Str(), Str())}))
{'YAML': {'spring,summer,fall,winter': '3,6,9,12',
"takes a no for a 'no'": 'no',
'the game is': 'on'}}
>>> load(x, Map({"YAML": Map({"spring,summer,fall,winter": Str(), "takes a no for a 'no'": Bool(), "the game is": Bool()})}))
{'YAML': {'spring,summer,fall,winter': '3,6,9,12',
"takes a no for a 'no'": False,
'the game is': True}}
So in other words, what I'm saying isn't "nonsense" at all, and they aren't fundamentally different things as you claim – you just prefer a standard that you think is better?
In any case, you're getting away from the point there. The point was not which standard was better, the point was that RFC 3339 is not canonical.
> > Well no, not done, because you then have to wrap it in a string
> Nonsense.
It's not nonsense in the slightest. You can't put an RFC 3339 timestamp into JSON without wrapping it in a string, at which point it is no longer part of JSON. All JSON sees is a string, not a timestamp.
> The document remains valid JSON, and the domain-specific language remains valid.
I never said that it wasn't valid JSON, my point was that as far as a JSON parser is concerned, it's a string, not a timestamp, so parsing a timestamp has to be handled by your application not the JSON parser.
> It isn't a primitive data type
When the subject of discussion is whether or not it should become a primitive data type, that's circular logic.
> nor is it required to implement generic data structures.
No, but it is required to implement a vast number of JSON-based APIs.
> Timestamps are a very specific data type whose application is limited to very specific corner cases
The "very specific corner cases" being every single RESTful API the author can think of? This is an incredibly common use case, I don't see how you can argue that it's a corner case when it's practically ubiquitous.
Which to be honest is what matters. However I would imagine that a lot of the problem grokking it is due to not being used to it.
Of course don't commit reformats where it diverges from the codebase.
Not 1999. 2004. JSON wasn't on anybody's radar in 1999.
>JSON is incredibly easy to read and write by hand, in comparison with XML
Maybe for small shallow objects (and for those XML is also quite readable). Once size or complexity get a little higher, you're done.
I would actually take away a feature of JSON: Unicode escaping. It's not needed anyway and astral plane characters being encoded as surrogate pairs is an added complexity for encoders/decoders. The selection of escape codes for control characters also is rather arbitrary.
, "age": 229
, "appearance": "Tree-like. It's a tree."
, "sex": "monoecious species"
{ "time": "3 minutes past four"
}
and the syntax is broken. With trailing commas, the syntax always stays valid: {
"age": 229,
"appearance": "Tree-like. It's a tree.",
"sex": "monoecious species",
"time": "3 minutes past four",
}
Would trailing commas and timestamps be nice. Yes. Would they be so nice that dealing with the json to json 1.1 transition would be worth it. Not really.
On removal of commas I'd just disagree.
It looks easier for me; I'm far more likely to notice a missing comma.
But I'm sure you must have a valid point, if you would elucidate?
Luckily, Douglas Crockford has an explanation and an almost prophetic solution[1] for your use-case: I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't.
Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.
1. https://plus.google.com/+DouglasCrockfordEsq/posts/RK8qyGVaG...
And to me, with any decent editor with folding, it is easy to read. And very importantly, allows comments. I have never understood all the XML-hate out there...
Commas were meant to be used in code that you actually type. Using them as separators in a format that is meant to be produced and consumed by computers is clear, simple, and wrong.
Me neither. I think it's truly irrational.
It's nonsense, because a timestamp isn't a date representation. This was already demonstrated. I don't understand why you decided to ignore this.
> The point was not which standard was better, the point was that RFC 3339 is not canonical.
No, the point is that the ISO standard you've quoted doesn't define timestamps. Hence, the example you provided to refute what I've said was nonsense.
> You can't put an RFC 3339 timestamp into JSON without wrapping it in a string
...and you can't encode a date without representing the year as a number, the month as another number, the day as anohter number, etc etc etc.
You, somehow, miss the point that a primitive data type is not required to represent timestamps.
In fact, you can represent timestamps in JSON by defining an aggregate type.
Timestamps as primitive data types doesn't make any sense if it's possible to use the types that are already available to represent it.
> my point was that as far as a JSON parser is concerned, it's a string
Somehow, you don't understand that JSON is only the superset language, and that JSON-based domain-specific languages represent specific subsets of JSON obtained by imposing other parsing rules.
> When the subject of discussion is whether or not it should become a primitive data type, that's circular logic.
You somehow already forgot that this particular data type is already representable by using another primitive data type.
> No, but it is required to implement a vast number of JSON-based APIs.
No, it's not.
Wrap it in a string. Done.
If that's too hard to do, just specify an aggregate data type.
Is it that hard to understand?
> The "very specific corner cases" being every single RESTful API the author can think of?
Somehow, no RESTful API was barred from being implemented in JSON because of this corner case.
I suspect you are, somehow, confusing "convenience" with "necessity".
edit: I was wrong: http://www.lysator.liu.se/c/ANSI-C-grammar-y.html#initialize...