Skip to content

Add BigInt primitive number type #4677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Bubbler-4 opened this issue Sep 7, 2020 · 13 comments
Closed

Add BigInt primitive number type #4677

Bubbler-4 opened this issue Sep 7, 2020 · 13 comments

Comments

@Bubbler-4
Copy link

I'm surprised no one suggested this yet (the only other relevant issue I could find was #2903). Now that all major browsers and runtimes support it (ignoring IE which is EOL'd anyway), I guess it's about time to add it as a primitive number type.

  • BigInt literals 1n, 9007199254740991n
  • Conversion from/to strings/ints/floats
  • Binary operators and/or built-in functions for arithmetic on bigints, e.g. + - * / ** %

(The MDN doc shows a couple static functions too, but they're not yet supported on Safari, and I don't think they're that useful.)

@bobzhang
Copy link
Member

bobzhang commented Sep 10, 2020

indeed, it's something we should add. note 3n has a special meaning in ocaml, it's nativeint. Shall we choose a different suffix or just override it.
If we use n as a suffix, we need check if we can make this works:

let f = function 
  | 1n 
  | 2n -> 0
  | x -> Nativeint.add x 3n

@yawaramin
Copy link
Contributor

We don't need a special literal imho. BigInt(1) is the same as 1n in JS. It can be done purely with bindings, say, a Js.BigInt module. Js.BigInt.ofInt, ofString, etc., can be constructors.

@somebody1234
Copy link

i feel like special literals would be better (like %re) so we could transpile to, say, 10000000000000n nicely

@yawaramin
Copy link
Contributor

It would make it perhaps slightly more convenient to do e.g. %bigint(10000000000000) instead of BigInt.ofString("10000000000000"), I just don't know if it's worth the tradeoff of implementing custom support in the compiler as opposed to just writing a library-level binding.

@somebody1234
Copy link

@yawaramin it would also be possible to avoid having to allocate a string - not that there's a noticeable difference in perforamance very much of the time, but i do believe it'd be slightly more idiomatic? idk

@tom-sherman
Copy link

This proposal is sorely needed IMO, we at least need a single type in pervasives for libraries to target to as a first step.

We don't need a special literal imho.

I disagree, literals are much more intuitive and much less error prone. ofString would have to be used everywhere which is a really frustrating experience when coming from JS.

Another +1 for why this is needed, Temporal will be landing in the coming months and parts of the API rely heavily on bigints: https://tc39.es/proposal-temporal/docs

Compiler support would be great also for output size - BigInt("100000") vs 100000n. You could argue that compression negates this point, but that only helps in bundles.

@yawaramin
Copy link
Contributor

@somebody1234 aren't strings interned by JS runtimes nowadays? And in any case, I doubt that calling the constructor like BigInt("1") would allocate a string.

@tom-sherman anyone can send a PR for at least initial BigInt bindings even without a custom literal syntax. Just need to create a new module Js.BigInt, put the t type and the rest of the bindings in there.

About 'frustrating experience', I'm not really seeing how it's worse than having to use e.g. React.string etc. ReScript is a little bit more explicit than JS/TS in return for being much more type-safe. and if typing out BigInt.ofString is a burden, then it's easy to do let b = BigInt.ofString, which also resolves the output size issue, not that it should be a serious issue in the first place if people are correctly using HTTP compression to deliver JS and other payloads in production settings.

@tom-sherman
Copy link

The ofString function introduces room for runtime errors though, errors that should be caught at compile time. It also requires the developer to be aware of the edge cases of string->bigint conversions, which can lead to very unexpected results. This is mental overhead that can all be avoided with a literal.

@somebody1234
Copy link

@yawaramin interned... sure. whether the runtime would optimize that into a bigint constant... i don't know.

of course as i basically mentioned before, it'd also be more "idiomatic" - as in, in js nobody uses BigInt("string literal") since bigint literals are a thing. therefore including bigint literals would result in more conventional output.

@yawaramin
Copy link
Contributor

@tom-sherman OK but the parsing of the literal has to happen somewhere. Making it compile-time in ReScript would mean duplicating the BigInt literal parsing functionality that already exists in the JavaScript platform, making sure to duplicate all its possible quirks and edge cases, and keeping those up-to-date, otherwise when people run into edge cases they will be super confused why ReScript BigInt literal parsing behaviour is different than vanilla JS (small example that we can already see: ReScript parses 1. as a valid float).

Anyway, whether that's done or not, all I'm saying is that the Js.BigInt module is needed anyway, and it will be much easier to implement than compile-time BigInt literal parsing. So perhaps some interested party can work on that, at least.

Copy link

stale bot commented Mar 13, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale Old issues that went stale label Mar 13, 2024
@fhammerschmidt
Copy link
Member

Too eager, stale bot!
#6670

@stale stale bot removed the stale Old issues that went stale label Mar 13, 2024
@mununki
Copy link
Member

mununki commented Mar 27, 2024

Resolved #6670

@mununki mununki closed this as completed Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants