-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
JSON cannot be a subset of JavaScript #1681
Comments
FWIW, I put an array on the outside to avoid the issue that JSON is approximates a subset of the JavaScript expression grammar, which is distinct from any JavaScript start production. |
I feel like the "subset" part is about syntax, not runtime behaviour. |
If language X's syntax is a subset of language Y's syntax, but X and Y associate these with, say, completely different meanings, I would say only "X's syntax is a subset of language Y's syntax." A language consists of a lot more than syntax. |
This misunderstanding --- which I shared --- caused https://github.com/Agoric/SES/issues/147 We should avoid over-simplistic statements that lead people to write buggy programs. |
I wonder how often code actually uses Out of historical interest, is there a reason this syntax was not restricted to sloppy mode? At least for the quoted case? |
I don't recall ever considering making a strict / sloppy distinction here. Attn @allenwb Do you remember? |
Because TC39 decided that proto in an object literal was the de factor standard for declaratively setting its [[Prototype]] and there is no point in ever inventing some other syntax. Applies to both strict and sloppy. We potentially could have excluded recognizing stirng literal "proto" as special. But I don't think at the time anybody ever brought it up as a JSON subset issue. We did exclude computed property names. |
Is there any chance it would be web compatible to exclude the string literal form now, even if just in strict mode? |
given that the consistent quotes eslint rule exists, i'd assume it will break at least a few sites. |
FTR, the incorrect assumption that JSON is a subset of JS has led to implementation bug in some JS engine: https://bugzilla.mozilla.org/show_bug.cgi?id=1337564 |
Does the consistent quotes rule complain about {__proto__: ...} ? |
@erights i believe this the rule, includes examples https://eslint.org/docs/rules/quote-props#consistent |
proposal-json-superset was careful to describe the post-change language as a syntactic superset of JSON for precisely this reason. The semantic discrepancy was explicitly mentioned and survives in the definition of What would make that more clear? |
The problem does not come from what is said, but from what is not said. There is a note in the spec (precisely at the end of this section) stating that “valid JSON text” is a subset of ES PrimaryExpression syntax. It should be added that nevertheless, such a text, when interpreted by |
Let me take my crack at explaining this: JSON is a syntax for data interchange. See the title of its standard. That syntax is indeed (now) a small subset of ES PrimaryExpression. JSON has no intrinsic semantics. Various semantics can be imposed upon the JSON syntax by readers and writers of a valid "JSON text".
JavaScript programs are not required to use JSON is not "a subset of JavaScript" . It's semantics is not (uniquely) defined by |
@allenwb , while everything you say is true, we still have the hazard that I and others fell into, by remembering something simpler that is almost true. I still think we need the clarifying text that @claudepache proposes. |
@claudepache It should probably also be noted that the use of ES parse and evaluation semantics in steps 3 and 4 of JSON.parse is just a hack that I came up with to avoid having to write the specification of a complete JSON reader semantics. It was convenient to piggy-back on the the evaluation mechanisms that were already in the spec. The @erights If you want to clarify it in the spec I suggest incorporating the text I just wrote above as an informative note. I agree that experience suggests that people have to be continually wacked on the head to educate/remind them that |
Could you share a link to the meeting notes containing that decision, if you can find it, please? |
It sounds like we're looking at a communication problem, rather than any possible change to syntax or semantics of JavaScript or JSON. I wonder if we could work with devrel and educator-type folks to avoid these sorts of misunderstandings. cc @bkardell @mathiasbynens |
The nuance that JSON is only a syntactic subset of ECMAScript is important. As @gibson042 says, we took special care to mention this explicitly in the proposal's README and in V8's developer-facing documentation. We could still add the note that @claudepache mentioned in #1681 (comment) to the spec. |
How can we get parser in standard that is conforming with JSON specs in terms of being able to represent any JSON object? Is there a reason to fix standard instead of implementation? |
The primary (and maybe only) reason is backward compatibility. Implementations are not willing to remove the special handling of the |
Seems like to close this, we need a PR to add the note mentioned here: #1681 (comment) |
const a = { ["__proto__"]: 1 }; This will set the actual |
Other gotcha: Json allows any finite decimal number being re-presentable, but not in JS, becasue JS standard has limited way to represent decimal numbers as decimal numbers are bounded by precision. Large set of numbers that is representable in Json is not representable in Javascript trough standard Json parser. |
That isn't legal JSON, so no, it can't.
You may be interested in this proposal, which addresses precisely that. (Though it will still be true that there are numbers representable in JSON but not as either Numbers or BigInts in JavaScript.) |
In reforming the JavaScript treatment of \u2028 and \u2029, we frequently described the rationale as ensuring that JSON is a proper subset of JavaScript. Indeed, this brings it much closer. But we cannot repair the remaining discrepancy:
As JavaScript, this makes a singleton array whose element inherits from an empty array. As JSON, this makes a singleton array whose element inherits from
Object.prototype
and has an own data property named__proto__
whose value is an empty array.Because of this, JSON will forever only approximate a subset of JavaScript.
The text was updated successfully, but these errors were encountered: