Decimal comparisons

Sam Ruby rubys at intertwingly.net
Fri Sep 19 05:45:44 PDT 2008


On Fri, Sep 19, 2008 at 2:29 AM, Brendan Eich <brendan at mozilla.org> wrote:
> On Sep 18, 2008, at 10:58 PM, Kris Zyp wrote:
>
>>>> * Like Crock, I prefer that typeof 1m === 'number'. However, unlike
>>>> Crock's
>>>> and Brendan's agreement, I think this should be unconditional. I
>>>> think it
>>>> would be horrible for 'typeof X' to depend not only on the value
>>>> of X but
>>>> also on the mode of the program unit in which the typeof appears.
>>>> Please
>>>> don't do that.
>>
>> +1 for typeof 1m === 'number'. As an example of breakage, I believe
>> Crockford's current version of his JSON library would not do as I
>> would
>> desire with decimals:
>>
>> JSON.stringify({foo:1m}) -> "{\"foo\":undefined}"

I'm not sure which library is Crockford's but trying the one on
json.org produces the following:

js> load('json2.js')
js> JSON.stringify({foo:1m})
{}
js> JSON.stringify([1,2m,3])
[1,null,3]

> Why is that worse than producing '{"foo":1}'? Consider 1.1m instead
> of 1m.
>
> JSON does not provide for decimal, and receiver-makes-it-wrong is a
> bug. JSON would need to be extended to handle decimal reliably.

Given that JSON is slated for 3.1, and Decimal is slated for no
earlier than 3.1; we need to turn that into questions...

1) What should JSON.stringify([1.1m]) produce?

  * [1.1]
  * ["1.1"]
  * ["1.1m"]
  * [1.1E0]

2) What should 1.2m-JSON.parse("[1.1]")[0] produce?

  * 0.099999999999999911182158029987477
  * 0.1

The motivation for the fourth choice on the first question is to
produce a value that is is valid JSON, is unlikely to be widely used
today (by virtue of the capital E), will fall back to binary 64 many
JSON implementations, and can be used as a signal to produce a decimal
value in ECMAScript.  I'm merely putting this forward as brainstorming
at this point, I'm less than enthusiastic about it myself.

As a possibly related aside, I think we need to more precisely specify
how ECMAScript will handle dates in JSON.

>> I think there is a may be a lot of code that is dependent on typeof
>> returning a one of exactly six possible values.
>
> There may be "a lot". There's probably some. But there's also
> probably some code that breaks if decimals are added and they have
> "number" typeof-type. There is no non-breaking way to add decimal.

Brief summary, wildly overstating a number of points omitting a *lot*
of important details so that we can focus on the bigger issues:

number: "===" would no longer is a reasonable proxy for object identity

decimal: code that does not handle new types won't handle decimal

object: null is no longer the only object value that is false

Key questions:

Can we live with (typeof 1.5 == typeof 1.5m) && (1.5 !== 1.5m) being true?

Can we live with (1.5===1.5m) && (1.5/10 !== 1.5m/10)  being true?

Can we live with !(0.0m) being false?

Can we live with?  !(0.0m) && (0.0m !== null) being true?

Does the committee feel that it can ever add new values to typeof
under any circumstances?

If the answer is no to all of the above, then decimal (nor any other
similar data type) can never be added to the language.

FWIW, my preference is (in order): decimal, object, then number.

I think it is preposterous to assume that ECMAScript can never add any
new data types.  The version of JSON that is included in the language
will be aware of the data types supported in that edition of
ECMAScript.  What json2.js does for decimal, it does for any object
data type that it doesn't understand.

As far as what the builtin JSON functionality slated for ECMAScript
3.1 does when parsing "[1.1]", a case could be made that producing
[1.1m] is the closest to the expressing what the data structure
actually conveys, is readily convertible to binary 64 floating point
when needed, and typical JSON isn't anywhere near as performance
critical as vector graphic intensive functions are.

> /be

- Sam Ruby


More information about the Es-discuss mailing list