188 comments

[ 2.8 ms ] story [ 91.6 ms ] thread
Yes, please! This applies to many other lists as well, not only restricted to JSON.

Besides, imagine a world of Java, Javascript, C-like anything, where you would be DISALLOWED to have a semicolon after the last statement in a block. Crazy thought, right?

In C you couldn't follow cases and labels with just a semicolon, it was an invalid statement. That's because a statement couldn't be just a semicolon. But yes, I agree.
(comment deleted)
Javascript: automatically inserts semicolons for you at the end of a line, but doesn't allow commas at the end of a list.
Welcome to Pascal.
How do you mean? In Pascal the semicolon after the last statement of a block is optional. So, for example, this:

  function square(const x : Integer) : Integer;
  begin
    result := x * x;
  end;
Is equivalent to:

  function square(const x : Integer) : Integer;
  begin
    result := x * x
  end;
If you mean in if-then-else constructions, then yes the semicolon must be at the end of the statement:

  if (condition) then
    dosomething
  else
    dosomethingelse;
Commas are unnecessary. There is zero benefit to having them. The code is actually easier to parse if you just remove them from the rules list entirely. No commas might look weird for a day or so, but you quickly get used to it.

(I'm ignoring the comma operator, which is a special case and not relevant to the main point.)

They exist because of string concatenation. In some languages any consecutive strings are implicitly concatenated so that you can have a very long string split across many lines.
(comment deleted)

    foo(x, -y)
is not the same as

    foo(x -y)
(from your last sentence, I assume you were talking about JS in general, not just JSON)
Mm, fair point. Infix math rears its ugly head again. I've been living in Lisp a bit too long.

Never mind.

Actually, let's double down: Instead of writing 1+2, you should really be writing +(1 2). Don't you see how much easier that would make things? A single, uniform syntax everywhere! + is just a function that gets called like anything else! Your foo(x -y) example would become foo(x -(y)).

I'm mostly joking.

Haskell makes a reasonable job of combining infix operators with no commas between function arguments[1]. You sometimes end up with a few extra parentheses and $s instead, but things generally seem to work out.

Does use commas for lists and tuples, though. The latter kind-of make sense, it's the commas that identify the expression as a tuple. Not sure what the rationale for commas in lists is, though.

[1] Slightly complicated by currying (arguably, it's several successive function applications rather than one multi-arg application) but the end result is the same...

> Not sure what the rationale for commas in lists is, though.

Well, you need some separator, and spaces won't do since [x y] has x applied to y.

Good point.

Although could, in principle, make space-between-list-items higher precedence than function application. E.g.:

    [x (func y) z]
But how do you write a list with only one element, x (func y) z?
It's not infix math that's the problem, it's the ambiguity of "-". It can take two arguments in one context, or one in another (or just be a representation of a negative number without implying any function call at all.) If we just used a different symbol for subtraction, it would clear up a number of other parsing problems languages run into. Or you could just require negations to be done inside parentheses.
Or just require whitespace for binary - and no whitespace for unary.

  res = -x ==> negative x

  res = c - x ==> c minus x

  res = - x ==> syntax error
I like OCaml's terse syntax. You can write something like that as just "foo x (-y)" (the brackets are only needed because of the use of minus but can usually be omitted).
Not really suggesting this, but if we only allow the unary operator - to always be stuck next to the number, and the binary operator - to always be surrounded by whitespace, it is. So:

  foo(x -y) => foo(x, -y)

  foo(x - y) => foo(x - y)
In Rust, omitting the last semicolon in a block indicates an implicit return of the final expression of the block.
That's terrible, to have semantics depend on such a tiny syntax change that's so easy to miss.
I wish there was times that HN supported Quadratic Voting[0] so that I could more (but costly) up votes to a really sane and pertinent comment.

[0] http://ericposner.com/quadratic-voting/

I've never heard about quadratic voting before. This is very interesting!
Thanks for the link, I started reading the paper. I love this:

Groups frequently make collective decisions through majority rule. Legislators pass bills by majority; shareholders make most corporate decisions by (share-weighted) majority rule, as do directors; clubs, university faculties, and civic associations typically use majority rule as well. The reason that they do so is not entirely clear. (Emphasis mine).

>The reason that they do so is not entirely clear.

Not clear? It's almost too clear as to be tautological.

They do because they (a) think all members should have equal say, (b) most members in the group want X to be done.

Unless we're talking about submitting to force or listening to expertise, why would many people wanting to do something, let fewer people tell them what to do instead?

Heck, if it comes to fighting for what's to be done (the most effective but primitive form of getting a decision), the majority could beat up the minority and have its way anyway.

Have you tried writing Rust? I have and I think this feature is great.

I upvoted you for your link, but actually the argument that it would be good because people who care more will make a better decision than those who don't does not completely convince me. Someone could care a lot about something but still have the wrong idea about it.

Since we're going off-topic about QV here: am I correct in my understanding that you can _buy_ votes there? Because the obvious problem (because I'm probably missing something) with that would be that money is not as costly for some as it is for others? In other words, it'd lead to tyranny of the wealthy?
(from a cursory read) You can buy votes, but they become increasingly costly. Also, the payments are redistributed out among the population, so if you spend 1B to buy 31.6K votes, that 1B gets handed to the population at large who, if larger in number, can more efficiently re-spend it voting you down.

What I imagine QV does is find the point at which participants who don't care so much would rather pocket the funds and walk away, rather than spend it on voting.

If the ballot measure is "Eat Vinnl", you might want to spend a lot to vote it down, but it might not take much to convince the others not to spend it back at you (and you all eat berries instead). If the ballot measure is "Vinnl eats everyone else", you won't be able to spend enough that everyone else can't just spend it back at you, more efficiently.

Edit: one important difference here is that unless the GP is actually going to pony up real money, something of value to those they inconvenience with their (imo silly) opinion, it doesn't make much sense.

Interesting idea, but what if I stead of buying them, we could spend our accumulated points to emphasize ideas.
In practice it's not so bad, because your program won't compile if you've missed returning something in any branch, or if you've returned the wrong thing.
No it isn’t. In practice it’s extremely obvious when it is happening. And if you mess up and add a semi colon accidentally then the type checker will catch it.
(comment deleted)
IANAPLRESEARCHER, but to my understanding, it actually unifies the semantics. The return value is always the result of the last expression, and its type may either be something non-trivial, or `()` which is what `expr;` returns.

This makes it easier to write and use generic code for which you don't know the return type (could be `String`, could be `()`), without insisting on special cases for "returns a thing" and "doesn't".

Example: I hold a thing of type `T` and want to let you call a function on it. I can write this generically as

    pub trait WithMut<T> {
      fn with_mut<R, F: Fn(&mut T)->R>(&mut self, func: F) -> R;
    }
and now with one implementation I can deal both with functions that return meaningful values, and "computations" that do some work but return nothing (other than `()`).
How do you feel about the ! operator?
I won't even get started. I see no reason why a modern language would use it in preference to "not" (like Python).
It's actually super nifty and IMO a great feature. However I think one of the reasons it works so well is that Rust is statically and very strongly typed, in a more dynamic language it would be hard to keep track of what's going on.

An other reason it works is that almost everything is an expression in Rust, including things like `if` statements. So for instance you can write:

    let message =
        if auth_ok() {
            "success"
        } else if tries < 3 {
            "try again"
        } else {
            "failure"
        };
If you add semicolumns after the strings the `if` will always evaluate to nil here.

Note that this won't work if one branch returns string an and other returns an integer for instance since the type of "message" must be known at compile time.

It also works well for getter functions and lambdas, for instance:

    fn is_empty(&self) -> bool {
        self.len == 0
    }
or:

    list.sort_by(|a, b| a.key < b.key);
This way you focus on what's important.

I can see where you're coming from though, it's easy to dismiss this feature as a bad idea on paper, especially if you've been traumatized with Javascript's insane handling of semicolumns. In practice however it's a rather useful sugar and so far it's been harmless in my experience. It basically makes the language more lispy.

I read your comment more as an endorsement of implicit returns. Make no mistake, I love those. I've been using them most of my life, first in OCaml and then in Scala.

I just think that using the semicolon to make the function return unit instead is problematic. It would be better to have the type system guide that decision, like in Scala. It would be even better to have an explicit `ignore` function or something (like in OCaml) to signal to the compiler that you really want to ignore the value and you only care about uthe side effect. I mean, why would you ever write just e.g. `a < b;`?

> I just think that using the semicolon to make the function return unit instead is problematic.

Agree. The idea to attach additional semantics to ; is completely nuts, especially as ; is mandatory in Rust (usually, there are odd corner cases where it is not allowed).

Just get rid of mandatory ; completely and let the type system handle the rest.

; is used to separate statements, how do you propose to get rid of that?

I guess you could use significant newlines like python but I never really liked that. I think Rust's compromise is pretty decent.

In particular it's the first time I hear people complaining about it, so far most users (myself included) seem to be praising it. Javascript's handling of semicolon is nuts, I wouldn't say Rust's is.

It's 2017, I'm not placing ; by hand anymore.

We have computers they are perfectly able infer them for me.

> Javascript's handling of semicolon is nuts, I wouldn't say Rust's is.

- JavaScript does insane things, as usual. This doesn't mean every implementation of semicolon inference has to be that bad and broken.

- Rust goes the other way by pretending it's still 1990.

There are plenty of languages out there that handle semicolon inference perfectly fine.

(Heck, I even let the IDE show me where the compiler has placed them.)

I was thinking the same before actually using rust. Turns out it surprisingly awesome given how rust treats statements and expressions.

it just makes obvious that "result of something" and "control flow back to caller" are very different things.

Don't sweat it, your compiler will point it out and it's fairly ingrained to functional programmers that the last line of function is its return value anyway
Oh definitely, implicit returns are awesome. I just commented on the fact that a semicolon supresses them.
By your logic, you should also hate the "+" and "-" operators – they're just as easy to confuse as ";" and "", completely change the semantics, and the type checker won't even catch your mistake!
Some JavaScript style standards require no semicolons at the end of lines: https://standardjs.com/rules.html#semicolons
Yes, but he means no semicolon only on the last statement of a function, I believe.
I made the switch earlier this year and I don't think I would ever willingly go back. It just looks so much more parsable. Semicolons at the end of my statements just look ugly and savage now.
In Erlang, commas and semicolons are separators not terminators. So you are in fact disallowed to have a semicolon at the end of a sequence of clauses, it's either nothing (for case) or a period (for functions)
It sounds dumb, but this was actually one of the things that turned me off Erlang despite my interest.
It's definitely weird, but it allows for neat stuff e.g. in Emacs' erlang-mode when you type a semicolon it automatically creates a new clause (function or case) for you.
I really dislike JSON. It's better than XML, but not by much.

There are several fundamental problems with JSON, one of which being that you have to duplicate the field names over and over again. It's just not a very structured format. Trailing commas is the least of my concerns.

I would like to see protobuf take over at this point.

It's an unstructured format, that's the point.

You can't edit a protobufs in an editor.

Maybe not in vanilla text editors, but I don't see a reason you couldn't have an Emacs mode or special-purpose editor that lets you manipulate protobufs as text or structured data, respectively.
Actually, there is a built-in ASCII format for them as well. It's a little less flexible than the binary serialisation though.

There's a canonical JSON serialisation in v3 as well, although obviously that doesn't solve the OP's problem...

Proto3 has a JSON serialization that you can use as an intermediate for editing
What formats would you suggest that are editable with a text editor and removes all the issues you have?
Why do you treat data representaions as mutual exclusive? Most web frameworks allow to have them. 'Accept: application/json, application/protobuf, text/xml'... problem solved.
Or you could serialise like this:

    {
      'fields': ['a', 'b'],
      'values': [
         [1, 2],
         [5, true]
      ]
    }
I might be misunderstanding something here, why not just:

    {
      a: [1, 2],
      b: [5, true],
    }
But this doesn't solve the problem if your data isn't a nice table and has deeply nested tree structures. Which is what JSON is for, otherwise people would have just stuck with CSV.
Why would it ever matter that keys are duplicated? It should always be compressed when going over the wire anyway
The use case of JSON is to be able to read structured data from dynamic languages, with a single line of code and no preparation otherwise. It fits this purpose and it works well if you know the layout of the input.

As a storage format I don't like it, either. No canonical representation (at all): Arbitrary whitespace, arbitrary order of members. Too much line noise: Quotes around each member name. No schema support.

CBOR [1] has an extension to allow string references [2], so field names won't take up much space.

[1] RFC-7049, also http://cbor.io/

[2] http://cbor.schmorp.de/stringref It won't make much sense unless you already understand CBOR encoding, but it's a registered extension.

>I really dislike JSON. It's better than XML, but not by much.

You'd be surprised -- if you had to live through the XML madness of the early 00s. And don't get me started on SOAP, XML namespaces and other crap.

>There are several fundamental problems with JSON, one of which being that you have to duplicate the field names over and over again.

You don't duplicate field names. You define different objects that just happen to have the same fields. They could just as well have different ones.

That's something for transport compression to handle.

The title is a possible reference to this satirical essay about solving poverty through cannibalism: https://en.wikipedia.org/wiki/A_Modest_Proposal
(comment deleted)
(comment deleted)
I assume so too, and it's well worth reading. From 1729, by Jonathan Swift. Full text here: http://www.gutenberg.org/files/1080/1080-h/1080-h.htm

When I was a kid in the 80s, the parents of a kid in my older brother's class complained angrily to the school about this, clearly having failed to realise it was satire.

Here's an excerpt:

"I have been assured by a very knowing American of my acquaintance in London, that a young healthy child well nursed, is, at a year old, a most delicious nourishing and wholesome food, whether stewed, roasted, baked, or boiled; and I make no doubt that it will equally serve in a fricasie, or a ragoust."

That's the problem with using "a modest proposal" for serious suggestions: you're supposed to use it for satire.
Wait, so is the op actually suggesting we be able to use commas? I thought op meant to say people who want to use commas are exactly like people who want to eat human babies to solve the problem of child poverty.
The second one. I read this as the author making fun of people who act like not having trailing commas is a situation so dire we may have to eat children.
>Wait, so is the op actually suggesting we be able to use commas?

Yes, I think they do.

The author just borrowed the title of Swift's article in the sense "here's a fun title based on a historical reference, for something that, for once, it's indeed a modest proposal".

They didn't intend it in the exact same way Swift intended it.

Well, the subtitle is "Let Me Put a Fucking Comma There, Goddamnit, JSON", and the argumentation is "for the love of all that is fucking holy", so I'd say the intention of the author of the proposal was not to make it look serious.
This isn't the only problem with JSON as a standard by a long shot[1]. Like Markdown and PHP its use has grown to the point where an extremely thoroughly reviewed reference implementation and test suite would make everybody's lives easier.

[1] http://seriot.ch/parsing_json.php

Json5 allows trailing commas. It also allows for comments, so definitely use json5 where you can
I would love to have trailing commas in JSON but I can see that being JSON something too widely extended over the internet it's not possible to do it for real as it will break all around. So, what I do is to have my editor to fix this issue as I'm completely unable to stop doing it :-)
Seems like a perfectly backwards-compatible change to me.
Personal plea is comments
Actually, in the JSON grammar as many others, the comma is completely irrelevant for the purposes of disambiguation. Commas could essentially be treated as whitespace and nothing would substantially change.

