GoogleChromeLabs/jsbi

Create a JSBI → BigInt transpiler

mathiasbynens opened this issue · 15 comments

Most features are transpiled from their standardized form into a more compatible form. For BigInt specifically, this is not feasible for the reasons outlined in the README.

As such, developers wishing to use BigInt functionality today should instead use JSBI to write their code. Then, when the time comes that BigInts are natively supported everywhere, they should be able to transpile their JSBI-based code into native BigInt code.

In other words, we need a JSBI → native BigInt transpiler.

If you’d like to help, please speak up!

Update: @FWeinb created a prototype Babel plugin. What’s left to do is for someone to take that code, package it up as its own repository with tests and publish it as an npm module.

For example, the README demo:

const max = JSBigInt(Number.MAX_SAFE_INTEGER);
console.log(String(max));
// → '9007199254740991'
const other = JSBigInt('2');
const result = max.add(other);
console.log(String(result));
// → '9007199254740993'

…would be transpiled to…

const max = BigInt(Number.MAX_SAFE_INTEGER);
console.log(String(max));
// → '9007199254740991'
const other = BigInt('2');
const result = max + other;
console.log(String(result));
// → '9007199254740993'

Transpiling this will get very tricky. See this example:

const addNumbers = (a, b) => a.add(b);
const a = JSBigInt('1');
const b = JSBigInt('2');
const result = addNumbers(a, b);

It would be very hard to statically analysis the code and track all functions that take JSBigInts.

One way to solve this issue would be to slightly change the API and have all the methods on the JSBigInt Prototype e.g. const addNumbers = (a, b) => JSBigInt.add(a, b)

That is indeed the main challenge. You can’t just replace all calls to a method named add, for example. I want to believe some tooling exists already to do this kind of tracking, though.

+1 for static methods that can be easily babel-macro'd away without the need for type inference. In the current state of JS tooling, typecheckers and code transformers are usually separate (TypeScript is the exception) and so writing a reliable, performant transform for this would be quite tricky.

Here is a quick prototype with using the static api https://astexplorer.net/#/gist/f3b0272a37d21487e8b3561c1c7d38c2/52cb36181a0f935062c9999a65f30a663a3d5245

[Edit]
I updated the prototype to include every operator and convert BigInts to a literal if possible.

I chatted with @hzoo today who confirmed that although there are a few existing projects in this area, it would certainly be easier to just change JSBI’s API to turn everything into static methods. So let’s just do that. @FWeinb’s WIP prototype could then be turned into a proper Babel plugin :)

The API was changed in #10, and jsbi@2.0.0 includes the changes. @FWeinb, would you be interested in packaging up your transpiler into a fully-fledged GitHub repo of its own + publishing it on npm?

@mathiasbynens Sorry, but I currently don't have enough time to maintain a babel plugin. Feel free to use the code I posted as a baseline.

@FWeinb No worries. Any takers?

@FWeinb Would you mind signing the CLA so we can release the plugin based on your prototype under the same license as JSBI itself?

@mathiasbynens I signed the CLA.

We’re working on publishing this soon.

https://github.com/GoogleChromeLabs/babel-plugin-transform-jsbi-to-bigint 🔥

Thanks for the help everyone! Special shout-out to @FWeinb for putting together the prototype and allowing us to build upon it.