Hacker News new | ask | show | jobs
by lfnoise 1762 days ago
Yes. I never understood why JSON over s-exprs. The absence of maps is not a negative. S-exprs can represent maps. There are no maps in JSON, really anyway. It is just text. How that data is represented in memory is the output of parsing. You could just as well parse (dict (a 1)(b 2)(c 3)) into a hash table if you wanted. You could also have sets (set 1 2 3) or whatever other data structure.
2 comments

You could do any of those things, but you have to pick a convention and other people have to agree on it.

JSON is nice in that it has just enough structure to do a good number of tasks in one obvious way. The biggest omission is probably some kind of time and/or date type (but ISO8601 in a string is the obvious solution there).

It’s not a coincidence that JSON was reverse-engineered from a language with convenient literals for dictionaries and arrays, and most languages provide those two collection types because they cover most use cases, so JSON fits most languages fairly well.

It’s just handy having both arrays and dictionaries available, rather than stretching one data structure to cover both, whatever Lua or Lisp might say.

You parse the s-exprs and execute them in the context of a namespace of data constructors. Then you can have whatever data structures in memory that are defined by the constructors. This is NOT equivalent to having one data structure to cover both as Lua does. It is having one text format that can construct any kind of data structure in memory for which you have constructors defined.
Okay, but we’re talking about a lingua franca for exchanging plain old data between different programs. You would have to pick your data constructors in advance.

I’m saying that arrays and maps give good bang for the buck, so you don’t really need to define anything beyond those. And if you accept that, having special syntax for arrays and maps is more convenient and readable than S-exprs.

> And if you accept that, having special syntax for arrays and maps is more convenient and readable than S-exprs.

S-expressions are arrays, and maps are really just degenerate unsorted arrays of key-value pairs. Taking a look at https://json.org/example.html, I think this is easily more readable:

    (menu
      (id file)
      (value File)
      (popup
        (item (value New) (onclick "CreateNewDoc()"))
        (item (value Open) (onclick "OpenDoc"))
        (item (value Close) (onclick "CloseDoc()"))))
than:

    {"menu": {
      "id": "file",
      "value": "File",
      "popup": {
        "menuitem": [
          {"value": "New", "onclick": "CreateNewDoc()"},
          {"value": "Open", "onclick": "OpenDoc()"},
          {"value": "Close", "onclick": "CloseDoc()"}
        ]
      }
    }}
Each to their own!

A big part of the difference is that all the JSON keys are quoted, which I agree is ugly (I like JSON5 myself).

You’ve also omitted the “menuitem” from the S-expr version. That could have been omitted from the JSON too but I assume it’s meant to be there for some good reason.

Fear of parentheses, basically.
But json already has quotes, commas, brackets and braces :-)
Yeah, apparently finding misplaced quotes, commas, brackets and braces is magically easier than misplaced parentheses. :)
You jest, but I find it easier to visually parse code organized using parentheses, quotes, commas, and brackets compared to code organized using parentheses, parentheses, parentheses, and parentheses. The latter approach is simple and elegant but makes it hard for me to read someone else's code.

I think the first reason is that the distinct characters provide a kind of visual checksum which makes me (slightly) more confident when initially matching a closing character to the correct starting character.

The second reason is that each character has a conventional meaning which makes it possible to form an initial guess as to its purpose.

Having said this, I freely admit this opinion may be colored by my only (paid) experience writing Lisp which was for a sprawling 20 year-old AI codebase mostly written by professors and graduate students who were often learning Lisp as they went.