Now, I don't know whether commas allow for faster parsers in some way, but edn[1] seems to be doing just fine without them.

Once you get used to optional commas, it really becomes a nuisance having to type them, especially in basic data type lists. The only place where I find commas visually helpful is C-style argument lists (with type and value pairs), which JSON doesn't even use.

[1] https://github.com/edn-format/edn

> Actually, in the JSON grammar as many others, the comma is completely irrelevant for the purposes of disambiguation. Commas could essentially be treated as whitespace and nothing would substantially change.

A while ago I saw somebody who had implemented pretty much that: a streaming non-validating JSON parser which just ignored commas and colons entirely.

(comment deleted)
But I want to use eval() in IE8!!
Between commas and comments, I would personally vote for comments.

JSON is, unfortunately, used in many places as a configuration language (think package.json). Sometimes you have to comment out a section for some experiment. Many times, you want to explain why you included this or that in the config. Hence comments.

The trailing commas issue is slightly annoying, but an order of magnitude less important IMHO.

Why not both?
Protocol Buffer?
In protocol buffers, you don't have commas. Also comments go where they belong, in the schema ...
There is a damned good reason JSON does not allow comments. It's not an accident.
So can you fill the rest of us in on the reason then?
You can blame Crockford for that: [1]

TLDR: Basically, in a typical Crockford move, he saw people were using them in a specific way he did not like (to store parsing parameters), so he removed them entirely. I say "typical Crockford" because some of his JS linting rules are gratuitous overkill in my opinion. He also suggests that if you want comments, you should pipe the config file through a minifier that removes them before parsing.

