| 14 Aug 2025 |
WeetHet | @raitobezarius:matrix.org please review https://gerrit.lix.systems/c/lix/+/3862 | 15:29:28 |
piegames | In reply to @emilazy:matrix.org IOW, the nlohmann_json semantics are "we try to find an integer type we can fit a literal into, and otherwise we produce a float" Thanks, I hate it | 15:34:14 |
emily | well, blame JavaScript :) | 15:34:30 |
emily | (and JSON for not specifying any goddamn semantics at all at first) | 15:34:35 |
piegames | Tbh if a library does untyped bullshit like that, I preferably want it out of my sight | 15:34:47 |
emily | no, this is just JSON | 15:34:58 |
emily | JSON has only one numeric type, because JavaScript does | 15:35:05 |
emily | its type is even vaguer than JavaScript's however | 15:35:09 |
emily | I don't have a strong opinion on "reject integer-looking things that are out of Nix integer range" vs. "always produce floats for things outside of Nix integer range"; both have their merits. the current state seems unjustifiable though | 15:35:36 |
Charles | i thought that JSON just didn't define any constraints on numeric types | 15:36:09 |
raitobezarius | In reply to @weethet:catgirl.cloud @raitobezarius:matrix.org please review https://gerrit.lix.systems/c/lix/+/3862 In ~ 5 days, yeah | 15:35:52 |
Charles | and left that as an implementation detail | 15:36:25 |
emily | it depends what you mean by "JSON". | 15:36:29 |
emily | the original terrible specification defines syntax and says basically nothing about semantics at all https://www.json.org/json-en.html | 15:36:45 |
emily | "A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used." | 15:36:51 |
Charles | lolsob | 15:36:56 |
emily | the latest RFC defines a single numeric type and says
This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754 binary64 (double precision) numbers [IEEE754] is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. A JSON number such as 1E400 or 3.141592653589793238462643383279 may indicate potential interoperability problems, since it suggests that the software that created it expects receiving software to have greater capabilities for numeric magnitude and precision than is widely available.
Note that when such software is used, numbers that are integers and are in the range [-(253)+1, (253)-1] are interoperable in the sense that implementations will agree exactly on their numeric values.
| 15:37:10 |
emily | * the latest RFC defines a single numeric type and says
This specification allows implementations to set limits on the range
and precision of numbers accepted. Since software that implements
IEEE 754 binary64 (double precision) numbers [IEEE754] is generally
available and widely used, good interoperability can be achieved by
implementations that expect no more precision or range than these
provide, in the sense that implementations will approximate JSON
numbers within the expected precision. A JSON number such as 1E400
or 3.141592653589793238462643383279 may indicate potential
interoperability problems, since it suggests that the software that
created it expects receiving software to have greater capabilities
for numeric magnitude and precision than is widely available.
Note that when such software is used, numbers that are integers and
are in the range [-(2**53)+1, (2**53)-1] are interoperable in the
sense that implementations will agree exactly on their numeric
values.
| 15:37:16 |
emily | there is an RFC that subsets it into an interoperable subset that IIRC they say that IETF specifications SHOULD use; I believe it limits the range to the interoperable subset | 15:37:39 |
emily | but I'd have to check | 15:37:42 |
emily | Nix could just always parse numeric literals in JSON into floats, but it would be annoying. (especially since Nixpkgs backs its integer-parsing functions by fromJSON) | 15:38:05 |
WeetHet | In reply to @raitobezarius:matrix.org In ~ 5 days, yeah Thanks | 15:38:15 |
emily | ok, I-JSON says
Software that implements IEEE 754-2008 binary64 (double precision)
numbers [IEEE754] is generally available and widely used.
Implementations that generate I-JSON messages cannot assume that
receiving implementations can process numeric values with greater
magnitude or precision than provided by those numbers. I-JSON
messages SHOULD NOT include numbers that express greater magnitude or
precision than an IEEE 754 double precision number provides, for
example, 1E400 or 3.141592653589793238462643383279.
An I-JSON sender cannot expect a receiver to treat an integer whose
absolute value is greater than 9007199254740991 (i.e., that is
outside the range [-(2**53)+1, (2**53)-1]) as an exact value.
For applications that require the exact interchange of numbers with
greater magnitude or precision, it is RECOMMENDED to encode them in
JSON string values. This requires that the receiving program
understand the intended semantic of the value. An example would be
64-bit integers, even though modern hardware can deal with them,
because of the limited scope of JavaScript numbers.
| 15:38:53 |
emily | ok, Nixpkgs does in fact detect the float case for integer conversions | 15:39:36 |
emily | so "fits into Nix integer → Nix integer, otherwise → float" would be desirable for Nixpkgs and consistent with other JSON implementations | 15:39:58 |
emily | "fits into Nix integer → Nix integer, otherwise → error" would be acceptable for that too, but less interoperable with other JSON implementations and weird per the spec | 15:40:28 |
emily | since adding a .0 isn't really meant to change a number by the specced JSON semantics | 15:40:39 |
emily | and indeed builtins.fromJSON "1.0" is 1 | 15:40:50 |
emily | oh wait 1.0 also prints as 1 | 15:41:01 |
emily | nix-repl> builtins.isInt (builtins.fromJSON "1.0")
false
ok never mind :)
| 15:41:12 |