-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Normative: Make JSON.stringify(-0) preserve the sign
#1466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
7c76421 to
897f6c6
Compare
ljharb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change LGTM, but I think we'll also want web compat data, to ensure nobody's relying on this behavior.
JSON.stringify(-0) preserve the sign
Although JSON supports -0 per ECMA-404 and JSON.parse('-0') returns -0, JSON.stringify(-0) currently loses the sign, outputting just '0'.
This patch makes JSON.stringify(-0) return '-0' instead, so that the following holds:
Object.is(JSON.parse('-0'), -0);
// → true (this is already the case, even without this patch)
JSON.stringify(-0);
// → '-0'
Object.is(JSON.parse(JSON.stringify(-0)), -0);
// → true
Results in current JavaScript engines:
$ eshost -se 'Object.is(JSON.parse("-0"), -0)'
#### Chakra, JavaScriptCore, SpiderMonkey, V8
true
#### XS
false
$ eshost -se 'JSON.stringify(-0)'
#### Chakra, JavaScriptCore, SpiderMonkey, V8, XS
0
$ eshost -se 'Object.is(JSON.parse(JSON.stringify(-0)), -0)'
#### Chakra
true
#### JavaScriptCore, SpiderMonkey, V8, XS
false
897f6c6 to
69be071
Compare
|
Under the following assumption – which is reasonable in many situations, and for which the relevant subset of Number values is expected to represent exactly the corresponding mathematical abstract concept of ”integer”:
I expect that
and, you guess it:
More generally, the distinction between +0 and -0 is primarily an artefact of the internal representation of numbers; the distinction between the two values is irrelevant for most purposes, and therefore should not surface in situations where you possibly don’t expect it. |
JSON already surfaces it, though; it's just that |
Note that the case of |
|
I object to this PR and agree with @claudepache . This violates the original intent of the JSON.stringify design. It would at least need general consensus, and I doubt it would gain mine. |
|
Can you elaborate on the original intent of the |
|
Note that this discrepancy is not an innovation of |
|
Also, note that the ES5 JSON.stringify specification was derived from upon Crockford's json2.js package which used String() to produce the output for finite values of typeof "number". |
|
I agree with @erights here. We intentionally made |
|
@waldemarhorwat why was that decision originally made for number toString? |
|
I'll happily withdraw this PR since it is apparently working as intended. However, it'd be good to clearly document the history in this thread. I'll keep the PR open for now until someone provides that context. |
|
My sense of the rationale, without implying that all this was discussed explicitly, nor that there was general consensus on this rationale. The committee doesn't ask for consensus on rationale, just conclusions, on which we did agree. A program that does not otherwise need to care about the difference between -0 and 0 should, as much as possible, be able to ignore this difference while remaining correct. After all, -0 and 0 denote the same real number. This is why (over my objections at the time), Map and Set key comparison is insensitive to the difference between -0 and 0. The only places I am aware of where the programmer needs to be aware of the difference, if they do not otherwise care, is:
Most programs that do not otherwise care about the difference between -0 and 0 will also not care about the bullet points above. This is also a hazard, as these bullet points may violate the principle of least surprise. However, the first bullet is mandated by IEEE and ancient JS, necessitating the other bullets. Had |
|
@erights There is also What about the situations where somebody does care about the distinction between I can imagine a server/client exchanging messages, and that message might be So is the recommendation in that case to completely avoid It also seems odd that It also has implications for a client (written in JavaScript and using My opinion is that it's okay for JavaScript as a language to not care about |
Good point, thanks!
The decision was already made for String(-0) before my time. I am just trying to explain my sense of the rationale. Given the behavior of String(-0), I think the behavior of JSON.stringify(-0) must remain as is
Note that JSON also cannot directly represent https://github.com/Agoric/PlaygroundVat/blob/master/src/vat/webkey.js#L181 |
|
Closing now that the historical context has been clarified. Thanks, everyone! |
Although JSON supports
-0per ECMA-404 andJSON.parse('-0')returns-0,JSON.stringify(-0)currently loses the sign, outputting just'0'.This patch makes
JSON.stringify(-0)return'-0'instead, so that the following holds:Results in current JavaScript engines: