# Why is BigInt broken?

**URL:** <https://es.discourse.group/t/why-is-bigint-broken/567>\
**Category:** 🦋 Proposals\
**Tags:** proposal\
**Created:** [December 5, 2020, 12:21am UTC](https://es.discourse.group/t/why-is-bigint-broken/567 "2020-12-05T00:21:44Z")\
**Posts on this page:** 14\
**Page:** 2

<div class="post-metadata">

**Author:** ![vrugtehagel](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/vrugtehagel/32/653_2.png) [@vrugtehagel](https://es.discourse.group/u/vrugtehagel)\
**Post date:** [March 11, 2021, 3:24pm UTC](https://es.discourse.group/t/why-is-bigint-broken/567/21 "2021-03-11T15:24:03Z")

</div>

Perhaps you're right in that I do not understand the point of a default constructor. In my own classes, I rarely ever allow the user to initialize it without explicitly defining what they want it to be, because it removes ambiguity and unpredictability. I never use constructors like `String` or `BigInt` without any arguments, because I have no reason to, and find writing out the value more readable.

As far as "neutral" values concerns, I find that concept a bit subjective (why is the neutral `Number` not `1`, since it's equal to its own inverse? Why is the property "being equal to its own negative" perceived as it being neutral?). Perhaps the neutral value for `BigInt` should be `Infinity`, as it's the biggest int I can think of, though it's not an object of type `BigInt`, so it throws an error. I know `Infinity` is technically not an integer, or mathematically speaking, it's not even a real number, but my point is that these "neutral" values could be somewhat subjective. I understand what you're saying though; while I would never use `String()` or `BigInt()` without arguments, I can see your point on why people would. I don't necessarily agree personally with that pattern, but that's not what we're here for to discuss.

As far as the language defending developers, I think it is essential that we move towards this. Of course, developers should learn to use different aspects of the language, but there's no reason not to steer them a little in taking the right path without having to think about it. This doesn't mean the language should be any more or less powerful - things like not allowing to call `String()` without any arguments doesn't make the language less powerful, because one could achieve the same result with `String('')` (I'm not saying we should move to that specifically; this is demonstrating that you can have the same language capabilities with fewer syntactical options).

You can see a similar pattern in everyday objects. If you have trouble using the washing machine, because it has 40 buttons on it and you don't know which ones to push in which order, then as the designer of that washing machine I could say "bah, people should just learn to use it!" but that's not what design is about. It should be intuitive and easy to use; ideally, you shouldn't even have to think about what buttons to push.

The same goes for programming languages. We can give it all the bells and whistles and expose these in as many ways as we like, or we can wrap up the same exact bells and whistles in a package that's easy to use and steers people towards using it flawlessly without them having to think about it too much.

I hope that clarifies my previous comment a bit.

---

<div class="post-metadata">

**Author:** ![rdking](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rdking/32/54_2.png) [@rdking](https://es.discourse.group/u/rdking)\
**Post date:** [March 12, 2021, 7:07am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/22 "2021-03-12T07:07:43Z")

</div>

@vrugtehagel Thanks for the clarification. I would agree with you on the issue of simply not calling a constructor without the required argument if the concept of a default value didn't exist. However, regardless of what that value is, as long as it exists, default constructors are there to initialize objects to that value.

As for the language defending developers, maybe you'll see my point if you look at the differences in purpose between a programming language and a washing machine. While indeed, a washing machine is a device with many options controlled by complex parameters, its intent is to do what appears to be a simple job for people who don't want to put much though into it because it appears simple. A programming language, by contrast, has the daunting purpose of providing access to the exposed capabilities of a computer so that a user of the language can translate human requests into a series of instructions the computer can understand and execute. In other words, we as developers perform the same kind of job that the control board in the washing machine does, translating end user desires into instructions that some hardware can execute. It's our responsibility as programmers to take the complexity of controlling the hardware away from the end users. We cannot perform our job well if the language we're using treats us like end users.

That's the last I'll say about that so as not to polute the thread further.

---

<div class="post-metadata">

**Author:** ![dcodeIO](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/dcodeio/32/670_2.png) [@dcodeIO](https://es.discourse.group/u/dcodeIO)\
**Post date:** [March 13, 2021, 1:11pm UTC](https://es.discourse.group/t/why-is-bigint-broken/567/23 "2021-03-13T13:11:36Z")

</div>

I am not sure if or how exactly this is related, but if it is, the [breakage](https://github.com/WebAssembly/design/issues/1399) it introduces with Wasm exports that are called with omitted `i64` values (via [JS-BigInt-integration](https://github.com/WebAssembly/JS-BigInt-integration)), leading to

```javascript
Uncaught TypeError: Cannot convert undefined to a BigInt

```

due to being unable to create a default value, seems like it is important enough to address. Like, there are certainly good reasons to gradually improve the language, but as soon as stuff breaks, even the best arguments around here become moot imo.

That is, unless there is a(nother) way to solve this at the Wasm\<-\>JS boundary?

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [March 14, 2021, 12:42am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/24 "2021-03-14T00:42:10Z")

</div>

Consider that `String` and `BigInt` return primitives, not objects. They really act more like coercion operators than constructors. And between that and the fact `func()` is equivalent to `func(undefined)` provided `func` doesn't care about argument count, `String()` and `BigInt()` are equivalent to `String(undefined)` and `BigInt(undefined)` respectively.

---

<div class="post-metadata">

**Author:** ![rdking](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rdking/32/54_2.png) [@rdking](https://es.discourse.group/u/rdking)\
**Post date:** [March 26, 2021, 9:07pm UTC](https://es.discourse.group/t/why-is-bigint-broken/567/25 "2021-03-26T21:07:41Z")

</div>

@claudiameadows Not quite right. For some function:

```javascript
function func(...args) {
   return args.length();
}

```

`func() != func(undefined)`. They are not "equivalent". They can be treated similarly only if the presence of an argument is unimportant. That's what's at the root of the discussion. The somewhat disturbing trend to let `SomeBuiltIn()` behave the same as `SomeBuiltIn(undefined)`, while useful in many cases, isn't useful in every case. Due to that inconsistency, it is IMO better to err on the side of consistent control and let an `undefined` parameter cause error where appropriate. It isn't clear how useful it is to have `BigInt(undefined)` return the same as `BigInt()` when even `Number(undefined)` returns `NaN`.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [March 28, 2021, 6:25am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/26 "2021-03-28T06:25:04Z")

</div>

You missed a bit:

> [@claudiameadows](#):
>
> Consider that `String` and `BigInt` return primitives, not objects. They really act more like coercion operators than constructors. And between that and the fact `func()` is equivalent to `func(undefined)` **provided `func` doesn't care about argument count** , `String()` and `BigInt()` are equivalent to `String(undefined)` and `BigInt(undefined)` respectively.

(emphasis added)

I intentionally didn't make any specific reference to how a function would detect it (whether via `arguments.length` or `args.length` given an `...args` parameter), BTW.

---

<div class="post-metadata">

**Author:** ![rdking](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rdking/32/54_2.png) [@rdking](https://es.discourse.group/u/rdking)\
**Post date:** [March 29, 2021, 6:17am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/27 "2021-03-29T06:17:47Z")

</div>

You got me. I did miss that fragment. Yet my reply still stands. I might change the example a bit, though.

```javascript
function func(...args) {
   return JSON.stringify(args);
}

```

Now the function doesn't care about the argument count, at least not directly, and that's also part of the point. There are many places where the presence or absence of a parameter makes a difference. That's why I brought up `Number`. Even though the language clearly defines that calling a function that has arguments with no argument values sets each argument to `undefined`, `Number() !== Number(undefined)`. ES has traditionally accepted that these 2 forms have different meanings. My point is that breaking this **useful** convention can have unexpected, hard to debug consequences.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [April 6, 2021, 1:41am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/28 "2021-04-06T01:41:52Z")

</div>

Still cares about argument count - `JSON.stringify` accesses `args.length`, just indirectly. Even stuff like this would still mean it cares about the number of arguments:

```js
// Example 1: `foo()` returns `"fake value"`
Array.prototype[0] = "fake value"
function foo(...args) { return args[0] }

// Example 2: `bar()` returns `"fake value"`
Object.prototype[0] = "fake value"
function bar() { return arguments[0] }

```

> Of course, nobody in their right mind would do this in the wild. But it's for the sake of example.

But my point still stands - they care about `arguments.length`, just not directly. However, positional parameters are still initialized as `undefined`, and can be directly desugared in strict mode to `var name; if (arguments.length >= N) name = arguments[N]` at least within the older `function` style.

I probably should've been more precise - I mean functions that do not use `arguments` or rest parameters for any reason other than to resolve positional parameters don't see a difference between the two.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 6, 2021, 8:46am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/29 "2021-04-06T08:46:12Z")

</div>

Good job, I hate different behaviours on absence and explicit undefined parameter, because developers don't always want to go into the detailed implementations and check whether the method has treated in different ways, especially when it is natively implemented.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [May 31, 2021, 1:09pm UTC](https://es.discourse.group/t/why-is-bigint-broken/567/30 "2021-05-31T13:09:59Z")

</div>

But `String()` is not equivalent to `String(undefined)`.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [June 1, 2021, 4:04am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/31 "2021-06-01T04:04:34Z")

</div>

Just tested, and you're right. 🤦‍♀️

---

<div class="post-metadata">

**Author:** ![guaijie](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/guaijie/32/1068_2.png) [@guaijie](https://es.discourse.group/u/guaijie)\
**Post date:** [October 18, 2021, 6:55am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/32 "2021-10-18T06:55:53Z")

</div>

hahaha, call Symbol() I get 'symbol()'. It's the one that ruins the whole aesthetic

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [October 19, 2021, 7:32am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/33 "2021-10-19T07:32:44Z")

</div>

Except it's not.

```nohighlight
> Symbol(undefined).toString()
'Symbol()'
> Symbol("").toString()
'Symbol()'
> Symbol().toString()
'Symbol()'

```

It's still consistent.

---

<div class="post-metadata">

**Author:** ![guaijie](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/guaijie/32/1068_2.png) [@guaijie](https://es.discourse.group/u/guaijie)\
**Post date:** [October 21, 2021, 9:38am UTC](https://es.discourse.group/t/why-is-bigint-broken/567/34 "2021-10-21T09:38:51Z")

</div>

sorry, I didn't make it clear. It refers to BigInt

[Previous page](https://es.discourse.group/t/why-is-bigint-broken/567.md?page=1)
