# Revisiting Decimal (generic algorithms)

Sam Ruby rubys at intertwingly.net
Fri Jan 16 17:54:17 PST 2009

```On Fri, Jan 16, 2009 at 8:30 PM, Brendan Eich <brendan at mozilla.com> wrote:
>
>> Like Allen says later, most small integers (i.e., the ones that fit
>> exactly in a double precision binary value) can simply be retained as
>> binary64.
>
> Or machine ints -- ALU >> FPU still.

Agreed.  Those values that could fit in int32 before could continue to do so.

>> I suspect that covers the majority of constants in deployed
>> javascript.  Now let's consider the rest.
>>
>> First, Allen's example:
>>
>> function fuzz(a) { return a + 0.1}
>>
>> Where fuzz(0.1)===0.2 and fuzz(0.1m)===0.2m
>>
>> The only way I can see that working is if the constant is initially in
>> a form that either is readily convertible to source, or stores both
>> values.  I don't understand how multimethods (on "+"?) affect this.
>> If I'm missing something, please let me know (or simply provide a
>> pointer to where I can educate myself).
>
> I did, see followup links to reading-lists, from which I'll pick a specific
>

I must be dense.  My previous understanding of multimethods was that
it depends on the assumption that the type of each argument can be
determined.  That article doesn't change that for me.

>> Continuing on, let's tweak this a bit.
>>
>> function fuzz(a) {var b=0.1; return a+b}
>>
>> I would suggest that if the expectation would be that this function
>> behaves the same as the previous one.
>

So, here's the problem.  At the point of the ';' in the above, what is
the result of typeof(b)?

The problem gets worse rapidly.  The above may seem to be appealing at
first, but it degenerates rapidly.  Consider:

function fuzz(a) {var b=0.05; var c=0.05; var d=b+c; return a+d}

Should this return the same results as the previous fuzz functions?
What is the value of typeof(d)?

>> My interpretation is that this means that internally there are three
>> data types, one that is double, one that is decimal, and one that
>> somehow manages to be both.  Internally in that this implementation
>> detail ideally should not be visible to the application programmer.
>> Again, I could be wrong (in the need for three data types, not on the
>> opinion that this should not be visible), but pressing on...
>
> No, Allen allowed for that, but of course this generic type has to propagate
> at runtime through variable and function abstraction.

I don't follow.

>> function is_point_one(a) {var b=0.1; return b===a}
>>
>> Is the expectation that this would return true for *both* 0.1 and
>> 0.1m?
>
> I don't see how this could work.

Before proceeding, let me simplify that:

function is_point_one(a) {return a===0.1}

The point of "fuzz" was that 0.1 as a literal would be interpreted as
a binary64 or as a decimal128 based on what it was combined with.  Why
would this example be any different?

>>  This leads to a rather odd place where it would be possible for
>> triple equals to not be transitive, i.e. a===b and b===c but not
>> a!===c.
>
> Er, a!==c ;-).
>
>>  That alone is enough to give me pause and question this
>> approach.
>
> Me too.
>
>> Continuing trip down this looking glass, what should typeof(0.1)
>> return?  You might come to a different conclusion, and again I might
>> be missing something obvious, but if these Schrödinger's catstants
>> (sorry for the bad pun) can be assigned to variable, then I would
>> assert that typeof(0.1) and typeof(0.1m) should both be 'number'.
>
> It should be clear that I won't go this far. My reply to Allen was gently
> suggesting that his suggestion would not fly on implementation efficiency
> grounds, but I think you've poked bigger holes. I'm still interested in
> multimethods, including for operators.

I don't see how this reasonably can be done half way.

And while multimethods are appealing for other reasons, I don't think
they relate to what Allen is suggesting.

- Sam Ruby
```