Skip to content

Currency and unit conformance #1071

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

aphillips
Copy link
Member

Fixes #1009

Makes currency codes case-insensitive more clearly. We used a squidgy "SHOULD" before in spite of the ABNF provided.

Make units either CLDR identifiers or impl-defined types (SHOULD->MUST).

This is consistent with the stability policy (no new error is specified, no valid message becomes invalid, and :unit is DRAFT)

Fixes #1009 

Makes currency codes case-insensitive more clearly.

Make units either CLDR identifiers or impl-defined types (SHOULD->MUST)
@aphillips aphillips added functions Issue pertains to the default function set normative Issue affects normative text in the specification labels Apr 14, 2025
@@ -257,8 +257,7 @@ Using this _option_ in such a case results in a _Bad Option_ error.
The value of the _operand_'s `currency` MUST be either a string containing a
well-formed [Unicode Currency Identifier](https://unicode.org/reports/tr35/tr35.html#UnicodeCurrencyIdentifier)
or an implementation-defined currency type.
Although currency codes are expected to be uppercase,
implementations SHOULD treat them in a case-insensitive manner.
Currency codes are case-insensitive.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This leaves it unclear what the resolved value is. Could we be more explicit?

Suggested change
Currency codes are case-insensitive.
The resolved `currency` value is normalized to upper-case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a reminder, even ASCII letters have locale-sensitive case folding exceptions (Turkic languages).

Do we need to specify that the resolved value is uppercased? Mostly we treat the operands as immutable. We don't have to require that implementations perform the case fold operation. It's a good idea to do it to save later processing, but we can't really test it at the MF level except to say that a value with usd is as functional as one with USD.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should specify the casing, so that it's clear in a message like

.input {$n :currency currency=Usd}
{{{$n :foo:bar}}}

what currency value the :foo:bar function handler will see.

Suggested change
Currency codes are case-insensitive.
The resolved `currency` value is locale-insensitively normalized to upper-case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a variety of quibbles with the suggestion, starting with not using the defined term resolved value. Also, we allow implementation-defined (currency) types in this option also. Since the literals must be ASCII letters, we can use Unicode's casefold algorithm. Perhaps:

Suggested change
Currency codes are case-insensitive.
Currency codes are case-insensitive.
If the value of the `currency` _option_ is a _literal_, the _resolved value_ MUST be case-folded to uppercase.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why limit the case-folding to literal values only? Why should the resolved value be different for $a vs $b?

.local $cc = {eur}
.input {$a :currency currency=eur}
.input {$b :currency currency=$cc}
...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value would have been resolved before reaching the function. So it is either resolved as a literal or as an implementation-defined type. We can't uppercase a Currency object, but we can on a literal. Note that your examples are in the MF processor space, but this directive is inside the function handler.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't currently have any place in the spec that defines specific behaviour based on whether a value originates from a literal, and I would very much prefer not adding anything like that. The restriction on :number select makes sense and is only about the immediate option value in part to avoid needing to track the origins of variable values like this.

Given that we say that

The resolved value of a text or a literal contains the character sequence of the text or literal after any character escape has been converted to the escaped character.

The definition here ought to limit its impact not on whether the option's resolved value came from a literal, but on whethe or not it contains a character sequence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
functions Issue pertains to the default function set normative Issue affects normative text in the specification
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEEDBACK] Conformance for currency and unit should be more strict
2 participants