Revisiting Decimal
Brendan Eich
brendan at mozilla.com
Wed Jan 14 19:24:29 PST 2009
On Jan 14, 2009, at 4:44 PM, Kris Zyp wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> Brendan Eich wrote:
>> On Jan 9, 2009, at 3:08 PM, Kris Zyp wrote:
>>>> The counter-argument is strong:
>>>>
>>>> typeof x == typeof y => (x == y <=> x === y)
>>>>
>>>> but 1.1 != 1.1m for fundamental reasons.
>>> I understand the counter-argument, but with such an overwhelming
>>> number of typeof uses having far easier migration with "number",
>>
>> Migration how? You'll have to change something to "use decimal" or
>> s/1.1/1.1m/. Only once you do that can you be sure about all
>> operands being decimal.
>>
> And I am sure our users will do that and pass decimals into our
> library functions.
I'm not disputing that. Straw man?
>> I'm assuming it would be "bad" in the Dojo code you've looked at if
>> 1.1 came in from some standard library that returns doubles, and was
>> tested against 1.1m via == or === with false result, where previous
>> to decimal being added, the result would be true.
> I am not aware of any situations in the Dojo codebase where this would
> cause a problem. I can't think of any place where we use an
> equivalence test and users would expect that decimal behave in the
> same way as a double. Do you have any expected pitfalls that I could
> look for in Dojo?
Sure, starting with JSON (see below).
>>> I can't possibly see how the desire to preserve this property is
>>> more
>>> important than better usability for the majority use cases.
>>
>> You really need to show some of these use cases from Dojo. I have a
>> hard time believing you've ruled out mixed-mode accidents.
> Ok, sounds good, I will be glad to be corrected if I misunderstanding
> this. Here are some of the places where I believe we would probably
> add extra code to handle the case of typeof checks where decimal
> values may have been passed in by users, and we would want the
> behavior to be the same as a number:
> As I have mentioned before, we would need to change our JSON
> serializer to handle "decimal":
> http://archive.dojotoolkit.org/nightly/dojotoolkit/dojo/_base/json.js
> (line 118)
You need to change this in any case, since even though the JSON RFC
allows arbitrary precision decimal literals, real-world decoders only
decode into IEEE doubles. You'd have to encode decimals as strings and
decode them using domain-specific (JSON schema based) type knowledge.
> Our parser function would need to add support for "decimal"
> http://archive.dojotoolkit.org/nightly/dojotoolkit/dojo/parser.js
> (line 32)
You're right, this parser would need to be extended. But if typeof
1.1m == "number", then str2ob 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), or else return a
double NaN (not the same as a decimal NaN, although it's hard to tell
-- maybe impossible?).
It seems to me you are assuming that decimal and double convert to and
from string equivalently. This is false.
> Matrix math handling for our graphics module:
> http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx/matrix.js
> (line 88 is one example)
I couldn't be sure, but by grepping for \.xx and \.yy I think I saw
only generic arithmetic operators and no mode mixing, so you're
probably right that this code would work if typeof 1.1m == "number".
Someone should take a closer look:
:g/\.xx/p
this.xx = this.yy = arg;
matrix.xx = l.xx * r.xx + l.xy * r.yx;
matrix.xy = l.xx * r.xy + l.xy * r.yy;
matrix.yx = l.yx * r.xx + l.yy * r.yx;
matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
D = M.xx * M.yy - M.xy * M.yx,
yx: -M.yx/D, yy: M.xx/D,
dy: (M.yx * M.dx - M.xx * M.dy) / D
return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y:
matrix.yx * x + matrix.yy * y +
matrix.dy}; // dojox.gfx.Point
M.xx = l.xx * r.xx + l.xy * r.yx;
M.xy = l.xx * r.xy + l.xy * r.yy;
M.yx = l.yx * r.xx + l.yy * r.yx;
M.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
:g/\.yy/p
this.xx = this.yy = arg;
matrix.xy = l.xx * r.xy + l.xy * r.yy;
matrix.yx = l.yx * r.xx + l.yy * r.yx;
matrix.yy = l.yx * r.xy + l.yy * r.yy;
matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
D = M.xx * M.yy - M.xy * M.yx,
xx: M.yy/D, xy: -M.xy/D,
dx: (M.xy * M.dy - M.yy * M.dx) / D,
return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y:
matrix.yx * x + matrix.yy * y +
matrix.dy}; // dojox.gfx.Point
M.xy = l.xx * r.xy + l.xy * r.yy;
M.yx = l.yx * r.xx + l.yy * r.yx;
M.yy = l.yx * r.xy + l.yy * r.yy;
M.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
I did not look at other files.
> Actually there are numerous situations in the graphics packages where
> a decimal should be acceptable for defining coordinates, scaling,
> etc.:
> http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx/
Only if never compared to a double. How do you prevent this?
> Charting also has a number of places where decimals should be an
> acceptable form of a number:
> http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/
> For example:
> http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/action2d/Magnify.js
> (line 22)
I will look at these later as time allows, pending replies on above
points.
> Again, I understand there are difficulties with typeof 1.1m returning
> "number", but in practice it seems we would experience far more pain
> with "decimal".
Trouble for you Dojo maintainers but savings for users. You may have
to do a bit more work to avoid imposing bugs on your users. That's
life in the big Dojo city.
/be
>
>
> - --
> Kris Zyp
> SitePen
> (503) 806-1841
> http://sitepen.com
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkluhukACgkQ9VpNnHc4zAyaLgCeLbJeVvoLd1ypvK9uiyfO0Jhw
> RuEAoKNZQeBKKfHzoupEdY+Nv16Lk+ch
> =pV7U
> -----END PGP SIGNATURE-----
>
More information about the Es-discuss
mailing list