Skip to content

Commit 8f57d63

Browse files
authored
[DESIGN] Number selection design refinements
This is to build up and capture technical considerations for how to address the issues raised by @eemeli's PR #842.
1 parent 132d9c3 commit 8f57d63

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

exploration/number-selection.md

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Selection on Numerical Values
22

3-
Status: **Accepted**
3+
Status: **Accepted** (moving back to **Proposed**)
44

55
<details>
66
<summary>Metadata</summary>
@@ -53,6 +53,21 @@ Both JS and ICU PluralRules implementations provide for determining the plural c
5353
of a range based on its start and end values.
5454
Range-based selectors are not initially considered here.
5555

56+
In <a href="https://github.com/unicode-org/message-format-wg/pull/842">PR #842</a>
57+
@eemeli points out a number of gaps or infelicities in the current specification
58+
and there was extensive discussion of how to address these gaps.
59+
60+
The `key` for exact numeric match in a variant has to be a string.
61+
The format of such strings, therefore, has to be specified if messages are to be portable and interoperable.
62+
In LDML45 Tech Preview we selected JSON's number serialization as a source for `key` values.
63+
The JSON serialization is ambiguous, in that a given number value might be serialized validly in more than one way:
64+
```
65+
123
66+
123.0
67+
1.23E2
68+
... etc...
69+
```
70+
5671
## Use-Cases
5772

5873
As a user, I want to write messages that use the correct plural for
@@ -75,6 +90,64 @@ either plural or ordinal selection in a single message.
7590
> * {{You have {$numRemaining} chances remaining (plural)}}
7691
>```
7792
93+
As a user, I want the selector to match the options specified:
94+
```
95+
.local $num = {123.456 :number maximumSignificantDigits=2 maximumFractionDigits=2 minimumFractionDigits=2}
96+
.match {$num}
97+
120.00 {{This matches}}
98+
120 {{This does not match}}
99+
123.47 {{This does not match}}
100+
123.456 {{This does not match}}
101+
1.2E2 {{Does this match?}}
102+
* {{ ... }}
103+
```
104+
105+
Note that badly written keys just don't match, but we want users to be able to intuit whether a given set of keys will work or not.
106+
107+
```
108+
.local $num = {123.456 :integer}
109+
.match {$num}
110+
123.456 {{Should not match?}}
111+
123 {{Should match}}
112+
123.0 {{Should not match?}}
113+
* {{ ... }}
114+
```
115+
116+
There can be complications, which we might need to define. Consider:
117+
118+
```
119+
.local $num = {123.002 :number maximumFractionDigits=1 minimumFractionDigits=0}
120+
.match {$num}
121+
123.002 {{Should not match?}}
122+
123.0 {{Does minimumFractionDigits make this not match?}}
123+
123 {{Does minimumFractionDigits make this match?}}
124+
* {{ ... }}
125+
```
126+
127+
As an implementer, I am concerned about the cost of incorporating _options_ into the selector.
128+
This might be accomplished by building a "second formatter".
129+
Some implementations, such as ICU4J's, might use interfaces like `FormattedNumber` to feed the selector.
130+
Implementations might also apply options by modifying the number value of the _operand_
131+
(or shadowing the options effect on the value)
132+
133+
As a user, I want to be able to perform exact match using arbitrary digit numeric types where they are available.
134+
As an implementer, I do **not** want to be required to provide or implement arbitrary precision
135+
numeric types not available in my platform.
136+
Programming/runtime environments vary widely in support of these types.
137+
MF2 should not prevent the implementation of e.g. `BigDecimal` or `BigInt` types
138+
and permit their use in MF2 messages.
139+
MF2 should not _require_ implementations to support such types where they do not exist.
140+
The problem of numeric type precision,
141+
which is implementation dependent,
142+
should not affect how message `key` values are specified.
143+
144+
> For example:
145+
>```
146+
>.local $num = {11111111111111.11111111111111 :number}
147+
>.match {$num}
148+
>11111111111111.11111111111111 {{This works on some implementations.}}
149+
>* {{... but not on others? ...}}
150+
>```
78151
79152
## Requirements
80153
@@ -460,3 +533,21 @@ and they _might_ converge on some overlap that users could safely use across pla
460533
#### Cons
461534
462535
- No guarantees about interoperability for a relatively core feature.
536+
537+
## Alternatives Considered (`key` matching)
538+
539+
### Standardize the Serialization Forms
540+
541+
Using the design above, remove the integer-only and no-sig-digits restrictions from LDML45
542+
and specify numeric matching by specifying the form of matching `key` values.
543+
Comparison is as-if by string comparison of the serialized forms, just as in LDML45.
544+
545+
### Compare numeric values
546+
547+
This is the design proposed in #842.
548+
549+
This modifies the key-match algorithm to use implementation-defined numeric value exact match:
550+
551+
> 1. Let `exact` be the numeric value represented by `key`.
552+
> 1. If `value` and `exact` are numerically equal, then
553+

0 commit comments

Comments
 (0)