From 9a08e14d2dd098e19cde7fa4d449a67084d10df7 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 7 Apr 2025 13:45:37 -0700 Subject: [PATCH 01/25] Design document for percent formatting This document is focused for now on documenting the options. --- exploration/percent-format.md | 169 ++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 exploration/percent-format.md diff --git a/exploration/percent-format.md b/exploration/percent-format.md new file mode 100644 index 0000000000..6d207d3e9a --- /dev/null +++ b/exploration/percent-format.md @@ -0,0 +1,169 @@ +# Formatting Percent Values + +Status: **Proposed** + +
+ Metadata +
+
Contributors
+
@aphillips
+
First proposed
+
2025-04-07
+
Pull Requests
+
#000
+
+
+ +## Objective + +_What is this proposal trying to achieve?_ + +One the capabilities present in ICU MessageFormat is the ability to format a number as a percentage. +This design enumerates the approaches considered for adding this ability as a _default function_ +in Unicode MessageFormat. + +## Background + +_What context is helpful to understand this proposal?_ + +> [!NOTE] +> This design is an outgrowth of discussions in #956 and various teleconferences. + +Developers and translators often need to insert a numeric value into a formatted message as a percentage. +The format of a percentage can vary by locale including +the symbol used, +the presence or absence of spaces, +the shaping of digits, +the position of the symbol, +and other variations. + +One of the key problems is whether the value should be "scaled". +That is, does the value `0.5` format as `50%` or `0.5%`? +Developers need to know which behavior will occur so that they can adjust the value passed appropriately. + +> [!NOTE] +> MessageFormat (MF1) in ICU4J scales. +> MeasureFormat in ICU4J does not scale. + +It is also possible for Unicode MessageFormat to provide support for scaling in the message itself, +perhaps by extending the `:math` function. + +An addition concern is whether to add a dedicated `:percent` function, +use one of the existing number-formatting functions `:number` and `:integer` with an option `type=percent`, +or use the proposed _optional_ function `:unit` with an option `unit=percent`. +Combinations of these approached might also be used. + +## Use-Cases + +_What use-cases do we see? Ideally, quote concrete examples._ + +Developers wish to write messages that format a numeric value as a percentage in a locale-sensitive manner. + +The numeric value is not scaled because it is the result of a computation, e.g. `var savings = discount / price`. + +The numeric value is scaled, e.g. `var savingsPercent = 50` + +Users need control over most formatting details, identical to general number formatting: +- negative number sign display +- digit shaping +- minimum number of fractional digits +- maximum number of fractional digits +- minimum number of decimal digits +- group used (for very large percentages, i.e. > 999%) +- etc. + +## Requirements + +_What properties does the solution have to manifest to enable the use-cases above?_ + + + +## Constraints + +_What prior decisions and existing conditions limit the possible design?_ + +## Proposed Design + +_Describe the proposed solution. Consider syntax, formatting, errors, registry, tooling, interchange._ + +- Use a dedicated function `:percent` that scales by default. +- Provide an option `scaling` with values `true` and `false` and defaulting to `true`. +- Provide all options identical to `:number` _except_ that `select` does not provide `ordinal` value. +- Allow `unit=percent` in `:unit` that is identical to `:percent` in formatting performance, + for compatibility with CLDR units, + but document that this usage is not preferred. + +## Alternatives Considered + +_What other solutions are available?_ +_How do they compare against the requirements?_ +_What other properties they have?_ + +### Function Alternatives + +#### Use `:unit` + +Leverage the `:unit` function by using the existing unit option value `percent`. +The ICU implementation of `MeasureFormat` does **_not_** scale the percentage, +although this does not have to be the default behavior of UMF's percent unit format. + +``` +You saved {$savings :unit unit=percent} on your order today! +``` + +**Pros** +- Uses an existing set of functionality +- Removes percentages from `:number` and `:integer`, making those functions more "pure" + +**Cons** +- `:unit` won't be REQUIRED, so percentage format will not be guaranteed across implementations. + Requiring `:unit type=percent` would be complicated at best. +- More verbose placeholder +- Could require a scaling mechanism + +#### Use `:number`/`:integer` with `type=percent` + +Use the existing functions for number formatting with a separate `type` option for `percent`. +(This was previously the design) + +``` +You saved {$savings :number type=percent} on your order today! +``` + +**Pros** +- Consistent with ICU MessageFormat + +**Cons** +- It's the only special case remaining in these functions. Why? + +#### Use a dedicated `:percent` function + +Use a new function `:percent` dedicated to percentages. + +``` +You saved {$savings :percent} on your order today! +``` + +**Pros** +- Least verbose placeholder +- Clear what the placeholder does; self-documenting? + +**Cons** +- Adds to a (growing) list of functions +- Not "special enough" to warrant its own formatter? + +### Scaling Alternatives + +#### No Scaling +User has to scale the number. The value `0.5` formats as `0.5%` + +#### Scaling +Implementation always scales the number. The value `0.5` formats as `50%` + +#### Optional Scaling +Implementation automatically does (or does not) scale. +There is an option to switch to the other behavior. + +#### Use `:math` to scale +Provide functionality to scale numbers arbitrarily using the `:math` function. +This alternative can be used with scaling/no scaling to fix the passed value appropriately without altering userland code. From 659a3758e32b664d73d48df101de0c87784d0760 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 7 Apr 2025 17:38:41 -0700 Subject: [PATCH 02/25] Address comments --- exploration/percent-format.md | 37 ++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 6d207d3e9a..020c2bb416 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -10,7 +10,7 @@ Status: **Proposed**
First proposed
2025-04-07
Pull Requests
-
#000
+
#1068
@@ -99,6 +99,15 @@ _What other solutions are available?_ _How do they compare against the requirements?_ _What other properties they have?_ +### Combinations of Functions and Scaling + +Any proposed design needs to choose one or more functions +each of which has a scaling approach +or a combination of both. +It is possible to have separate functions, one that is scaling and one that is non-scaling. +However, the working group suspects that this would represent a hazard, +since users would be forced to look up which one what which behavior. + ### Function Alternatives #### Use `:unit` @@ -144,6 +153,10 @@ Use a new function `:percent` dedicated to percentages. You saved {$savings :percent} on your order today! ``` +> [!NOTE] +> @sffc suggested that we should consider other names for `:percent`. +> The name shown here could be considered a placeholder pending other suggestions. + **Pros** - Least verbose placeholder - Clear what the placeholder does; self-documenting? @@ -152,6 +165,28 @@ You saved {$savings :percent} on your order today! - Adds to a (growing) list of functions - Not "special enough" to warrant its own formatter? +#### Use a generic scaling function + +Use a new function with a more generic name so that it can be used to format other scaled values. +For example, it might use an option `unit` to select `percent`/`permille`/etc. + +``` +You saved {$savings :dimensionless unit=percent} on your order today! +You saved {$savings :scaled per=100} on your order today! +``` + +**Pros** +- Could be used to support non-percent/non-permille scales that might exist in other cultures +- Somewhat generic +- Unlike currency or unit values, "per" units do not have to be stored with the value to prevent loss of fidelity, + since the scaling is done to a plain old number. + This would not apply if the values are not scaled. + +**Cons** +- Only percent and permille are backed with CLDR data and symbols. + Other scales would impose an implementation burden. +- More verbose. Might be harder for users to understand and use. + ### Scaling Alternatives #### No Scaling From 442722beec4042f28c0b64ae5dfc9a51aa77e36f Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Thu, 10 Apr 2025 08:55:54 -0700 Subject: [PATCH 03/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 020c2bb416..034500060f 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -42,8 +42,13 @@ That is, does the value `0.5` format as `50%` or `0.5%`? Developers need to know which behavior will occur so that they can adjust the value passed appropriately. > [!NOTE] -> MessageFormat (MF1) in ICU4J scales. -> MeasureFormat in ICU4J does not scale. +> In ICU4J: +> - MessageFormat (MF1) scales. +> - MeasureFormat does not scale. +> +> In JavaScript: +> - `Intl.NumberFormat(locale, { style: 'percent' })` scales +> - `Intl.NumberFormat(locale, { style: 'unit', unit: 'percent' })` does not scale It is also possible for Unicode MessageFormat to provide support for scaling in the message itself, perhaps by extending the `:math` function. From 813226a0ebcffa6453066c9ab05ac2045de334d9 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Thu, 10 Apr 2025 08:56:11 -0700 Subject: [PATCH 04/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 034500060f..67248547fb 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -137,11 +137,11 @@ You saved {$savings :unit unit=percent} on your order today! #### Use `:number`/`:integer` with `type=percent` -Use the existing functions for number formatting with a separate `type` option for `percent`. +Use the existing functions for number formatting with a separate `style` option for `percent`. (This was previously the design) ``` -You saved {$savings :number type=percent} on your order today! +You saved {$savings :number style=percent} on your order today! ``` **Pros** From 9a76ea703f4650e7bffd42c25445d4f283f3034c Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Thu, 10 Apr 2025 08:56:36 -0700 Subject: [PATCH 05/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 67248547fb..4453abd19d 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -197,7 +197,7 @@ You saved {$savings :scaled per=100} on your order today! #### No Scaling User has to scale the number. The value `0.5` formats as `0.5%` -#### Scaling +#### Always Scale Implementation always scales the number. The value `0.5` formats as `50%` #### Optional Scaling From 817b58b3df339e6c3d329ac53ed65abb3bc39fcf Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Thu, 10 Apr 2025 09:03:34 -0700 Subject: [PATCH 06/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 4453abd19d..b3048d5286 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -204,6 +204,26 @@ Implementation always scales the number. The value `0.5` formats as `50%` Implementation automatically does (or does not) scale. There is an option to switch to the other behavior. -#### Use `:math` to scale -Provide functionality to scale numbers arbitrarily using the `:math` function. -This alternative can be used with scaling/no scaling to fix the passed value appropriately without altering userland code. +#### Use `:math exp` to scale +Provide functionality to scale numbers with integer powers of 10 using the `:math` function. + +Examples using `:unit`, each of which would format as "Completion: 50%.": +``` +.local $n = {50} +{{Completion: {$n :unit unit=percent}.}} + +.local $n = {0.5 :math exp=2} +{{Completion: {$n :unit unit=percent}.}} +``` + +#### Use `:math multiply` to scale +Provide arbitrary integer multiplication functionality using the `:math` function. + +Examples using `:unit`, each of which would format as "Completion: 50%.": +``` +.local $n = {50} +{{Completion: {$n :unit unit=percent}.}} + +.local $n = {0.5 :math multiply=100} +{{Completion: {$n :unit unit=percent}.}} +``` From d9149452225820225534b39d3634092c625bdde5 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Sat, 12 Apr 2025 12:41:36 -0700 Subject: [PATCH 07/25] Address comments --- exploration/percent-format.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index b3048d5286..2312f4c26d 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -204,7 +204,28 @@ Implementation always scales the number. The value `0.5` formats as `50%` Implementation automatically does (or does not) scale. There is an option to switch to the other behavior. -#### Use `:math exp` to scale +#### Provide scaling via additions to `:math` +Regardless of the scaling done by the percent formatting function, +there might need to be an in-message mechanism for scaling/descaling values. +The (currently DRAFT) function `:math` was added to support offsets in number matching/formatting. +Extension of `:math` to support other mathematical capabilities would allow for scaling. + +**Pros** +- Users may find utility in performing math transforms in messages rather than in business logic. +- Should be easy to implement, given that basic math functionality is common + +**Cons** +- Implementation burden, especially when providing generic mathematical operations +- Designs should be generic and extensible, not tied to short term needs of a given formatter. +- Potential for abuse and misuse is higher. +- "Real" math utilities or classes tend to have a long list of functions with many capabilities. + A complete implementation would require a lot of design work and effort or introduce + instability into the message regime as new options are introduced over time. + Compare with `java.lang.Math` + +Two proposals exist: + +##### Use `:math exp` to scale Provide functionality to scale numbers with integer powers of 10 using the `:math` function. Examples using `:unit`, each of which would format as "Completion: 50%.": @@ -216,7 +237,7 @@ Examples using `:unit`, each of which would format as "Completion: 50%.": {{Completion: {$n :unit unit=percent}.}} ``` -#### Use `:math multiply` to scale +##### Use `:math multiply` to scale Provide arbitrary integer multiplication functionality using the `:math` function. Examples using `:unit`, each of which would format as "Completion: 50%.": From 3b10266eb69d97eb95c37a6e0ac584d7e70f1d95 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Tue, 22 Apr 2025 09:00:29 -0700 Subject: [PATCH 08/25] Update exploration/percent-format.md Co-authored-by: Mark Davis --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 2312f4c26d..7c9261a018 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -94,7 +94,7 @@ _Describe the proposed solution. Consider syntax, formatting, errors, registry, - Use a dedicated function `:percent` that scales by default. - Provide an option `scaling` with values `true` and `false` and defaulting to `true`. - Provide all options identical to `:number` _except_ that `select` does not provide `ordinal` value. -- Allow `unit=percent` in `:unit` that is identical to `:percent` in formatting performance, +- Allow `unit=percent` in `:unit` that is identical to `:percent` in formatting capabilities, for compatibility with CLDR units, but document that this usage is not preferred. From e4ef2a423993a0a9a0c70af8a784d15e55f3ad16 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Tue, 22 Apr 2025 11:27:18 -0700 Subject: [PATCH 09/25] Update exploration/percent-format.md --- exploration/percent-format.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 7c9261a018..83ae1f3f3c 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -81,7 +81,10 @@ Users need control over most formatting details, identical to general number for _What properties does the solution have to manifest to enable the use-cases above?_ - +- **Be consistent** Any solution for scaling percentages should be a model for other, similar scaling operations, + such as _per-mille_ or _per-myriad_, + as well as other, non-percent or even non-unit scaling. + This does not mean that a scaling mechanism or any particular scaling mechanism itself is a requirement. ## Constraints From 23c1d994e0708638668d4dae7a8b455a9b526f3c Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Tue, 22 Apr 2025 11:42:40 -0700 Subject: [PATCH 10/25] Update percent-format.md --- exploration/percent-format.md | 47 ++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 83ae1f3f3c..e296fcaf69 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -64,9 +64,11 @@ _What use-cases do we see? Ideally, quote concrete examples._ Developers wish to write messages that format a numeric value as a percentage in a locale-sensitive manner. -The numeric value is not scaled because it is the result of a computation, e.g. `var savings = discount / price`. +The numeric value of the operand is not pre-scaled because it is the result of a computation, +e.g. `var savings = discount / price`. -The numeric value is scaled, e.g. `var savingsPercent = 50` +The numeric value of the operant is pre-scaled, +e.g. `var savingsPercent = 50` Users need control over most formatting details, identical to general number formatting: - negative number sign display @@ -81,10 +83,17 @@ Users need control over most formatting details, identical to general number for _What properties does the solution have to manifest to enable the use-cases above?_ -- **Be consistent** Any solution for scaling percentages should be a model for other, similar scaling operations, - such as _per-mille_ or _per-myriad_, - as well as other, non-percent or even non-unit scaling. - This does not mean that a scaling mechanism or any particular scaling mechanism itself is a requirement. +- **Be consistent** + - Any solution for scaling percentages should be a model for other, similar scaling operations, + such as _per-mille_ or _per-myriad_, + as well as other, non-percent or even non-unit scaling. + This does not mean that a scaling mechanism or any particular scaling mechanism itself is a requirement. + - Any solution for formatting percentages should be a model for solving related problems with: + - per-mille + - per-myriad + - compact notation + - scientific notation + - (others??) ## Constraints @@ -113,8 +122,13 @@ Any proposed design needs to choose one or more functions each of which has a scaling approach or a combination of both. It is possible to have separate functions, one that is scaling and one that is non-scaling. -However, the working group suspects that this would represent a hazard, -since users would be forced to look up which one what which behavior. + +Some working group members suspect that having a function that scales and one that does not +would represent a hazard, +since users would be forced to look up which one has which behavior. + +Other working group members have expressed that the use cases for pre-scaled vs. non-pre-scaled are separate +and that having separate functions for these is logically sensible. ### Function Alternatives @@ -136,7 +150,7 @@ You saved {$savings :unit unit=percent} on your order today! - `:unit` won't be REQUIRED, so percentage format will not be guaranteed across implementations. Requiring `:unit type=percent` would be complicated at best. - More verbose placeholder -- Could require a scaling mechanism +- Could require a separate scaling mechanism #### Use `:number`/`:integer` with `type=percent` @@ -198,15 +212,24 @@ You saved {$savings :scaled per=100} on your order today! ### Scaling Alternatives #### No Scaling -User has to scale the number. The value `0.5` formats as `0.5%` +User has to scale the number. +The value `0.5` formats as `0.5%` #### Always Scale -Implementation always scales the number. The value `0.5` formats as `50%` +Implementation always scales the number. +The value `0.5` formats as `50%` #### Optional Scaling Implementation automatically does (or does not) scale. There is an option to switch to the other behavior. +> Example. +>``` +> .local $pctSaved = {50} +> {$pctSaved :percent} {$pctSaved :percent scale=false} +>``` +> Prints as `5000% 50%` if `:percent` is autoscaling by default + #### Provide scaling via additions to `:math` Regardless of the scaling done by the percent formatting function, there might need to be an in-message mechanism for scaling/descaling values. @@ -226,7 +249,7 @@ Extension of `:math` to support other mathematical capabilities would allow for instability into the message regime as new options are introduced over time. Compare with `java.lang.Math` -Two proposals exist: +Two proposals exist for using `:math`: ##### Use `:math exp` to scale Provide functionality to scale numbers with integer powers of 10 using the `:math` function. From 03b1f784b45d8a5fb840ed139263d76200123152 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Tue, 22 Apr 2025 12:42:23 -0700 Subject: [PATCH 11/25] Update percent-format.md --- exploration/percent-format.md | 80 +++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index e296fcaf69..4080e4dda6 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -142,15 +142,25 @@ although this does not have to be the default behavior of UMF's percent unit for You saved {$savings :unit unit=percent} on your order today! ``` -**Pros** +The `:unit` alternative could also support other unit-like alternatives, such as +_per-mille_ and _per-myriad_ formatting. +It doesn't fit as cleanly with other notational variations left out of v47, such as +compact notation (1000000 => 1M, 1000 => 1K), +or scientific notation (1000000 => 1.0e6). + +_Pros_ - Uses an existing set of functionality +- Might provide a more consistent interface for formatting "number-like" values - Removes percentages from `:number` and `:integer`, making those functions more "pure" -**Cons** +_Cons_ - `:unit` won't be REQUIRED, so percentage format will not be guaranteed across implementations. Requiring `:unit type=percent` would be complicated at best. +- Implementation of `:unit` in its entirely requires significantly more data than implementation of + percentage formatting. - More verbose placeholder -- Could require a separate scaling mechanism + +--- #### Use `:number`/`:integer` with `type=percent` @@ -161,11 +171,14 @@ Use the existing functions for number formatting with a separate `style` option You saved {$savings :number style=percent} on your order today! ``` -**Pros** +_Pros_ - Consistent with ICU MessageFormat -**Cons** -- It's the only special case remaining in these functions. Why? +_Cons_ +- It's the only special case remaining in these functions, + unless we also restore compact, scientific, and other notational variations. + +--- #### Use a dedicated `:percent` function @@ -179,14 +192,17 @@ You saved {$savings :percent} on your order today! > @sffc suggested that we should consider other names for `:percent`. > The name shown here could be considered a placeholder pending other suggestions. -**Pros** +_Pros_ - Least verbose placeholder -- Clear what the placeholder does; self-documenting? +- Clear what the placeholder does; self-documenting +- Consistent with separating `:currency` -**Cons** +_Cons_ - Adds to a (growing) list of functions - Not "special enough" to warrant its own formatter? +--- + #### Use a generic scaling function Use a new function with a more generic name so that it can be used to format other scaled values. @@ -197,14 +213,14 @@ You saved {$savings :dimensionless unit=percent} on your order today! You saved {$savings :scaled per=100} on your order today! ``` -**Pros** +_Pros_ - Could be used to support non-percent/non-permille scales that might exist in other cultures - Somewhat generic - Unlike currency or unit values, "per" units do not have to be stored with the value to prevent loss of fidelity, since the scaling is done to a plain old number. This would not apply if the values are not scaled. -**Cons** +_Cons_ - Only percent and permille are backed with CLDR data and symbols. Other scales would impose an implementation burden. - More verbose. Might be harder for users to understand and use. @@ -215,15 +231,29 @@ You saved {$savings :scaled per=100} on your order today! User has to scale the number. The value `0.5` formats as `0.5%` +> Example. +> ``` +> .local $pctSaved = {50} +> {$pctSaved :percent} +> ``` +> Prints as `50%`. + #### Always Scale Implementation always scales the number. The value `0.5` formats as `50%` +> Example. +> ``` +> .local $pctSaved = {50} +> {$pctSaved :percent} +> ``` +> Prints as `5000%`. + #### Optional Scaling Implementation automatically does (or does not) scale. There is an option to switch to the other behavior. -> Example. +> Example. Note that `scale=false` is only to demonstrate switching. >``` > .local $pctSaved = {50} > {$pctSaved :percent} {$pctSaved :percent scale=false} @@ -236,11 +266,19 @@ there might need to be an in-message mechanism for scaling/descaling values. The (currently DRAFT) function `:math` was added to support offsets in number matching/formatting. Extension of `:math` to support other mathematical capabilities would allow for scaling. -**Pros** +> Example. +>``` +> .local $pctSaved = {0.5} +> .local $pctScaled = {$pctSaved :math exp=2} +> {$pctSaved :percent} {$pctScaled :unit unit=percent} +>``` +> Prints as `50% 50%` if `:percent` is autoscaling by default and `:unit` is not. + +_Pros_ - Users may find utility in performing math transforms in messages rather than in business logic. - Should be easy to implement, given that basic math functionality is common -**Cons** +_Cons_ - Implementation burden, especially when providing generic mathematical operations - Designs should be generic and extensible, not tied to short term needs of a given formatter. - Potential for abuse and misuse is higher. @@ -263,6 +301,14 @@ Examples using `:unit`, each of which would format as "Completion: 50%.": {{Completion: {$n :unit unit=percent}.}} ``` +_Pros_ +- Avoids multiplication of random values +- Useful for other scaling operations + +_Cons_ +- Might require changes to digit size options, since negative exponents are a Thing + + ##### Use `:math multiply` to scale Provide arbitrary integer multiplication functionality using the `:math` function. @@ -274,3 +320,9 @@ Examples using `:unit`, each of which would format as "Completion: 50%.": .local $n = {0.5 :math multiply=100} {{Completion: {$n :unit unit=percent}.}} ``` + +_Pros_ +- Can be used for other general purpose math + +_Cons_ +- Brings in multiplication From 72b11d20a7bece41aedbb36f3a4d55ada66e12ad Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Tue, 22 Apr 2025 12:54:59 -0700 Subject: [PATCH 12/25] Add @macchiati's exact unit scaling example explanation ... well, with edits. --- exploration/percent-format.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 4080e4dda6..edcc4fe022 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -58,6 +58,36 @@ use one of the existing number-formatting functions `:number` and `:integer` wit or use the proposed _optional_ function `:unit` with an option `unit=percent`. Combinations of these approached might also be used. +### Unit Scaling + +There is a difference between _input_ scaling and _output_ scaling in `MeasureFormat`, +which is the model for the `:unit` function in Unicode MessageFormat. + +For example, an input of <3.5, `meter`> with `meter` as the output unit doesn't scale. + +If one supplies <0.35 `percent`> as the input and the output unit were `percent`, +`MeasureFormat` would format as 0.35%. +Just like `meter` ==> `meter` doesn't scale. + +However, if one supplies a different input unit, then percent does scale +(just like `meter` ==> `foot`). +The base unit is for such dimensionless units is 'part'. +In MF, a bare number literal, such as `.local $foo = {35}` +or an implementation-specific number type (such as an `int` in Java) +might be considered to use the input unit of `part` +unless we specified that the `percent` unit value or `:percent` function overrode the `part` unit with `percent`. + +With <0.35 `part`> as the input and the output unit of `percent`, the format is "35%". + +| Amount | Input Unit | Formatted Value with... | Unit | +|---|---|---|---| +| 0.35 | part | 0.35 | part | +| 0.35 | part | 35.0 | percent | +| 0.35 | part | 350.0 | permille | +| 0.35 | part | 3500.0 | permyriad | +| 0.35 | part | 350000.0 | part-per-1e6 | +| 0.35 | part | 3.5E8 | part-per-1e9 | + ## Use-Cases _What use-cases do we see? Ideally, quote concrete examples._ From c95919d8585123d278d16ad5fa147b1d92ed21fe Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Wed, 23 Apr 2025 07:18:05 -0700 Subject: [PATCH 13/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index edcc4fe022..804ed398f3 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -71,7 +71,7 @@ Just like `meter` ==> `meter` doesn't scale. However, if one supplies a different input unit, then percent does scale (just like `meter` ==> `foot`). -The base unit is for such dimensionless units is 'part'. +The base unit for such dimensionless units is called 'part'. In MF, a bare number literal, such as `.local $foo = {35}` or an implementation-specific number type (such as an `int` in Java) might be considered to use the input unit of `part` From a4b0b1b842c93326b39008e4edf6eb5d8edabf3d Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Wed, 23 Apr 2025 07:32:55 -0700 Subject: [PATCH 14/25] Apply suggestions from code review Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 804ed398f3..ff06845637 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -181,7 +181,7 @@ or scientific notation (1000000 => 1.0e6). _Pros_ - Uses an existing set of functionality - Might provide a more consistent interface for formatting "number-like" values -- Removes percentages from `:number` and `:integer`, making those functions more "pure" +- Keeps percentage formatting out of `:number` and `:integer`, making those functions more "pure" _Cons_ - `:unit` won't be REQUIRED, so percentage format will not be guaranteed across implementations. @@ -277,7 +277,7 @@ The value `0.5` formats as `50%` > .local $pctSaved = {50} > {$pctSaved :percent} > ``` -> Prints as `5000%`. +> Prints as `5,000%`. #### Optional Scaling Implementation automatically does (or does not) scale. @@ -288,7 +288,7 @@ There is an option to switch to the other behavior. > .local $pctSaved = {50} > {$pctSaved :percent} {$pctSaved :percent scale=false} >``` -> Prints as `5000% 50%` if `:percent` is autoscaling by default +> Prints as `5,000% 50%` if `:percent` is autoscaling by default #### Provide scaling via additions to `:math` Regardless of the scaling done by the percent formatting function, @@ -336,7 +336,7 @@ _Pros_ - Useful for other scaling operations _Cons_ -- Might require changes to digit size options, since negative exponents are a Thing +- Cannot use _digit size option_ as the `exp` option value type, since negative exponents are a Thing ##### Use `:math multiply` to scale From 7ab3bf0c0771a1ddce86e022876520c34b5afcae Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Wed, 23 Apr 2025 07:42:17 -0700 Subject: [PATCH 15/25] Update percent-format.md --- exploration/percent-format.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index ff06845637..9bc5c902f2 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -60,8 +60,9 @@ Combinations of these approached might also be used. ### Unit Scaling -There is a difference between _input_ scaling and _output_ scaling in `MeasureFormat`, -which is the model for the `:unit` function in Unicode MessageFormat. +This section describes the scaling behavior of ICU's `NumberFormatter` class and its `unit()` method, +which is one model for how Unicode MessageFormat might implement percents and units. +There is a difference between _input_ scaling and _output_ scaling in ICU's `NumberFormatter`. For example, an input of <3.5, `meter`> with `meter` as the output unit doesn't scale. @@ -225,11 +226,15 @@ You saved {$savings :percent} on your order today! _Pros_ - Least verbose placeholder - Clear what the placeholder does; self-documenting -- Consistent with separating `:currency` +- Consistent with separating specialized formats from `:number`/`:integer` + as was done with `:currency` _Cons_ - Adds to a (growing) list of functions - Not "special enough" to warrant its own formatter? +- Unlike `:currency`, because currency formatting depends on currency codes, + which in turn impact default fraction digits, and other presentation details. + Nothing like that applies to percents. --- From 0e9c442fafea45b4a27db006187f9bdb6b752aba Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Sat, 10 May 2025 09:57:49 -0700 Subject: [PATCH 16/25] Address 2025-05-05 call consensus In the 2025-05-05 call, we agreed to remove the proposed design so that we can commit the design document to the main line in the repo. --- exploration/percent-format.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 9bc5c902f2..8c88166a47 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -134,12 +134,7 @@ _What prior decisions and existing conditions limit the possible design?_ _Describe the proposed solution. Consider syntax, formatting, errors, registry, tooling, interchange._ -- Use a dedicated function `:percent` that scales by default. -- Provide an option `scaling` with values `true` and `false` and defaulting to `true`. -- Provide all options identical to `:number` _except_ that `select` does not provide `ordinal` value. -- Allow `unit=percent` in `:unit` that is identical to `:percent` in formatting capabilities, - for compatibility with CLDR units, - but document that this usage is not preferred. +(Awaiting WG consensus) ## Alternatives Considered From 377bcedfd552683ab8cf04e5106aef9bf5971e03 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 12 May 2025 06:58:22 -0700 Subject: [PATCH 17/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 8c88166a47..fb6838ad5f 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -188,7 +188,7 @@ _Cons_ --- -#### Use `:number`/`:integer` with `type=percent` +#### Use `:number`/`:integer` with `style=percent` Use the existing functions for number formatting with a separate `style` option for `percent`. (This was previously the design) From 863734be466c66705fafc55f192f6e5e07562167 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 12 May 2025 06:58:43 -0700 Subject: [PATCH 18/25] Update exploration/percent-format.md Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index fb6838ad5f..2d10203c81 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -264,7 +264,7 @@ The value `0.5` formats as `0.5%` > Example. > ``` > .local $pctSaved = {50} -> {$pctSaved :percent} +> {{{$pctSaved :percent}}} > ``` > Prints as `50%`. From 1186c958fa880b41b793630abdea0a8158ee8449 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 12 May 2025 07:05:14 -0700 Subject: [PATCH 19/25] Apply suggestions from code review Co-authored-by: Eemeli Aro --- exploration/percent-format.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 2d10203c81..6d221efa6a 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -181,7 +181,7 @@ _Pros_ _Cons_ - `:unit` won't be REQUIRED, so percentage format will not be guaranteed across implementations. - Requiring `:unit type=percent` would be complicated at best. + Requiring `:unit unit=percent` would be complicated at best. - Implementation of `:unit` in its entirely requires significantly more data than implementation of percentage formatting. - More verbose placeholder @@ -275,18 +275,23 @@ The value `0.5` formats as `50%` > Example. > ``` > .local $pctSaved = {50} -> {$pctSaved :percent} +> {{{$pctSaved :percent}}} > ``` > Prints as `5,000%`. #### Optional Scaling -Implementation automatically does (or does not) scale. -There is an option to switch to the other behavior. +Function automatically does (or does not) scale, +but there is an option to switch to the non-default behavior. +Such an option might be: +- An option with a name like `scaling` with boolean-like values `true` and `false` +- An option with a name like `scale` with + digit size option values + limited to a small set of supported values (possibly only `1` and `100`) > Example. Note that `scale=false` is only to demonstrate switching. >``` > .local $pctSaved = {50} -> {$pctSaved :percent} {$pctSaved :percent scale=false} +> {{{$pctSaved :percent} {$pctSaved :percent scale=false}}} >``` > Prints as `5,000% 50%` if `:percent` is autoscaling by default @@ -300,7 +305,7 @@ Extension of `:math` to support other mathematical capabilities would allow for >``` > .local $pctSaved = {0.5} > .local $pctScaled = {$pctSaved :math exp=2} -> {$pctSaved :percent} {$pctScaled :unit unit=percent} +> {{{$pctSaved :percent} {$pctScaled :unit unit=percent}}} >``` > Prints as `50% 50%` if `:percent` is autoscaling by default and `:unit` is not. From 81a923474b025af53e9c9f928cb15543ff6f3fc5 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 19 May 2025 08:45:33 -0700 Subject: [PATCH 20/25] Address removal of `:math` --- exploration/percent-format.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 6d221efa6a..7ccebeb7fd 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -50,8 +50,9 @@ Developers need to know which behavior will occur so that they can adjust the va > - `Intl.NumberFormat(locale, { style: 'percent' })` scales > - `Intl.NumberFormat(locale, { style: 'unit', unit: 'percent' })` does not scale -It is also possible for Unicode MessageFormat to provide support for scaling in the message itself, -perhaps by extending the `:math` function. +It is also possible for Unicode MessageFormat to provide support for scaling in the message itself. +Since we've removed the `:math` function (at least for now), this would have to be through either +the re-introduction of `:math` or through a specialized scaling function. An addition concern is whether to add a dedicated `:percent` function, use one of the existing number-formatting functions `:number` and `:integer` with an option `type=percent`, @@ -295,13 +296,15 @@ Such an option might be: >``` > Prints as `5,000% 50%` if `:percent` is autoscaling by default -#### Provide scaling via additions to `:math` +#### Provide scaling via a function Regardless of the scaling done by the percent formatting function, there might need to be an in-message mechanism for scaling/descaling values. -The (currently DRAFT) function `:math` was added to support offsets in number matching/formatting. -Extension of `:math` to support other mathematical capabilities would allow for scaling. +The function `:math` was originally proposed to support offsets in number matching/formatting, +although the WG removed this proposal and replaced with with an `:offset` function in May 2025. +Reintroducing `:math` to support scaling +or the proposal of a new function dedicated to scaling might address the need for value adjustment. -> Example. +> Example using `:math` as a placeholder function name >``` > .local $pctSaved = {0.5} > .local $pctScaled = {$pctSaved :math exp=2} @@ -322,9 +325,9 @@ _Cons_ instability into the message regime as new options are introduced over time. Compare with `java.lang.Math` -Two proposals exist for using `:math`: +Two proposals exist for `:math`-like scaling: -##### Use `:math exp` to scale +##### Use `:math exp` (`:exp`??) to scale Provide functionality to scale numbers with integer powers of 10 using the `:math` function. Examples using `:unit`, each of which would format as "Completion: 50%.": @@ -344,7 +347,7 @@ _Cons_ - Cannot use _digit size option_ as the `exp` option value type, since negative exponents are a Thing -##### Use `:math multiply` to scale +##### Use `:math multiply` (`:multiply`??) to scale Provide arbitrary integer multiplication functionality using the `:math` function. Examples using `:unit`, each of which would format as "Completion: 50%.": From 6399c838850ab05bc28b74e3f8ea4fb5afa40877 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Tue, 20 May 2025 12:50:54 -0700 Subject: [PATCH 21/25] Address 2025-05-19 comments In our most recent call, we discussed adopting the proposed design found in this commit. Note the addition of selector behavior. --- exploration/percent-format.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 7ccebeb7fd..9c425b9629 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -135,7 +135,30 @@ _What prior decisions and existing conditions limit the possible design?_ _Describe the proposed solution. Consider syntax, formatting, errors, registry, tooling, interchange._ -(Awaiting WG consensus) +Support the formatting of percent values as follows: + +- REQUIRE the `:unit` function for all implementations + - Only specific `unit` option values are required, initially the unit `percent`. + - The function `:unit unit=percent` does not scale the operand, e.g. `{5 :unit unit=percent}` formats as `5%`. +- REQUIRE the `:number` and `:integer` functions to support `style=percent` as an option + - The functions `:number` and `:integer` scale the operand, e.g. `{5 :integer style=percent}` formats as `500%`. + Note that the selector selects on the scaled value + (selectors currently cannot select fractional parts) + +> Examples. These are equivalent **except** that `:unit` does NOT scale. +>``` +> {{You have {$pct :number style=percent} remaining.}} +> {{You have {$pct :unit unit=percent} remaining.}} +> {{You have {$pct :integer style=percent} remaining.}} +>``` +> Selector example: +>``` +> .local $pct = {0.05 :number style=percent} +> .match $pct +> 5 {{This pattern is selected}} +> one {{You have {$pct} left.}} +> * {{You have {$pct} left.}} +>``` ## Alternatives Considered From 3bb7dad688924997f12212965ede6af681f0d591 Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 9 Jun 2025 06:38:28 -0700 Subject: [PATCH 22/25] Update exploration/percent-format.md Co-authored-by: Tim Chevalier --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 9c425b9629..82fe3bc4db 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -201,7 +201,7 @@ or scientific notation (1000000 => 1.0e6). _Pros_ - Uses an existing set of functionality - Might provide a more consistent interface for formatting "number-like" values -- Keeps percentage formatting out of `:number` and `:integer`, making those functions more "pure" +- Keeps percentage formatting out of `:number` and `:integer`, limiting the scope of those functions _Cons_ - `:unit` won't be REQUIRED, so percentage format will not be guaranteed across implementations. From 67ebc43f72ee90e968da943609031a23af33eb6e Mon Sep 17 00:00:00 2001 From: Addison Phillips Date: Mon, 9 Jun 2025 06:38:46 -0700 Subject: [PATCH 23/25] Update exploration/percent-format.md Co-authored-by: Tim Chevalier --- exploration/percent-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 82fe3bc4db..26020e73e9 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -327,7 +327,7 @@ although the WG removed this proposal and replaced with with an `:offset` functi Reintroducing `:math` to support scaling or the proposal of a new function dedicated to scaling might address the need for value adjustment. -> Example using `:math` as a placeholder function name +> Example using `:math` as a hypothetical function name >``` > .local $pctSaved = {0.5} > .local $pctScaled = {$pctSaved :math exp=2} From 4c884b614e9d91ce74512c2a80853a31c5dc7402 Mon Sep 17 00:00:00 2001 From: Eemeli Aro Date: Mon, 14 Jul 2025 21:47:58 +0300 Subject: [PATCH 24/25] Move proposed solution to be one of the alternatives --- exploration/percent-format.md | 55 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index 26020e73e9..ada7302e4b 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -7,6 +7,7 @@ Status: **Proposed**
Contributors
@aphillips
+
@eemeli
First proposed
2025-04-07
Pull Requests
@@ -135,30 +136,7 @@ _What prior decisions and existing conditions limit the possible design?_ _Describe the proposed solution. Consider syntax, formatting, errors, registry, tooling, interchange._ -Support the formatting of percent values as follows: - -- REQUIRE the `:unit` function for all implementations - - Only specific `unit` option values are required, initially the unit `percent`. - - The function `:unit unit=percent` does not scale the operand, e.g. `{5 :unit unit=percent}` formats as `5%`. -- REQUIRE the `:number` and `:integer` functions to support `style=percent` as an option - - The functions `:number` and `:integer` scale the operand, e.g. `{5 :integer style=percent}` formats as `500%`. - Note that the selector selects on the scaled value - (selectors currently cannot select fractional parts) - -> Examples. These are equivalent **except** that `:unit` does NOT scale. ->``` -> {{You have {$pct :number style=percent} remaining.}} -> {{You have {$pct :unit unit=percent} remaining.}} -> {{You have {$pct :integer style=percent} remaining.}} ->``` -> Selector example: ->``` -> .local $pct = {0.05 :number style=percent} -> .match $pct -> 5 {{This pattern is selected}} -> one {{You have {$pct} left.}} -> * {{You have {$pct} left.}} ->``` +TBD ## Alternatives Considered @@ -387,3 +365,32 @@ _Pros_ _Cons_ - Brings in multiplication + +--- + +### Why not both? + +Rather than choosing only one option, choose multiple parallel solutions: + +- REQUIRE the `:unit` function for all implementations + - Only specific `unit` option values are required, initially the unit `percent`. + - The function `:unit unit=percent` does not scale the operand, e.g. `{5 :unit unit=percent}` formats as `5%`. +- REQUIRE the `:number` and `:integer` functions to support `style=percent` as an option + - The functions `:number` and `:integer` scale the operand, e.g. `{5 :integer style=percent}` formats as `500%`. + Note that the selector selects on the scaled value + (selectors currently cannot select fractional parts) + +> Examples. These are equivalent **except** that `:unit` does NOT scale. +>``` +> {{You have {$pct :number style=percent} remaining.}} +> {{You have {$pct :unit unit=percent} remaining.}} +> {{You have {$pct :integer style=percent} remaining.}} +>``` +> Selector example: +>``` +> .local $pct = {0.05 :number style=percent} +> .match $pct +> 5 {{This pattern is selected}} +> one {{You have {$pct} left.}} +> * {{You have {$pct} left.}} +>``` From 99f176cef4a30fe674725915055a91582268cd1f Mon Sep 17 00:00:00 2001 From: Eemeli Aro Date: Tue, 15 Jul 2025 10:55:35 +0300 Subject: [PATCH 25/25] Apply suggestions from code review Co-authored-by: Shane F. Carr --- exploration/percent-format.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/exploration/percent-format.md b/exploration/percent-format.md index ada7302e4b..4dc958a816 100644 --- a/exploration/percent-format.md +++ b/exploration/percent-format.md @@ -225,13 +225,12 @@ _Pros_ - Clear what the placeholder does; self-documenting - Consistent with separating specialized formats from `:number`/`:integer` as was done with `:currency` +- Makes it possible to apply a `scaling` option to only percent formatting. _Cons_ - Adds to a (growing) list of functions - Not "special enough" to warrant its own formatter? -- Unlike `:currency`, because currency formatting depends on currency codes, - which in turn impact default fraction digits, and other presentation details. - Nothing like that applies to percents. +- Adds yet another numeric function, with its own subset of numeric function options. --- @@ -364,7 +363,7 @@ _Pros_ - Can be used for other general purpose math _Cons_ -- Brings in multiplication +- Increases implementation burden: multiplication must be handled on arbitrary numeric input types --- @@ -375,16 +374,15 @@ Rather than choosing only one option, choose multiple parallel solutions: - REQUIRE the `:unit` function for all implementations - Only specific `unit` option values are required, initially the unit `percent`. - The function `:unit unit=percent` does not scale the operand, e.g. `{5 :unit unit=percent}` formats as `5%`. -- REQUIRE the `:number` and `:integer` functions to support `style=percent` as an option - - The functions `:number` and `:integer` scale the operand, e.g. `{5 :integer style=percent}` formats as `500%`. +- REQUIRE the `:number` function to support `style=percent` as an option + - The function `:number`scales the operand, e.g. `{5 :number style=percent}` formats as `500%`. Note that the selector selects on the scaled value (selectors currently cannot select fractional parts) > Examples. These are equivalent **except** that `:unit` does NOT scale. >``` > {{You have {$pct :number style=percent} remaining.}} -> {{You have {$pct :unit unit=percent} remaining.}} -> {{You have {$pct :integer style=percent} remaining.}} +> {{You have {$scaledPct :unit unit=percent} remaining.}} >``` > Selector example: >```