Zulu-Inuoe / jzon

A correct and safe(er) JSON RFC 8259 reader/writer with sane defaults.
MIT License
151 stars 14 forks source link

Number types #1

Closed Zulu-Inuoe closed 3 years ago

Zulu-Inuoe commented 3 years ago

I want to establish reasonable rules when reading numbers from JSON.

In JavaScript, there is a singular number type (no distinction between Integers & Floats), but in CL we can have integers, floats, ratios, etc. Given the JSON is data coming from outside the application, a user of jzon should should write code such that it can work with any representation, performing coercions (eg truncate or float calls), but I think it's reasonable to be somewhat consistent in what's returned so that in the general case it 'Just Works'

Currently the logic is:

If the number contains no decimal mark nor exponent, it is an integer. Otherwise double-float

This is the same logic applied when interpreting number tokens in the standard CL reader.

But I don't know if it's reasonable to be a bit more clever about this, for example, maybe it's reasonable for the following to be integers?

  1. 5e6
  2. 5e0
  3. 4.2e1
  4. 40e-1

.. Or would those all be too surprising?

Valera commented 3 years ago

.. Or would those all be too surprising?

I think, it will. If data originates from some language with distinct integer and float types, json libraries for that language will keep integers and floats in distinct representation. For example, in Python:

>>> import json
>>> json.dumps({"foo": 1000000, "bar": 1e6})
'{"foo": 1000000, "bar": 1000000.0}'
>>> json.loads(_)
{'foo': 1000000, 'bar': 1000000.0}

I think its good to follow the same logic for loading the same type that were originally serialized in CL or some other language with distinct floats and ints.

Maybe parsing function could accept a list of fields to ensure their values are integers (or floats), but I think it is too narrow use-case.

Zulu-Inuoe commented 3 years ago

Thanks @Valera That's how I ended up implementing it, and in hindsight I agree, trying to do that sort of coercing is too surprising, so I'm going to leave it as is. In a followup version I will include doing value coercions which would include things like coercing floats into integers, and vice versa.

But that's a separate issue