-
Notifications
You must be signed in to change notification settings - Fork 45
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
Store decimal fractions explicitly in NumberLiteral #232
Comments
Another alternative is to store a float and a precision. I'm expecting that the primary use-case here will be external variables and float plural rules? When would we have plural rules on number literals? I'm more expecting this to be a thing for FluentType instances passed into format()? |
Ah, good point. I like that the best. I guess we should make the
You're right that this is mostly intended for |
This looked like a simple enough change to quickly try it out in code. See #235. I first wrote a test case which I'd like to merge regardless of whether this change lands. We don't currently have good testing coverage for numbers. |
I like this change. |
@Pike and I talked about this a few days ago and we wondered whether it's enough to differentiate integers and rational numbers, rather than store the exact precision. It seemed like for plural rules, such a binary distinction would be enough. I mentioned this to @zbraniecki today and he pointed me to at least two languages in which this isn't true: Latvian and Prussian. new Intl.PluralRules("lv", {minimumFractionDigits: 1}).select(0.1)
"one"
new Intl.PluralRules("lv", {minimumFractionDigits: 2}).select(0.1)
"other" Their plural rules use the new Intl.PluralRules("lv", {minimumFractionDigits: 2}).select(0.11)
"zero"
new Intl.PluralRules("lv", {minimumFractionDigits: 3}).select(0.11) // 0.110
"other"
new Intl.PluralRules("lv", {minimumFractionDigits: 3}).select(0.111)
"one" |
It might still be a good idea to specialize |
But that's not a property of the number, is it? This sounds like a tricky problem, because we need to choose the plural form based on the formatter in the resulting string. |
technically, it is a property of the number. But because of JS limitations we need the option to specify the precision of it (which uses the formatter, yeah, to achieve the expected precision). |
It is. Both a number passed as an $variable and a number expressed as a literal in the syntax are affected. The literal is converted to a
I don't think that's tricky. In fact, we already do that in https://github.com/projectfluent/fluent.js/blob/35ceb11c97268378b9b6fea2eebfedb48d5f5e1d/fluent/src/resolver.js#L64-L66, where the |
But ... math. The number of digits after the decimal separator and the number of trailing zeros are locale dependent. Like, 1.2kg might be written down as 1.2kg, or 1.200kg, depending on language? |
It's locale dependent, but also needs to be defined explicitly by the localizer: kilos = { NUMBER($weight, minimumFractionDigits: 3) ->
[zero] Zero
[one] One
*[Other] Other
} This already works in the Playground if you select Latvian in the Config tab :) |
This was undone by #239. |
The
NumberLiteral
AST node currently has avalue
field. In most implementations it is stringly-typed in order to preserve the fractional part of the number, even if it's0
. This is important because in some languages the plural rules change based on the mere presence of the fractional part, thus making it significant.This approach has the benefit of being simple but it leaves the logic of converting the number literal into a
FluentNumber
type up to the implementation (e.g.parseFloat
). Instead, we could clarify the expected behavior by parsing the number literal during parse-time. The resulting AST node could look as follows:1.002
would parse as{integer: 1, fractional: 2, places: 3}
. Theplaces
field is used to left-pad the fractional part with0
.Alternative approaches include:
1002
as an integer together withplaces = 3
to move the decimal separator to the left.1.002
would parse as1
and200
) and assigningplaces = null
when the number is a fraction-less integer.The text was updated successfully, but these errors were encountered: