JSON support for BigInt in ES6.

# Anders Rundgren (6 years ago)

For good or for worse I have written a proposal for tc39/proposal-bigint#162 available at cyberphone/es6-bigint-json-support#json-support-for-bigint-in-es6

Since the proposal doesn't introduce a default serialization mode, I guess nobody will be happy :-( OTOH, a fairly decent rationale for not specifying a default is also provided :-) This comment is also worth reading: tc39/proposal-bigint#162

# J Decker (6 years ago)

my primary usage of json is developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications#Using_JSON_to_transmit_objects

in which case JSON.parse( JSON.strinigfy( msg ) ) really needs to result in the same sort of thing as the input; although I guess dates do get lost in translation anyway, but they could be handled as numbers with a few more character exceptions ':','-'(in a number),'Z',' ' the last one (the space) complicating the whole thing immensely; there is no meaning of multiple numbers without a ',' between them in JSON, so maybe not so impossible.

and given the requirement that seems to be lost, that bigints ONLY interop with bigints, they MUST decode the same as their encoding; the JSONnumber type almost works; but requires custom code every time bigints are used. (much like dates)

what writing a JSON parser taught me, is the type of a variable is the type of the data it has; and JSON does a really good job of representing 99% of generally communicated types. which makes generic code quite easy... without having to respecify/recast the data, the data is already the type it is.

but there's certainly fewer of me, than of those that thing everything is perfectly fine, and shouldn't evolve as the langugage has. but then there's 'don't break the net' and 'this could certainy break the net'; but since bigints didn't exist before, I guess they shouldn't be added now, because sending them to old code would break the old code.... but actually since being added; should also update JSON to support that number type (although I guess base JSON doesn't suppose ES6 number encodings like 0x, 0b, etc...)

and again, since bigints ONLY interop with other bigints, there should be no chance they will get lost in interpretation.

can see JSONnumber can aid application handling; but if you send bigints to an application that doesn't support bigints it's not going to work anyway; so why not just let existing json.parse throw when it doens't have bigint support?

# Anders Rundgren (6 years ago)

On 2018-08-14 06:55, J Decker wrote:

my primary usage of json is developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications#Using_JSON_to_transmit_objects

in which case JSON.parse( JSON.strinigfy( msg ) ) really needs to result in the same sort of thing as the input; although I guess dates do get lost in translation anyway, but they could be handled as numbers with a few more character exceptions ':','-'(in a number),'Z',' ' the last one (the space) complicating the whole thing immensely; there is no meaning of multiple numbers without a ',' between them in JSON, so maybe not so impossible.

and given the requirement that seems to be lost, that bigints ONLY interop with bigints, they MUST decode the same as their encoding; the JSONnumber type almost works; but requires custom code every time bigints are used. (much like dates)

what writing a JSON parser taught me, is the type of a variable is the type of the data it has; and JSON does a really good job of representing 99% of generally communicated types. which makes generic code quite easy... without having to respecify/recast the data, the data is already the type it is.

Since the JSON standard doesn't distinguish between a single bit or BigNumber, I guess you are proposing extensions to JSON?

but there's certainly fewer of me, than of those that thing everything is perfectly fine, and shouldn't evolve as the langugage has. but then there's 'don't break the net' and 'this could certainy break the net'; but since bigints didn't exist before, I guess they shouldn't be added now, because sending them to old code would break  the old code.... but actually since being added; should also update JSON to support that number type (although I guess base JSON doesn't suppose ES6 number encodings like 0x, 0b, etc...)

and again, since bigints ONLY interop with other bigints, there should be no chance they will get lost in interpretation.

can see JSONnumber can aid application handling; but if you send bigints to an application that doesn't support bigints it's not going to work anyway; so why not just let existing json.parse throw when it doens't have bigint support?

The proposal is targeting cross-platform applications using JSON. The only thing it adds is offering a way to use JSON Number formatting for new numeric types, in addition to the quoting schemes which already are fully supported (and extensively used as well).

Example: A java class element like BigInteger big; used in a JSON context presumes that all values targeting "big" should be treated as BigIntger (=BigInt). However, there are different practices for formatting BigIntegers in JSON and they are all "right" :-)

In essence, the proposal's only ambition is making the ES6 JSON object better aligned with an already established JSON reality.

Anders

# Michał Wadas (6 years ago)

Personally, I would like to see:

  • third argument to JSON.parse reviver, "raw string"
  • new class JSON.Fragment accepting any syntactically valid JSON in constructor (eg. new JSON.Fragment('99999999999999999')
  • returning JSON.Fragment from JSON.stringify would paste it as-it-is into string output

This should cover any Bigint use case without breaking backward compatibility.

# Anders Rundgren (6 years ago)

On 2018-08-14 15:34, Michał Wadas wrote:

Personally, I would like to see:

  • third argument to JSON.parse reviver, "raw string"
  • new class JSON.Fragment accepting any syntactically valid JSON in constructor (eg. new JSON.Fragment('99999999999999999')
  • returning JSON.Fragment from JSON.stringify would paste it as-it-is into string output

This should cover any Bigint use case without breaking backward compatibility.

Would it be possible adding a little bit more meat to this? I didn't understand the "raw string" part :-(

JSON.Fragment seems like a more universalized version of JSONNumber.

BTW, my proposal is in fact designed to be 100% backward compatible.

Anders

# Michael Theriot (6 years ago)

I've been brainstorming a few days and this is the same idea I reached. I just wasn't sure if returning some kind of special object (JSON.Fragment) was a good way to handle stringify.

Elaborating, basically a third argument would come back in JSON.parse reviver method, which is the actual string that was parsed (not the parsed value). When stringifying, a JSON.Fragment would not get parsed but inserts the underlying string value (which must be valid JSON).

JSON.Fragment would just be a way to use valid, raw strings in JSON. E.g. JSON.stringify([0]) === JSON.stringify(JSON.Fragment("[0]")

# Isiah Meadows (6 years ago)

I like the idea, but I don't feel it's quite as simple as as just adding an option for serializing BigInts/numbers as explicit integers/floats.


Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# Anders Rundgren (6 years ago)

On 2018-08-14 20:30, Michael Theriot wrote:

I've been brainstorming a few days and this is the same idea I reached. I just wasn't sure if returning some kind of special object (JSON.Fragment) was a good way to handle stringify.

Since we now are three who have the same (basic) idea it can't be all bad :-)

Elaborating, basically a third argument would come back in JSON.parse reviver method, which is the actual string that was > parsed (not the parsed value).

Indeed, this exactly what my proposal suggests: cyberphone/es6-bigint-json-support#22-rfc-mode-deserialization

The only difference is that my proposal is dedicated to JSON Number while Michal suggest JSON fragments. The JSONNumber object can due to this restriction support additional number-related methods aiding the parsing process: cyberphone/es6-bigint-json-support#223-syntax-checking-deserialization

Since the only non-conformant part of the JSON object actually is JSON Number, it seems like a dedicated solution would be more appropriate.

Anders

When stringifying, a JSON.Fragment would not get parsed but inserts the underlying string value (which must be valid JSON).