Revisiting Decimal

Brendan Eich brendan at mozilla.com
Wed Jan 14 22:36:21 PST 2009


On Jan 14, 2009, at 9:32 PM, Kris Zyp wrote:

> Of course, there is no decimal support in ES3, there is no other  
> option.

This is not strictly true:

http://code.google.com/p/gwt-math/source/browse/trunk/gwt-math/js_originals/bigdecimal.js

The point is that JSON peers that do math on numbers, to interoperate  
in general, need to parse and stringify to the same number type. It  
may be ok if only ints that fit in a double are used by a particular  
application or widget, but the syntax allows for fraction and  
exponent, which begs representation-type precision and radix questions.

> One of the major incentives for JSON is that it is interoperability
> between languages. If other implementations in other languages treat
> JSON's number as decimal than the assertion that I understood you were
> making that JSON number's are being universally expected to be treated
> as binary is not true.

It's probably a mix, with application-dependent restrictions on domain  
and/or computation so that using either double or decimal works, or  
else buggy lack of such restrictions.


>> JSON's numbers are decimal, languages that support decimals agree.
>> Dojo _will_ convert JS decimal's to JSON numbers regardless of what
>> path ES-Harmony takes with typeof, whether it requires a code
>> change or not.
>>
>>> That will break interoperatability between current
>>> implementations that use doubles not decimals.
>>
> How so? And how did all the implementations that use decimals to
> interpret JSON numbers not break interoperability?

Not necessarily. But correctness is not a matter of hopes or  
percentages. It may be fine for JSON to leave it to the app to choose  
number type and/or operations done on the data. But  some layer has to  
care. Some apps probably already depend on json2.js and json.js and  
the like (ES3.1's JSON built-in) using double, not decimal. Changing a  
future JSON codec to use decimal instead of double is not a backward- 
compatible change.


> So you are suggesting that we shouldn't let users pass mix of decimals
> and numbers even if they explicitly attempt to do so?

No, I'm suggesting unintended mixed-mode bugs will be common if we  
make typeof 1.1m == "number".


> It's not beside my point. If signficantly more real world code will
> break due to violating the expected invariant of a constant finite set
> of typeof results (and the expectation that numbers regardless of
> precision will be typeof -> "number") than those that break due to
> violating the expected invariant of typeof x == typeof x => (x == y
> <=> x === y)

We can't measure this, realistically, but again: the breakage from a  
new typeof result is not dependent on the numeric value of the  
operand, and entails either a missing case, or a possibly insufficient  
default case, while the breakage from your proposal is subtly data- 
dependent.

Plus, the invariant (while not holy writ) is an important property of  
JS to conserve, all else equal.


> than I think we would be negligent as language designers
> to ignore that consideration.

It's not a consideration if it can't be quantified, and if it  
introduces value-dependent numeric bugs. Decimal and double are  
different enough that typeof should tell the truth. 1.1m != 1.1, 1.2m ! 
= 1.2, but 1.5m == 1.5.


> I understand the logical concerns, but I
> would love to see real empirical evidence that contradicts my  
> suspicions.

I gave some already, you didn't reply. Here's one, about dojotoolkit/ 
dojo/parser.js:

"But if typeof 1.1m == "number", then str2obj around line 52 might  
incorrectly call Number on a decimal string literal that does not  
convert to double (which Number must do, for backward  
compatibility), ...."

It won't do to assume your proposal saves effort and demand me to  
prove you wrong. First, no one has access to all the extant typeof x  
== "number" code to do the analysis and prove the majority of such  
code would "work" with your proposal. This is akin to proving a  
negative. Second, I've given evidence based on Dojo that shows  
incompatibility if typeof 1.1m == "number".

How about we talk about an alternative: "use decimal" as a way to make  
all literals, operators, and built-ins decimal never double?

The problem with this "big red switch" is that it requires conversion  
from outside the lexical scope in which the pragma is enabled, since  
code outside could easily pass double data into functions or variables  
in the pragma's scope. It requires a decimal-based suite of Math,  
etc., built-ins too, but that may be ok (it was contemplated for ES4).

The problem with this old idea is really the challenge of ensuring  
conversion when cross the pragma's lexical scope boundary. Presumably  
double numbers going in would convert to decimal, while decimals  
flowing out would remain decimal. Even this is questionable: what if  
the callee was compiled without "use decimal" and it's another window  
object's function that expects a double-number?

/be


More information about the Es-discuss mailing list