Doesn't seem like that much of a good reason to me, but whatever.

1. https://plus.google.com/+DouglasCrockfordEsq/posts/RK8qyGVaG...

Yeah...that's frustrating. For a Chrome Extension manifest JSON file I was recently editing, you have to enter a description field that I found out is limited to around 100 characters after a failed upload. I wanted to add a comment above this field so myself and anyone else editing the file was aware of this in the future (a good use of comments in my opinion). I'm not going go through the hassle of a build step to do this. Programming languages allow comments for a reason and I don't see what's so different about JSON.
If the consuming program allows it, you can fake a comment by storing it as a JSON property value:

  { "myComment": "This is a comment!", "realValue": 1 }
That's what I did actually. I don't like it though. A comment is really saying "this is a note for the reader that isn't used at runtime". Putting a comment in as a value goes against that and it uses up memory when the file is read in.
On the flip side, I've always found it useful when debugging at a REPL to be able to read various kinds of metadata about objects, including documentation. Clojure is one example of this, but I wouldn't mind seeing it elsewhere as well.

https://clojure.org/reference/metadata

Hmm, so I'm thinking about cases where you have 10K objects and you wouldn't want the metadata duplicated and attached to all of those. Would that happen in Clojure?
I think he wanted it to be something different than js, hence the focus on strictly data exchange.

