# Revisiting Decimal (generic algorithms)

David-Sarah Hopwood david.hopwood at industrial-designers.co.uk
Fri Jan 16 19:38:42 PST 2009

```Brendan Eich wrote:
> On Jan 16, 2009, at 5:30 PM, David-Sarah Hopwood wrote:
>> David-Sarah Hopwood wrote:
>>> function id(x) { return x; }
>>>
>>> What is the result and type of id(0.1) in this approach, and why?
>>
>> - if binary 0.1, then we would have
>>
>>     1m + 0.1 !== 1m + id(0.1)
>>
>>   which breaks referential transparency (in the absence of side-effects)
>>
>> - if decimal 0.1m, then we break compatibility with ES3.
>>
>> - if the value remains generic, then such values must be supported at
>>   run-time as a third numeric type besides number and decimal, which
>>   seems unsupportably complex to me.
>
> Agreed on all points.

A final nail in the coffin for the last (three-type) option above:

In ES3, the expression Number(0.1 + 0.1 + 0.1) would give
Number(0.1) + Number(0.1) + Number(0.1) ==
0.3000000000000000444089209850062616169452667236328125

In the three-type option, it would give
Number(0.3) ==
0.299999999999999988897769753748434595763683319091796875

(Decimal expansions are computed using SpiderMonkey's implementation
of toFixed. The point is simply that they are different.)

So the three-type option does not maintain compatibility, at least
if we are concerned with exact values.

It could be argued that most ES3.x programs are probably not relying
on the exact errors introduced by double-precision IEEE 754, but that
seems risky to me. By that argument, ignoring performance, you could
unconditionally implement all numbers as decimals, and I don't think
many people here would accept that as being compatible.

Compatibility could, in principle, be maintained by adding a third
kind of literal for generic values, with a different suffix. However,
I think it is likely that unless generic values used the suffix-free
numeric literal form, they would remain too rarely used to make any
difference to the issue that Allen is concerned about.

> Have you looked at multimethods in Cecil?

I've previously studied Cecil's multimethods and type system in
detail (it's very nicely designed IMHO), but I'm not sure that it
is what we need here. Multimethods address the problem of how to
concisely define type-dependent functions, but the implementations
of those functions still have to be given explicitly for each type
combination on which the behaviour differs (ignoring inheritance
and subtyping, which I don't think are relevant here).

To address the problem raised by Allen, you would probably want to
implicitly define implementations that used different types for
constants, depending on the argument types to a given function
(and it is not clear how that would work for mixed-type arguments).

In any case, I think we first need to decide what the semantics
would be *after* any desugaring of multimethods.

--
David-Sarah Hopwood
```