Skip to content
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

BigDecimal literal syntax #7

Open
littledan opened this issue Nov 13, 2019 · 22 comments
Open

BigDecimal literal syntax #7

littledan opened this issue Nov 13, 2019 · 22 comments

Comments

@littledan
Copy link
Member

Following the rough consensus of several programming languages as well as TC39 tradition, this proposal uses the syntax 123.456m for BigDecimal literals. (Maybe m stands for Money?) Is this a reasonable syntax, or are there any issues?

@chicoxyzzy
Copy link
Member

Should 123.m be a valid literal?

@littledan
Copy link
Member Author

Offline, @bkardell proposed 123.456d. Does this seem better?

@MaxGraey
Copy link

I like d suffix more because 123n and 123m is pretty similar especially on monospaced fonts

@qzb
Copy link

qzb commented Nov 16, 2019

After some googling (correct me if I got something wrong):

  • Java - doesn't have literal for BigDecimal, uses d suffix for doubles;
  • Python - doesn't have literal for Decimal, doesn't use d and m suffixes;
  • PHP - no builtin BigDecimal type, doesn't use d and m suffixes;
  • C# - uses suffix m for 128-bit decimal type and suffix d for doubles;
  • Ruby - doesn't have literal for BigDecimal, doesn't use d and m suffixes, uses 0d prefix for decimal notation;
  • C++ - no builtin BigDecimal type, doesn't use d and m suffixes;
  • Go - doesn't have literals for math/big types, doesn't use d and m suffixes;
  • Rust - no builtin BigDecimal type, doesn't use d and m suffixes.

I don't see strong consensus here - most of the popular languages are missing this feature, so there will be no much harm to choose some different suffix than m. Personally I find it confusing, I think d is much more intuitive.

@fabiosantoscode
Copy link

I propose we just use n. It would be easier to remember, and also to learn "when a number has an n at the end it's not a float, it's an arbitrary precision number".

Even if their implementations are different their semantics are very much the same.

It's also not a big deal to support both decimals and integers having similar syntax in terms of parser writing. I suppose I can change a few lines in the Terser parser and this goes right in.

@ljharb
Copy link
Member

ljharb commented Nov 16, 2019

@fabiosantoscode n is already used for BigInt. It would be exceedingly confusing if 5.0n produced a BigInt and 5.01n produced a BigDecimal.

@qzb
Copy link

qzb commented Nov 16, 2019

@ljharb isn't 5.0n a syntax error? Still, I agree that it would be confusing.

@littledan
Copy link
Member Author

I was imagining that it'd be possible to have BigDecimal literals that didn't have a literal decimal point in them, e.g., 5m would be meaningful. If we use n, that'd be lost due to the BigInt conflict.

@ENvironmentSet
Copy link

@ljharb What about extending BigInt to BigDecimal? I mean, let BigDecimal be supertype of BigInt, then we could easily solve the problem about ambiguity & confusing syntax.

I was wondering why we should separate BigInt and BigDecimal. If we do so, we can’t simply write function that parametrically polymorphic to BigInt & BigDecimal but we would use function like ‘matchBigNumbers(BigN1, BigN2)’, which makes code long.

@littledan
Copy link
Member Author

@ENvironmentSet I think that would lead to certain mismatches. For one, division in BigInt is integer division (which many developers told us was an important use case), but in BigDecimal, we may want to give a more precise answer, or trigger an error (discussed further in #13).

@wheresrhys
Copy link

How about an x suffix from the roman numeral for ten?

@qzb
Copy link

qzb commented Nov 17, 2019

@wheresrhys It would make 0x0x a valid literal :)

@chicoxyzzy
Copy link
Member

I can imaging cases where 1.d being invalid syntax could cause problems. Let's say, we have some code generator and trying to eval a template string containing ${integer}.${fraction}${isBigDecimal ? 'd' : ''}. If fraction is an empty string, then for Numbers this will work fine, but for BigDecimals it will throw SyntaxError. So I'd prefer to make trailing dot before d an allowed syntax. @ljharb WDYT?

@chicoxyzzy
Copy link
Member

I don't like how 0.d primitive value or 0.d.toString() looks, but I think that making it an invalid syntax will lead to a worse developer experience.

@ljharb
Copy link
Member

ljharb commented Nov 18, 2019

@chicoxyzzy fraction || 0 seems like a better choice in that example than allowing the worst part of Number syntax to propagate.

@littledan
Copy link
Member Author

Due to #36 , I think we should avoid d as the suffix: Even if we don't want hexadecimal decimals now, it feels like backing us into an unfortunate corner (which may get worse depending on how extended numerical literals go). For now, I think I'll switch back to m, but if you have other ideas here, please post them

About a trailing .: my feeling is that we should follow the Number grammar here and allow it. Divergences from Number should have a particular reason in my opinion (like omitting legacy octal literals from BigInt because they are legacy).

littledan pushed a commit that referenced this issue Jan 15, 2020
littledan pushed a commit that referenced this issue Jan 15, 2020
@ljharb
Copy link
Member

ljharb commented Jan 15, 2020

Maybe the trailing decimal should warrant a separate issue; it feels like a mistake nobody wants that would be a shame to replicate.

@Rudxain
Copy link
Contributor

Rudxain commented Apr 10, 2022

I think "0." should be allowed only if it's a string being parsed, not a literal in code. Such that any BigDecimal parser implementation should allow 1 trailing dot at most, without throwing an error or returning NaN

@jessealama
Copy link
Collaborator

It seems that this issue has been resolved. Shall we close it?

@jessealama
Copy link
Collaborator

Based on feedback received at plenary about this issue, it looks like adding new literal syntax for decimals is, as of today, too heavy of a lift for some of the engine implementors. (That's not to say that it's not a bad idea and that we couldn't return to the issue sometime down the road.)

@ljharb
Copy link
Member

ljharb commented Aug 30, 2023

I don't think the pushback was about new syntax as much as it was about "a new primitive" and ===, but maybe I'm remembering incorrectly.

@jessealama
Copy link
Collaborator

I don't think the pushback was about new syntax as much as it was about "a new primitive" and ===, but maybe I'm remembering incorrectly.

IIRC I thought that the argument for "no new syntax" did indeed involve ===. The argument went something like this:

Assumptions:

  1. no new built-in datatype
  2. no overloading, but:
  3. new literal syntax (it would basically be just a macro for invocations of new Decimal(...), given assumption (1))

Given those assumptions, we would be led to the awkward situation where 1.2m === 1.2m would be false because of (2).

In other words, adding new literals without overloading would lead to confusion. That was my takeaway, anyway. Maybe I'm getting the argument wrong.

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

10 participants