Instantly share code, notes, and snippets.

# Implicit integers for JavaScript

This proposal is an alternative to “Integer: Arbitrary precision integers in JavaScript” by Daniel Ehrenberg, but it also builds on his work.

Everything mentioned here is work in progress. It is not sure that these ideas will work out:

• They may break the web.
• They may turn out to be too complicated/user-unfriendly.

## Rationale

The current proposal for Integers with arbitrary precisions has pros and cons:

• Pros: It is very clean and paves the way for more operator overloading and user-definable value types in the future.
• Cons: It is only partially backward-compatible. The already existing implicit “small integers” (incl. array indices, Array#entries(), Array#forEach(), etc.) clash with the new “big integers”.
• That is, you can’t tell developers: “Use Integers whenever you can.”
• Instead, best practices are: “Use Numbers for up to 53-bit ints. Use Integers if you need more bits.”

This proposal sketches an alternative approach. It has different pros and cons.

## Number is a supertype of Int and Double

Number is a supertype of Int and Double: Number = Int ∪ Double

• Double:
• `typeof 123.0 === 'number'`
• `Number.isDouble(123.0) === true`
• Converting to Double: `Number.asDouble()`
• Int:
• `typeof 123 === 'number'`
• `Number.isInt(123) === true`
• `Number.isInt(0xFF) === true`
• Converting to Int: `Number.asInt()`

More tool functions:

• `Number.parseInt() : Int` (new signature)
• `Number.asUintN(width, theInt)` (works as described in Dan’s proposal)
• `Number.asIntN(width, theInt)` (works as described in Dan’s proposal)

### Binary operators

Existing binary operators for numbers are overloaded:

• `+`, `-`
• `*`, `/`, `%`, `**`
• `<<`, `>>`, `>>>`

Signature:

• Signatures where results are Double:
• Int × Double → Double (via coercion)
• Double × Int → Double (via coercion)
• Double × Double → Double
• Signature where the result has arbitrary precision:
• Int × Int → Int (all operators except `/`, see below)

Additionally, new Int-only operators (signature: Int×Int→Int) are introduced:

• Integer division: `div`
• Normal division must produce non-integer values, e.g. for `1/2`
• Bitwise operators: `band`, `bor`, `bxor`
• Shift operators: `shl`, `shr`

Open question: Will `+` and `*` having more precision for Ints break code on the web? For example:

• Currently: `9007199254740992 + 1 === 9007199254740992`
• With this proposal: `9007199254740992 + 1 === 9007199254740993`

### Equality

• With this proposal, `===` has to coerce if a Double has no decimal fraction: `1.0 === 1`

### Bitwise operators

The results of bitwise operators stay within 32 bits and are of type Int.

### Unary operators

• Unary `+` must coerce to Double, because, among others, asm.js depends on it.
• Unary `-`: it is unclear how this operator can be made to work for Ints (which only have a single zero), given that:
• `Object.is(-0, 0) === false`

## Open questions

• Int operators: coerce or throw exception if operand types are wrong?
• Naming: Int makes most sense, given `Number.isInteger()` etc.

## Various thoughts

• Static type checking tools could warn if the operands of a numeric operator mix numbers and integers.
• JSON would automatically get big integer values (more than 53 bits).

 Deciding that `1` is now an integer is a backwards-incompatible change. Code could expect two integers being multiplied to end up being a truncated float.