Why not use js for config instead of json? It's your app and your config so if you want it to look like json + comments + trailing comma you can. With so many options for config files like yaml, xml, heck even sqlite it does seem a bit silly how much json is used. Herd mentality.

Comments also are a bit tricky to preserve when programatically modifying data structures, so a destructive minifier approach makes sense. Although it's very Javascript, "let's make another utility you now need".

Crockford probably didn't think it would take off like it did, but with hindsight comments would have been the pragmatic choice IMO.

They tend not to survive roundtripping well, for example. JSON describes data; comments are metadata. To do them well you'd have to bring them into JSON infoset, such as it is.

(ETA: JSON already has problems with canonicalization. Adding comments makes this worse. Are they in or out of the equivalence over JSON terms?)

gotta love the hn community, downvoting things that are correct but hurt them feels
no, we downvote things that state an opinion as fact without even an attempt at explaining why, especially when done in a tone that is aggressive and disrespectful.
It's not an opinion however. JSON is a standard. Kinda worries me professionals use it without having a clue.
The reason why something did or didn't make it into a standard are definitely opinions. All sneak had to do was to provide a link to the "damned good reason."
That JSON has a "good reason" for disallowing comments is an opinion, it could be a popular, well-known and established opinion or it could be completely uninformed. To know the difference one must explain it.

