Hacker News new | ask | show | jobs
by kybernetikos 1722 days ago
I think allowing a whitelisted set of constructors (so it's extensible, but with some standard ones) as types in a future JSON-like could be good. e.g.

   { 
      birthdayParty: Date(1632817436514),
      sounds: Map([["cow", "moo"], ["fox", "?"]]),
      possibilities: Set(["she loves me", "she loves me not"]),
      aSymbol: Symbol("tag"),
      aBuffer: UInt8Array(ArrayBuffer([104, 101, 108, 108, 111])),
   }
      
So you'd do something like

   const serialised = NuJSON.stringify(data)
   const result = NuJSON.parse(serialised, allowedConstructors, fallbackConstructor)
And if allowedConstructors wasn't present, it'd default to including all the standard JS ones (Map,Set,Date,Symbol,ArrayBuffer etc). The fallback constructor would be used if there were data types in the data that didn't have matching allowed constructors. By default it would through an error.

Of course, my ideal NuJSON would also include bigints, multiline strings, comments, bare keys (i.e. without having to wrap them in quotes).

Stretch nuJSON would also include the ability to serialise circular graph structures, perhaps through the use of a Reference([up, up, "aSymbol"]) data type.

1 comments

I know this is how Javascript is done nowadays but using constructors for maps and arrays just seems like unnecessary syntax to me. And if you're going to initialize an array buffer too, you might as well just not use JSON at all and send plain Javascript code over the wire.

I think all JSON needs in this regard is type hinting. Let everything else be handled by the application:

    {
      birthdayParty: Date 1632817436514,
      sounds: String? { // zomgwtfbbq comments too 
          cow:"moo",
          fox: null 
      },
      possibilities: ["she loves me", "she loves me not", 42],
      aSymbol: Symbol "tag",
      aBuffer: Uint8 [104, 101, 108, 108, 111]
    }
I think the main difference between my suggestion and yours is that mine has more brackets. I think type hinting and 'constructors' are basically the same thing, but I like the types to be extensible, so even in your version, I'd make the type hints things that could be provided into the NuJSON.parse function.

Obviously, in your version my approach would be

    sounds: Map {
        cow: "moo",
        fox: null
    },
    possibilities: Set ["she loves me", "she loves me not", 42]
I suppose that the idea could be that type hints are entirely ignoreable, and if you strip them the file just becomes normal JSON?
I suppose my point was that you don't have to specify types for maps and sets at all (which I didn't do in my example,) the existing syntax already does that. [] is already a set, {} is already a map. Type hints would just be used for the values.

Sending type definitions seems like a good idea. Although at that point it might as well not even be called any kind of JSON.

I don't agree that you don't have to specify types for maps and sets. For example

    {true: "yes", false: "no"}
Is not valid JSON, but

    Map [[true, "yes"], [false, "no"]]
should be valid 'NuJSON'. Maps and Sets are semantically different to Objects and Arrays, and they are Javascript standard objects that should ideally be supported by the default serialisation. The other alternative of course is to force the deserialisation code to fix them up afterwards, but that is painful.

I want to be able to stringify records with Sets, Maps, Arrays and Objects in, and have that work, even if they have behavior not supported by objects and arrays, and I don't think the user should have to fix up the output after parsing of JSON containing standard javascript objects.