1 of 10

BigInt / Number parameter overloading: Just Say No (?)

Daniel Ehrenberg

Igalia, in partnership with Bloomberg

January 2019 TC39

2 of 10

Background: How operators and BigInt work

-(3) ⇒ -3

-"5" ⇒ -5 // not -5n

-{valueOf() { return 5 }} ⇒ -5

-(3n) ⇒ -3n

-{valueOf() { return 5n }} ⇒ -5n

3 of 10

Overload functions as well? (ecma402#236)

let fmt = new Intl.NumberFormat("en");

fmt.format(3) ⇒ "3"

fmt.format("5") ⇒ "5"

fmt.format({valueOf() { return 5 }}) ⇒ "5"

fmt.format(3n) ⇒ "3" ???

fmt.format({valueOf() { return 5n }}) ⇒ "5" ???

4 of 10

I initially thought we should;

Now I suspect we shouldn't

5 of 10

Overload functions as well? (ecma402#236)

let fmt = new Intl.NumberFormat("en");

fmt.format(3) ⇒ "3"

fmt.format("5") ⇒ "5"

fmt.format({valueOf() { return 5 }}) ⇒ "5"

fmt.format(3n) ⇒ "3" ???

fmt.format({valueOf() { return 5n }}) ⇒ "5" ???

6 of 10

Give them a separate name! (ecma402#318)

let fmt = new Intl.NumberFormat("en");

fmt.format(3) ⇒ "3"

fmt.format("5") ⇒ "5"

fmt.format({valueOf() { return 5 }}) ⇒ "5"

fmt.formatBigInt(3n) ⇒ "3" !!!

fmt.formatBigInt({valueOf() { return 5n }}) ⇒ "5" !!!

7 of 10

Why a separate method?

8 of 10

Hazard #1: Unintuitive rounding from strings

-"987943287529743907509271"-987943287529743971254272

fmt.format("987943287529743907509271")

⇒ "987,943,287,529,744,000,000,000"

fmt.formatBigInt(987943287529743907509271n)

⇒ "987,943,287,529,743,907,509,271"

9 of 10

Hazard #2: Temptation to overload everything

  • People are really excited about BigInt
  • Many want to upgrade random things taking integer to BigInt
  • Often this is overkill/doesn't make sense/will cause pain with Number
  • Intl.NumberFormat.prototype.format is a rare exception
  • We put "Big" in the name to explain, it's just for big cases
  • Let's recommend against confusion in the ecosystem

10 of 10

Can we agree:

Even where it semantically makes sense, like in Intl.NumberFormat, let's not overload parameters between Number and BigInt?