Also standards change, and professionals use their tools in ways the original creators did not imagine a lot, that doesn't make them clueless. Heck, even JSON is a result of professionals misusing a programming language syntax for a serialization protocol.

Your opinion that all opinions must be explained up front was not explained up front.
Not liking comment macros is not a "damned good reason," it's just a reason. People could still do that in JSON anyway the same way they hack in comments - just add them as strings.
It may be used as such but it shouldn't be. YAML serves this purpose much better.

JSON works better as a language independent serialization format that is incidentally readable.

Yeah json is a fact of life, the fact yaml exists doesn't change that. Actually, toml is even better than yaml and yet...
TOML's array/table syntax is kind of confusing, especially when you're a few levels deep. Having meaningful whitespace in YAML makes it clearer.

It's also kind of messy when you have a lot of multiline strings.

Meaningful whitespace is horrid. I speak from 3.5 years of working on s project that exclusively used yaml as configuration. Yaml is horrid.

Toml is way better. Yes, multilayered objects in toml are ugly. Don't make your users created multilayered objects for their configuration. That's just a bad UX regardless of the language.

> Meaningful whitespace is horrid

Millions of Python programmers might disagree, not to mention that most programmers using languages with meaningless whitespace (as far as the computer is concerned) still put whitespace in there, because humans.

And it isn't like INI is a great experience, either. Flat configs suck in their own ways.

It's weird that a language with the mantra "explicit is better than implicit" has, as a core feature, braces implied by the negative space of the left-hand margin of a text editor.

>And it isn't like INI is a great experience, either. Flat configs suck in their own ways.

Yes, INI isn't great, but people who object to significant whitespace don't object to the "whitespace" part, they object to the "significant" part. That code could not compile or have scope errors because of one extra space or because a space replaced a tab just seems absurd to some people.

This is something about which reasonable people can disagree.

> It's weird that a language with the mantra "explicit is better than implicit"

The lack of braces enforces a certain style - something that can be found throughout Python. For example, the lack of multi-line lambda statements.

> braces implied by the negative space

It's easier to think of it in the same way that the compiler does: indent and dedent. Indent? Creating a new scope. Dedent? Exiting the current scope. All of the "constant 4 spaces" and "spaces instead of tabs" simply makes it easier for humans to interpret the indent and dedents visually.

In my experience in writing code in multiple languages: even when using braces you, the coder, still effectively require indentation to visually parse blocks. Yes, copying and pasting code is a touch harder, and most text editors are too lazy to parse for indents and dedents, but the first is mitigated by applying basic DRY principles, the second by installing a python-aware plugin.

The INI example is in response to "Don't make your users created multilayered objects". Personally, I cannot stand TOML, but there's no accounting for taste.

I think the significant whitespace is a pragmatism thing. If you're already doing it, do it consistently, if you're already doing it consistently do you really need brackets? The answer is no, and the added bonus is you (and everybody else) is forced to do the whitespace consistently. I'll take a consistently formatted codebase over inconsistencies any day!

XML was a fact of life in the 90s - inescapable.

Things can change. Push the world forward. Think of little things you can do that make the world of development the world you want to be in.

YAML can go off and die in a fire... especially because it cannot transfer the data type, which JSON can: you have either an integer, a float or a string. Also some libraries want the values escaped, some not, some barf on non-alphanumeric keys... JSON is pretty much standardized across the board.
I use YAML all the time (for config) and the things you mention have caused no more than one minute's frustration in my life. JSON is great for serialisation, YAML for little config files that need frequent hand-editing during development.
Yaml is terrible. The fact that there are so many optional and different ways to format things and the fact that it has significant white space means it's horrible to hand edit. I'd much rather hand edit json. At least it won't care if I accidentally use a tab instead of two spaces.

But of course toml is superior to both because it has comments and no significant white space and the comma at the end of lists is optional.

Here are some examples: https://github.com/cblp/yaml-sucks

TBH, common JSON implementations have their problems too. Integer size and integer/float (de-)serialization tend to be somewhat interesting at times. I've even seen implementations serializing JavaScript objects as JSON (e.g., {foo: 2} instead of {"foo": 2})

> you have either an integer, a float or a string.

JSON doesn't have "integers" and "floats", it has "numbers" which are are expressed in decimal scientific notation. There's no guarantee an implementation will let you distinguish what was parsed, and the numerical precision and range of interoperable JSON is undefined.

The bottom line is JSON is a risky proposition for financial or scientific data exchange.

And before you say JSON numbers are de-facto IEEE754 doubles, bare in mind that most JSON implementations can't roundtrip them properly.[0] A symptom of everybody wanting to write a toy implementation.

[0] https://rawgit.com/miloyip/nativejson-benchmark/master/sampl...

Lua tables are better than both, in my opinion. Simpler than JSON, allows for comments, and whitespace is not syntactically significant.
When I use JSON, I usually make sure that the parser supports trailing commas and comments, even if I have to add that myself. The reason is that I deal a lot with machine-generated but potentially user-edited JSON. Anything else is needlessly masochistic.

When producing JSON for others, I just use the minimal consensus format (read: the "official" spec).

I do the same, but instead of switching/patching the JSON parser, I replace it with a YAML one. YAML was designed to be a superset of JSON precisely so that it could be used as an upgrade path. It also allows comments and neat multiline string formatting (in addition to trailing commas).
That is a good option, but YAML is too complex for my taste, with the optional indentation based syntax. JSON + comments, like what sublime text uses for configs, is a sweet spot for me. If you know JS or Python, you can probably write it instinctively.
I just learned about cbor. Does cbor have this issue too?
Complainers in this thread might take a look at YAML
but "All I know is a hammer and it won't let me work this screw!"
People suggesting YAML might want to think long and hard about its horrible syntax issues, and why it didn't make it as the de facto serialization/config format as much as JSON did.
I'm surprised this got voted up considering how dismissive (and, frankly, mean) HN was to "JSON5" a few years back https://news.ycombinator.com/item?id=4031699

Trailing commas have been fine everywhere in JS since IE7 - it's about time all interpreters have this as an option, and preferably on by default.

Anyone looking for a “better JSON” night was well just move to YAML. Someone managed to make JSON5 the config format for something here and we wasted way too long before switching that over to YAML. Now we have a bunch of JSON5 with comments we’ve gotta manually transcribe.
Every YAML parser I've ever used has been literal magnitudes slower than the slowest JSON parser. It's way too flexible a format.

> YAML may seem ‘simple’ and ‘obvious’ at a glance, but it’s actually not. The YAML spec is 23,449 words; for comparison, TOML is 838 words, JSON is 1,969 words, and XML is 20,603 words.

https://arp242.net/weblog/yaml_probably_not_so_great_after_a...

If data is so big that parsing is a bottleneck, that seems like the wrong case for YAML. It's good for hand-edited and human-readable config files, and it's fast enough for that.
Hand-edited and human-readable? With significant whitespace and tab-space difference?
Human readability is exactly the point of significant whitespace. And I'm not sure how significant whitespace could even work without distinguishing between tabs and spaces, as a tab could represent any number of spaces.
You cannot indent yaml with spaces instead of tabs. This has been a source of confusion for years for many bukkit end-users.
Toml is far superior for hand editing. This is why yaml is terrible (aside from significant white space):

    foo: 80:80
    bar: 22:22
    baz: 22.22

What's the value of foo? It's the string "80:80". What's the value of baz? The float 22.22 What's the value of bar? The integer 1342.

I rest my case about both readability and writability.

> bar: 22:22

I know zero toml (don't even know what toml stands for) but I'm pretty sure you meant the value of bar is the string 22:22 based on foo.

I think he's attempting to point out a shortcoming of yaml; I can reproduce it myself in Python.

That said, I've never run up against this myself - in the face of potential ambiguity I attempt to be explicit, and surround it in quotes to be explicit string.

TOML itself is going through its own growth pains brought on by a rather sizable spec. For example:

    >>> pytoml.loads("foo = 20:20:20")
    [...]
    pytoml.core.TomlError: <string>(1, 9): msg
I agree that's a downside, but it almost never comes up in practice, and it's solved by syntax highlighting when it does. I'm always in a code editor when editing YAML, it's not something that goes down the wire and needs to be debugged without syntax colours. For config files it's fine. Maybe TOML is even better, I haven't used it. I'm just saying these problems raised about YAML have never really affected me and I use it all the time. For config only. JSON for data exchange.
If it's something you do thousand of times a second, like say a php app parsing a config it makes a HUGE difference. A number of PHP framework that use YAML config files actually cache the results in memcache because a network request is faster than parsing YAML from local disk.
If it's something you do thousands of times a second, then opening, reading, and parsing a config file is absolutely something you should be caching, no matter the implementation.
It's got a lot of bad features which should not really be used. The core is good though.
The problem with talking about 'cores', is I still have to parse and handle the entire language if I want to claim to support YAML.

I've used JSON is some constrained places, I can't imagine writing my own YAML parser, or hacking an existing one into a constrained place (no memory allocation for example).

First, JSON is not just used for config, and I've yet to find the an API to parse YAML in the browser natively.

Secondly, JSON is here and you have to deal with it everyday, so smoothing the work wouldn't hurt.

Finally, if you have to pick a format, take TOML. Less error prone than YAML, faster, and injecting executable code and shooting your in the foot is not part of the standard. The fact that a lot of ini files are valid toml is a nice bonus.

I cannot follow TOML at all. YAML is nice and obvious in the limited basically json subset I use whereas nested maps in TOML are a nightmare.
You can always parse using an eval. I guess it should work.

/me ducks.

Sigh.

Don't duck too much. This kind of config implementation is actually pretty common in some other languages. Clojure, for example. Most configuration files for Clojure programs are written in Clojure, and defended as such.

I also see it frequently done in Python and Ruby, given how simple they make it to dynamically import random files as modules. I've even watched a colleague rant about how they couldn't figure out how to do exactly this in Go.

Trailing commas are commonly allowed in the subset of JS that is JSON, but I believe most JSON parsing libraries disallow them.
Slightly related: I did some work on a format with really homogenous and canonical syntax that is also low-noise and human-editable. It's based on a relational representation, so also supports some integrity checks out of the box.

I also experimented with specification of transformations to/from hierarchical representations, but I think the problem is that there are different possible approaches with their own pros and cons.

http://jstimpfle.de/projects/wsl/main.html

http://jstimpfle.de/projects/python-wsl/main.html

Tell me what you think!

['not', 'my', 'cup', 'of', 'tea',].join(' ')
Is this only useful for code diffs, or am I missing something ?

Couldn't git take this into account to visually "depollute" diffs ?

personally i don't like dangling commas.
Me neither but it should be tolerated.
commas should just be treated as whitespace.
They’re version control friendly.
They are visually annoying and I'll trade that for minor visual annoyance while looking at diffs any day. I look at code far more often than I look at diffs.

On a related note I'd rather not have any commas like in EDN. All problems go away.

>They are visually annoying

That's a personal opinion -- like a mild OCD annoyance, etc, most like borne just out of being used to not having them from the start.

Their benefits on the other hand (uniform syntax, easier insertions/deletions, better for source code control, etc) are objective.

And there's no objective visual annoyance when looking at the code to see that it's uniformly comma-ed.

> personal opinion

I take it you didn't read my original comment?

Also I disagree, dangling comma is a visual cue that the sequence has a continuation.

>Also I disagree, dangling comma is a visual cue that the sequence has a continuation

We already have a mechanism for telling whether a sequence ends or not -- the opening and closing bracket for the sequence. No need to have a second redundant one.

This way the last element is an ordinary part of the sequence as any other and doesn't need a special exception to its formatting like the omission of the comma.

Besides the point is moot as the "dangling" comma is already part of the JS standard.

You're talking about syntactic rules, I'm talking about visual cues.

IMO there is no reason to have commas at all so this discussion is pointless.

>You're talking about syntactic rules, I'm talking about visual cues.

In what way is ] also not a visual cue?

In what world having multiple cues with opposite meanings is considered good?
In what world is the "," at the end of the final line an "opposite meaning" to ]?

Not on modern JS world, which allows for dangling , everywhere: http://2ality.com/2013/07/trailing-commas.html, so having a "," doesn't mean the line is not the last one anymore, just means "it's a line like any other".

It's time JSON gets up with the times -- especially since it's a totally backwards compatible improvement.

> it's a line like any other

yeah, in other words - there should be no commas whatsoever. Weren't you the one complaining about redundancy?

Good ol' S-expressions! I'll gladly stick with some extra parentheses (which can be easily made readable with consistently applied indentation) instead of these problems with commas and other rigid syntax issues.
Seeing as the vast majority of statements while coding aren't multiline, I wish there was a symbol to indicate that instead of a symbol to represent the end of a single line statement. I think Python has things right with the significant whitespace as well as it seriously reduces annoying errors caused by misbalanced brackets/braces.

Going further with this, I wish languages would be more copy/paste friendly. For example, in JavaScript I'll sometimes change code along the lines of

    a.x = 1;
    a.y = 2;
to

    a = {
        x: 1,
        y: 2
    };"
If you eliminate the commas, semicolons and changed the colons/equals to the same thing, you could copy/paste it with much less hassle.
> Seeing as the vast majority of statements while coding aren't multiline, I wish there was a symbol to indicate that

I dunno, that kind of exists in some bash/scripting contexts (using a backslash) and I've never enjoyed it.

Bash has horrific syntax but a huge amount of coding time is wasted because of unbalanced brackets/braces and forgotten end of line statements that result in unhelpful and confusing error messages so I like things that reduce this. Bash also has the quirk where variable assignments are of the form "var=1" but their usage is "$var" which always trips me up. I just like syntax that is easy to get right first time and is copy/paste friendly.
>I think Python has things right with the significant whitespace as well as it seriously reduces annoying errors caused by misbalanced brackets/braces.

You still get errors caused by mis-indented statements which are almost just as hard to check (if the indent continues for 10-15 lines and is nested etc).

And because of allowing to mix tabs and spaces, you also get other issues.

I think go had the best idea in this with gofmt: all code should be auto-formatted absolutely the same -- then it becomes trivial to read.

> You still get errors caused by mis-indented statements which are almost just as hard to check (if the indent continues for 10-15 lines and is nested etc).

I find wrong indents miles easier to see than unbalanced brackets/braces though. A single bracket/brace is only one symbol so it's hard to spot but it completely changes the semantics (see Apple's goto fail error).

> I think go had the best idea in this with gofmt: all code should be auto-formatted absolutely the same -- then it becomes trivial to read.

Yes, I like this. There's so many pointless arguments about things to do with naming conventions and tabs vs spaces...just make it part of the language so people can argue about more important topics.

goto fail was caused by a failure to use braces at all - ironically, it seems, for the same aesthetic reasons that significant whitespace is used, because it seems "cleaner."

Had braces been used, the error might have been easier to spot or might not have happened at all.

Significant whitespace forces the look of the code and the meaning of the code together to prevent mistakes like that though. It's really silly that indenting code within a condition is a universal code formatting convention but it's not enforced by the compiler. I can't think of any exceptions where you wouldn't want to indent code like that and it's obvious badly indented code can be misleading so I don't see why a compiler shouldn't pick that up for you.
The conventions around whitespace and code formatting are not universal, and the problem is once the compiler has to care about whitespace, it's no longer whitespace, it's code.

Code has to be correct in ways whitespace doesn't. Some people use tabs, some people use spaces. Some people even use both. In terms of whitespace, it doesn't really matter.

But, if your language cares which of the visually indistinguishable but otherwise incompatible kinds of non-printing characters you're formatting your code with, then it can still fail while visually communicating the correct information to the reader.

> The conventions around whitespace and code formatting are not universal

How is it not though? For every mainstream language it's standard convention to indent conditions and functions.

> But, if your language cares which of the visually indistinguishable but otherwise incompatible kinds of non-printing characters you're formatting your code with, then it can still fail while visually communicating the correct information to the reader.

This a complete non-issue to me. The pros of significant whitespace vastly overshadow any possible benefit of letting people choose tabs vs spaces and the latter issue is easily solved with IDEs anyway. I don't see people having any issues with this using Python either.

Personally, I think even naming conventions should be enforced by the language as well so people can stop wasting time debating insignificant details and in code reviews.

>goto fail was caused by a failure to use braces at all - ironically, it seems, for the same aesthetic reasons that significant whitespace is used, because it seems "cleaner."

In Python's case it's not just an aesthetic -- the whitespace is also functional, so that mistake can't happen just for aesthetics.

I vaguely recall some PL research that used the dot as a scoping operator, you could write object.(expression) and all fields of the object were automatically in scope within the expression. Your example would look like

    a.(
      x = 1;
      y = 2;
    )