-
-
Notifications
You must be signed in to change notification settings - Fork 36
Selection method expectations #425
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
Comments
Some parts of this have been surfaced previously (e.g. #368 (comment), #420 (comment)), but I don't believe that we've established consensus on this topic. It also has not been necessary for us to address before now, as we've been thus far working without any prepopulated registry. I think this topic is a blocker for including any matching function implementations in our base registry. My own preference would be for the I also believe that allowing the exact same expression to be used for both selection and formatting would make it likelier for developers to use a local variable for it, as in:
|
These are good thoughts. I think they might need to be broken into separate concerns.
Much of your commentary is about choosing the default behavior of an unspecified selector, e.g. What you call We might say that non-default default selection is up to the implementation. That is, ICU4J's implementation might use reflection to decide that
On the one hand, I think there is a certain elegance to what you suggest above. Maybe the veritable zoo of time formatters (regular, relative, duration, etc.) or number (regular, currency, measure, percent, ordinal, etc.) is a quirk we can avoid via the judicious use of options. On the other hand, there are multiple different types of selection that can be applied to e.g. a number or e.g. a time value, just as there are multiple types of formatting that can be applied. There is also the problem of identifying what selector or selector behavior is intended when the argument is not available. For example, in your example above, For these reasons, I tend to think that separate functions for different types of selection might win out against cramming everything into single keywords.
We will describe the registry in the spec in functional terms. Individuals or platform implementations might then use that to define valid functions that we collectively might disapprove of. But our default registry should meet a high bar and should model the right behaviors. How do we decide? What model should we use? We need to document these, both to guide future registration requests, and to ensure that we understand it ourselves. |
I am sure this is something we covered before:
Absolute disagreement :-) So:
would return "1 foo" but:
would return "bar foos"? So now to figure out what will happen at runtime (or how to translate) one must know the type of the argument AND look at ALL the keys listed in the message? This is one of the reasons I proposed that selectors ALWAYS have a function. This becomes every messier in languages like JavaScript, or Python, where types can easily change "by mistake". |
I do believe (and argued before) that they are distinct.
And a collator doing numeric-aware sorting ("3 files" sorting before "21 files") should understand a bit about parsing numbers (including non-ASCII digits), and maybe understand a bit about breaking at word limits, for example. If we think in terms of interfaces, the signatures are different.
Looks pretty different. Same as in programming, a class might implement two interfaces, if it chooses to do so. And can also register with the same name, or different (pseudocode, even if it looks like Java):
Some might have a different class for By making selectors and formatters separate we allow implementations to do what they think it works best for them, internally, without forcing those decisions on others, or exposing those decisions. Note that in order to make the selection on 1 formatted as "1" ("1 dollar") vs "1.00" (1.00 dollars) we don't actually need to format. It is enough to look at the options (min/max fractional digits, etc). It only needs to understand a small subset of what the formatter does. So plural selection is not as tied to a number formatter as it might seem. |
The problem we are trying to solve is that if you format numbers (and
other cases with numeric components, like amounts with units) with
different options than you select, you will get the wrong answer.
If we had multivalue return types, then you could have it all be crystal
clear:
let $countFormat, $countSelector = {$inputCount :number ... options}
match {$countSelector}
when ... {...{$countFormat}....}
or if you had them separated you could do
let $countFormat = {$inputCount :numberFormat ... options}
let $countSelector = {$inputCount :numberSelect ... options2} // and have
likely failure if options2 ≠ options
match {$countSelector}
when ... {...{$countFormat}....}
What we're trying to do is hide that complexity under the covers, with:
let $count = {$inputCount :number ... options}
match {$count}
when ... {...{$count}....}
where logically speaking, $count internally has two values, a formatted
number, and a selector appropriate for that formatted number.
…On Tue, Jul 18, 2023 at 10:20 AM Mihai Nita ***@***.***> wrote:
Are formatters and selectors distinct? If they are no distinct, when do we
lump or split functionality? If they are distinct, can they share keywords
(e.g. number-selector and number-formatter)? (We will need to deal with
naming precedence rules in any event)
I do believe (and argued before) that they are distinct.
If we think in terms of interfaces, the signatures are different.
They take different arguments, and do different things.
- formatting takes the operand + options and returns a
"format-to-parts" thing, or a string
- selectors takes the operand + options + existing matching keys and
returns which key is best
Intl.PluralRules and Intl.DateTimeFormat are not the same kind of classes.
Same as in programming, a class might implement two interfaces, if it
chooses to do so.
And can also register with the same name, or different (pseudocode, even
if it looks like Java):
class NumberFormatAndPlural implements ISelector, IFormatter { ... }
registry.addSelector("plural", NumberFormatAndPlural.class);
registry.addFormatter("number", NumberFormatAndPlural.class);
Some might have a different class for PluralSelector implementing Selector,
which might delegate some functionality to a formatter, or not.
For example a collator doing numberic-aware sorting ("3 files" sorting
before "21 files") should understand a bit about parsing numbers (including
non-ASCII digits), and maybe understand a bit about breaking (word limits,
for example).
That does not make collators and formatters / breakiterators the same
thing.
By making selectors and formatters separate we allow implementations to do
what they think it works best for them, internally, without forcing those
decisions on others, or exposing those decisions.
Note that in order to make the selection on 1 formatted as "1" ("1
dollar") vs "1.00" (1.00 dollars) we don't actually need to format. It is
enough to look at the options (min/max fractional digits, etc).
We don't need all the options formatting needs, we don't need to know what
digits or thousand separators to use, etc., and we don't need to format at
all.
So plural selection is not as tied to a number formatter as it might seem.
—
Reply to this email directly, view it on GitHub
<#425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACJLEMGOK7YBAQOHIDHWPO3XQ3AVPANCNFSM6AAAAAA2LFG2O4>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
I think I mostly agree with your questions as presenting nicely orthogonal facets of this topic. Some specific comments and replies below.
Yes. For selection, they work the same. The key difference is in how we're asking people to conceive of the function. Is it a "selection function" or is it a type cast/assertion?
We ought to also take into account their frequency. For example, in my experience it is exceedingly rare for a selector on a number not to be a plural category selector. I do think that we need to ensure that non-plural number selection is possible, but I do not believe that it's a very common thing. If anyone has examples or data on this that they could share, that would be invaluable.
I agree that this is a potential issue for a message like (c) where the type of the selector is not at all defined in the message. In the Or did you intend to address that in the last sentence? It cuts off a bit abruptly.
Strong agreement here; it's why I raised this issue explicitly.
Yes, we've discussed parts of this topic before, but have not concluded those discussions.
That would require introspection of the variant keys to determine how selection happens. I am not proposing for that to happen, and I don't think we should make that possible.
If so, should we also always require a function for placeholders to avoid such confusion?
I don't think I follow how using the same MF2 keyword imposes a restriction on implementations. Following your pseudocode example, why wouldn't this also work?
I agree, the options bags are not exactly the same. Plural selection also depends on the type of selection we're doing (cardinal vs. ordinal) which a formatter won't need to care about. But they don't conflict either, and can be combined so that a formatter cares about some of them, while a selector cares about a different subset.
Yes. And going further, to establish a good precedent and model for future/custom selectors and formatters to follow so that they don't end up making a similar mistake.
You know, going a slight step further, we could simplify the syntax a little and make this mistake even harder to make:
The change here is that |
I think I'm starting to agree with this. Revisiting my example messages from above, I now think that here:
the message should be considered to contain a data model error, and to format as
For any translation tooling to work with that, it either needs an annotation, or we really do need a semantic comments spec that we could rely on defining the value type. Regarding
This is how gender selectors (either personal or grammatical) are currently done in MF1 and other formats that support such, and with the But it's not fine. We are providing no information here about what type of value we're selecting on, and whether there might be a locale dependency on the appropriate keys. Finnish, for instance, does not use either grammatical or personal gender. If instead the message read as:
then it's much more obvious how we're treating |
A few minor comments. (emphasis added)
I think it is important to be careful of frequency arguments. Strings with replacements are "rare" compared to strings without. String with two selectors are rare compered to those with only one. Etc. I have plenty of examples of non-plural numeric selection that should be handled by the message formatters and not by writing spaghetti logic. I should note that virtually all cases of inserting a number into a string should (also) involve a plural selector (for the grammatical matching). The example I use for this is one you can observe in most driving direction applications:
How does a translation tool which only has access to the message resource know that
I see that you're trying to put up guardrails around common internationalization mistakes that developers make, such as "reinventing plurals" or (later in your examples) "inventing their own gender format". Those examples not only look valid---they are valid. It will always be possible to write non-internationalized messages using our formatters, either directly (by abusing tools such as I think we should have reasonable guardrails, but I disagree with your "too valid" assertion. The antidote to your examples is making the correct APIs obvious and available and then doing education. Everyone writes the following (generally as
FWIW, I do think that we might not call |
Related to #42 ? |
About:
I agree it is problematic, but I don't think it can be prevented in syntax only.
I think can only be detected at higher level, something that can have a high level view of the whole message. 1: "You are at the last credit!" So we can't safely forbid it in syntax, or throw at runtime, because of false positives |
I think that building something like that we have to make a decision on the currency amount (a number), but the selector is not a plural, it is a "decide based on the sign of the number" selection. Maybe not common. But also maybe a chicken-and-egg thing. Might be more common if this would be possible. Another example: showing different things depending on the day of week
The day of week can be an enum, but a lot of APIs use an int for that. Or can force developers to convert that number to a string, meaning a buffer allocation, and int-to-string conversion, only to be able to do a textual select. The most natural thing is to select on that number. |
Agree.
If I add a Worse, I don't even know if I have to expand this for the plural cases, for instance in a CAT tool. So I can't validate anything, in lint, or in CAT tools. |
I am not 100% against, and it would be cleaner, and with more chances for validations. It is pretty much everywhere. I agree that this would make things inconsistent: selects (with forced function) and formatting placeholders (with a default function decided by type) But a human can usually translate something with a placeholder of unknown type. If all I see is this:
And I don't know the type of foo, I don't know (as a human translator, or as a CAT tool, or a lint tool) if I have to add gendered forms, or plural keywords, or grammatical cases, or something else (sorry, same argument as above, in a different form).
Yes, that would also work. I can in theory do a plural select on non-numbers, for example on a list (and yes, probably the plural decision would be on the number of items in the list). Or on a int range, and the decision might be on the difference between end and start (yes, still a number, but I force the dev to calculate it and put it in some argument) TLDR: I can do plural selections on non-numbers, and and I can do non-plural selections on numbers.
I am 150% on board with that, if we add a And not that I agree now, I coded it that way one year ago: :-) |
I don't feel strongly about But I don't think that using I strongly believe that sooner or later we would need an explicit standard A tool (and a human) will instantly know that this:
needs to add the gender forms required by their language. With We can also ask developers to add the gender variants in source, even if the source language (let's say English) does not need them. To summarize, I see gender similarly to booleans or enums in programming languages. |
My intent with the frequency argument is to follow a version of the "make the easy jobs easy, without making the hard jobs impossible" dictum with our language design.
With a
But this is probably a sidetrack from the main thread here.
We might be referring to different messages here? Before your earlier comment, the only "
There,
I would prefer
To make that work, I think you'd need something like a
Is this an appropriate use of
I think I'm still missing something here. What do you mean by "the visible, public signatures"?
I'm pretty sure that the only way we could drop the braces from
That's exactly my point! We want to encourage the development of of explicitly clear (grammatical or personal, not sure which)
But with
In neither case would a translator or their tooling get any info from the above about what the possible keys might be, but with |
Nothing helps with gender except a gender selector. Everything else will be people hacking something together based on their (probably insufficient) thinking about it. This is like the way people used What
Full agreement, but the registry is fairly static. Rather than look at the bad examples, let's look at valid ones:
Just like an The other thing about |
No, actually, that's not the same thing. In my example, the message morphs from: "You have 11 km to go" Either you need a "less than 10 message" or you need a "less than 10 selector". Make sense? I proposed Another alternative that occurs to me from @mihnita is I think it is important that there be a selector that developers can use to perform selection against data values without going to the registry.
I think I'd like to propose the classical comparison operators for the default registry?
In the PR you noted that requiring an annotation in the syntax (my "option b") would require a separate expression processor, which is true but could probably be mitigated. My other option was to have a defined default for the selector function when it isn't specified. The option you present is my option "b" but with the allowance that the selector can be declared in an declaration. That is, this message is not valid:
... but this one is:
That's a lot of state to be carrying for each declaration (in case it is used later in a Anyway, I think we have three options: (a) there is a default selector and it is Are there any others? |
I think it should be easy to implement a custom function doing that.
Yes, that would be a custom selector function. But the main point of the argument is: there are reasonable non-plural selector functions that work on numbers.
The stuff that I see as a developer.
The two
Yes, but that only moves the requirement to always have function in selector (what I suggest) What I mean is: it's easy to force in syntax that
Than why not also encourage them to use
Probably not :-) They don't spend time in it, they probably never read the spec.
That was not the point I was trying to make. The point I was trying to make is that I am on board with
But I should not be FORCED to declare that local variable.
This is close enough, although a bit more verbose, it is still an almost 1:1 mapping:
This feels like too much "ceremony" to get the same result:
|
In some languages it would also be trivial to make it work for enums.
:-D I don't know. Might be a bit too early? I was think (even the more controversial)
Not saying it is a good idea. |
I think your summary is right on:
I think (c) is harder (impossible) to enforce in syntax, would require a linter. It is is not in syntax it is also harder to detect / highlight as a problem in editors that offer "real time error detection". So I'm OK with (b), and (b) + (a) (function required, if not then :string / :equal is implied) With a slight preference for (b) without (a), because (a) means that the syntax / engine rendering MF2 has to know about the special method Solvable, but a bit unclean. |
Unfortunately github doesn't have threads, which would make this easier to follow!
is a terrible example, because it assumes that all languages measure distances the same way. There are probably examples illustrating :lt, but this isn't a good one to use.
Firmly agree! |
I left out the measure units part of the example to focus on number selection and formatting. FWIW, I didn't recreate the full example here because I thought it would be too baroque (it is also the example of an MF1 "very complicated message" that I used in my IUC presentation calling for the creation of this WG--that version selected independently of locale between SI and customary units)...... 😛
MF2 can be registry independent in terms of well-formed messages, but cannot be fully independent if we normatively require a default registry (will we?). I think it is reasonable in the formatting part of the spec to require:
I could be okay with (b). My goal in enumerating the options was to ensure that all of them were in one place for a discussion (perhaps Monday). |
The downside of that is that it is fragile. Take the following: match {$count} If someone passes in an integer with value 1, this will fail. I think it would be better to require an an annotation somewhere, that is, either: A. |
Requiring an annotation in the selector (like #431 proposes) doesn't prevent errors caused by using non-matching functions.
Similarly, we can't prevent errors due to matching functions being used inside placeholders:
We'll need to handle such cases on runtime anyways. I'd like to propose that we design the behavior of formatting and selection around the concept of wrapper interfaces around the passed values. If someone passes in an integer
Crucially, all functions would be required to return an instance of This way, in all of The reason why I think it's important to talk about this now is that it seems like we're trying to add some sort of static typing to arguments flowing through messages, but just to selectors, because we also want placeholders to be typed dynamically (and loosely). And because messages are not compiled, the only place to enforce static typing is during parsing: either as a On top of that, the presence of local declarations makes static typing via
...while also I'd expect it to not require So we're left with runtime
My position then is to:
|
Yes. There's more to quibble about here, but it's besides the point.
I agree. I just want the developer to feel a little dirty when doing that.
This would encourage packaging logic into messages, rather than the calling code. Do we really want to do that? I would much rather add a
Yes, actually. Doing so would strongly guide a user to consider the annotation of a selector as a "select function" rather than as something like a constructor. This is related to what we're asking our users to consider to be the "resolved value" of an expression. For now, a user can consider an expression just by itself, irrespective of where in a message it shows up. If we syntactically require an annotation on every selector, then they'll need to consider where an expression is before considering its meaning. To use
My concern here is that this message lets a localiser control whether the shop is "open" or "closed" on a Saturday. I would think that we'd prefer something like:
or even two entirely separate messages.
Yes, they need to be supported as non-default selectors. My point is that when a number is used as a selector, it is reasonable to assume by default that it's being used for plural selection.
With Fluent, this has not appeared as a concern. In that format, a
In my PR #431, I propose it as a data model error. We already have a few, comparing the selector and variant key counts. This has comparable complexity with those.
What would be your preferred alternative for the above? With out current syntax, it ought to have |
We might allow localization to add options beyond the ones from the source. Or not. But if you don't trust your localizer, you have bigger problems than that. We try to help localization (with validation, lints, etc) by preventing non-intentional mistakes.
I get that. And my take is that number is not something to use as a selector.
I've shown it more than once:
It is a plural selector, taking a number formatter as an operand. And it can look at it's parameters, and input, but does not need to invoke it. Which also allows one to add selectors like If we think about By trying to make |
The way to look at it is: The function is part of the public API; its signature is defined in the registry. The runtime type is private and is not described in the registry. In fact, implementations don't even have to use any runtime types, as long as the behavior is the same as specified. |
@mihnita gives an example:
This looks great, and I think it should be how we recommend messages are built. I like it that it demonstrates the need for I also believe that using a naked selector should be possible, i.e. the following message should not produce a syntax nor a data model error:
If the If the
|
I mostly agree with your reply above, but...
I am concerned about having type-based selection in a type-less system:
The above is only a plural selector if In MF1, the selector is always named. Formatters can be inferred from types, but never selectors. This does not mean that we have to require the selector. But how do I know that my variants will work as intended?
Message selection logic? Absolutely I would want message selection logic in messages. I agree about booleans, but I have found that enumerated sets are super common. When a specific message varies content based on a data value, developers often want to use an
This message avoids the temptation to use MessageFormat to do string concatenation (I won't explain why these are bad messages):
|
The way to look at it is: :number is a constructor function which returns
an instance of some runtime type, which wraps around the raw value of $count,
stores options, and can format and match.
I agree; that's the way I think of it also. Moreover, I think that instance
is what you are passing in to a further 'let'. So the following works just
fine.
let $foo = {$count :number}
let $bar = {$foo}
let $baz = {$bar}
match {$baz} ...
…On Thu, Jul 20, 2023 at 8:35 AM Stanisław Małolepszy < ***@***.***> wrote:
The way to look at it is: :number is a constructor function which returns
an instance of some runtime type, which wraps around the raw value of
$count, stores options, and can format and match. The exact interface of
this runtime type is implementation-specific, but I think it will help in
our discussions if we admit that it exists.
The function is part of the public API; its signature is defined in the
registry. The runtime type is private and is not described in the registry.
In fact, implementations don't even have to use any runtime types, as long
as the behavior is the same as specified.
—
Reply to this email directly, view it on GitHub
<#425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACJLEMBLZOC7POUQ6BQYSD3XRFF4RANCNFSM6AAAAAA2LFG2O4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I am concerned about having type-based selection in a type-less system:
I think that is a valid concern. So the question is what the behavior of
the following
match ($count) {
when few {...}
when * {...}
The fundamental question is: can an API for language with reflection (where
API can determine datatypes) interpret this as matching the "few" case when
the value of $count is the integer 3? Taking C as a paradigmatic
unreflective language:
int x = 3;
formatMessage(patternString, x)
There are a few possibilities:
1. Yes, it can, and so the results will just be different for Java than for
C (for example).
Pro: simpler for reflection languages
Con: no interop between reflection and non-reflection languages
2. No, it can't. It must interpret it (since there is no :number) as a
string match, and will pick the "*" case.
Pro: slightly more complicated for reflection languages; you need to have
the :number on count somewhere.
Con: interop between reflection and non-reflection languages
3. We require that the unreflective APIs for formatting MF2 specify
datatypes in their argument lists
Pro: simpler for reflection languages, maintains interop
Con: Hmmm, this needs more thought. This is just a rough
stream-of-consciousness take:
At first I was thinking that this might be an excessive burden for
unreflective languages. But C is pretty painful, with printf needing
special format specifiers to allow for variable arguments (%s, %d, %f, ...)
for it to work at all, and a mismatch will fail badly. A C API is going to
need some help with this *anyway*, because the code that handles :number
will need help to determine whether a parameter is a double or integer or
... And I don't think we want to build that into the way that message
format works. But it will also need *some* way to associate the parameter
IDs in the message to a particular argument, so C APIs are going to need
some help with that as well. My C is very rusty, but it might be something
like the following.
Args args;
MFaddInt(args, "$count", 3);
MFaddString(args, "$deviceType", "phone");
formatMessage(patternString, args);
…On Thu, Jul 20, 2023 at 8:47 AM Addison Phillips ***@***.***> wrote:
@eemeli <https://github.com/eemeli>
I mostly agree with your reply above, but...
Yes, they need to be supported as non-default selectors. My point is that
when a number is used as a selector, it is reasonable to assume by default
that it's being used for plural selection.
I am concerned about having type-based selection in a type-less system:
match {$count}
when * {You have {$count} items}
The above is only a plural selector if $count is a number. I don't know
if my translation tool should explode the plural to generate few and many
variants unless I know it is a number. The name count doesn't help
(translation tools can't read and the name might not be an obvious number
anyway). Similarly, there can be selectors that use the keywords reserved
by other selectors: when one is not owned by plural exclusively.
In MF1, the selector is *always* named. Formatters can be inferred from
types, but never selectors. This does not mean that we have to require the
selector. But how do I know that my variants will work as intended?
This would encourage packaging logic into messages, rather than the
calling code. Do we really want to do that? I would much rather add a
:boolean instead.
Message selection logic? Absolutely I would want *message selection*
logic in messages. I agree about booleans, but I have found that enumerated
sets are super common. When a *specific* message varies content based on
a data value, developers often want to use an enum (which they already
have) or dataset to power it:
match {$deviceType}
when phone {Your phone is ready to use.}
when tv {Your TV is ready to use.}
when tablet {Your tablet is ready to use.}
when headphones {Your headphones are ready to use.}
when * {Your device is ready to use.}
This message avoids the temptation to use MessageFormat to do string
concatenation (I won't explain why these are bad messages):
{Your {$deviceType} is ready to use.}
{Your {$deviceType :getDisplayName} is ready to use.}
—
Reply to this email directly, view it on GitHub
<#425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACJLEMGQWPU6UPZZTJDCREDXRFHKZANCNFSM6AAAAAA2LFG2O4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
FYI, (3) is exactly what the Rust implementation of Fluent does: let mut args = FluentArgs::new();
args.set("name", FluentValue::from("John"));
// (snip)
let value = bundle.format_pattern(&pattern, Some(&args), &mut errors); |
That said, I think that in your example:
…even when the implementation learns about That would be a job for the Matching against the “few” key requires plural selection, and I agree with the position that @mihnita expressed before, that it should be possible to implement plurals outside the core engine of the implementation. Consequently, we shouldn’t make plural handling the default for naked selectors. |
Sorry, I omitted that it being formatted for a specific locale (eg Czech)
…On Thu, Jul 20, 2023 at 11:25 AM Stanisław Małolepszy < ***@***.***> wrote:
That said, I think that in your example:
match ($count) {
when few {...}
when * {...}
…even when the implementation learns about $count being an integer, we
should not select the “few” case.
That would be a job for the :plural selector function. Without it, I’d
like $count to resolve to an instance of an implementation-specific
runtime type for integers, which can match against literal keys that look
like other integers.
Matching against the “few” key requires plural selection, and I agree with
the position that @mihnita <https://github.com/mihnita> expressed before,
that it should be possible to implement plurals outside the core engine of
the implementation.
—
Reply to this email directly, view it on GitHub
<#425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACJLEMCUQZLBHKQETTOLDL3XRFZYLANCNFSM6AAAAAA2LFG2O4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
The problem is not with the runtime of reflective vs. unreflective languages. The problem is with the translation time when the argument type cannot be known without some sort of assertion present in the body of the message itself. It also does not matter what the calling code does because the calling code is invisible to the message. Inference of |
On Thu, Jul 20, 2023, 11:49 Addison Phillips ***@***.***> wrote:
@macchiati <https://github.com/macchiati>
The problem is not with the runtime of reflective vs. unreflective
languages. The problem is with the *translation* time when the argument
type cannot be known without some sort of assertion present in the body of
the message itself. It also does not matter what the calling code does *because
the calling code is invisible to the message*.
Good point. That also means inference for a formatter, tho.
Inference of plural for a selector cannot depend solely on the use of
plural's reserved keywords unless plural is going to be baked into the
specification (and no other formatters allowed to use zero/one/two/few/many
as their outputs). Numbers are important, to be sure, but they are not the
only types that can be selected against.
I never held that position.
… —
Reply to this email directly, view it on GitHub
<#425 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACJLEMCYEWA6VARTSTNQPETXRF4U5ANCNFSM6AAAAAA2LFG2O4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
It does, although formatters generally don't require translation tools to do something different with the placeholder. And implementations are more forgiving of unspecified formatters (for example, reflecting the type).
No, you didn't. But some readers might think that this is implied by inspecting the variant list. I wanted to call it out. |
I agree that these kind of errors can't be detected based on syntax only. But a linter would have access to the registry, can detect the errors you describe.
Sure, by throwing (or whatever error reporting mechanism is most natural for the implementation). |
About C++ (no runtime type) and Rust ( ICU4C handles this very similar to Rust. And we use the constructors: |
In fact I would be more worried about JavaScript and types. It is relatively easy to mess up the type in JavaScript and pass a string when you think it is an integer, or the other way around. The chances the So this would return "1 files" if
Because the real selector function to apply only depends on the runtime type. |
@mihnita writes:
Linting is not required. While we will strongly recommend it and we make an effort to make it powerful, we must also accept that some users may not want or be able to perform it. Consequently, the runtime must handle any message that didn't produce syntax or data model errors. My point above is that making a missing selector annotation a data model error doesn't help in the absence of proper registry-enabled linting. Therefore I claim that naked selectors should be considered well-formed and valid, but we should recommend against them by giving compelling reasons:
|
If I'm reading this thread correctly (as I try to summarize for the 2023-08-14 telecon agenda), I would make the following observations:
Given the above, is that enough to close this issue in favor of default registry tasks? Is there any specification or syntax change that needs to occur if functions handle this? |
Marking |
In the following, the (a), (b), etc. may be used to refer to individual messages.
For formatting, I believe that it's relatively uncontroversial to expect that with an en-US message (a)
formatting it to a string with
{ foo: 'bar' }
would result inFoo is bar
while formatting it to a string with{ foo: 1234 }
would result inFoo is 1,234
rather thanFoo is 1234
.In other words, we would expect a numerical value to be formatted according to the current locale, even if the type of the value is not made explicit in the message.
Separately, I also believe that it's almost as uncontroversial to expect that with an en-US message (b)
formatting it to a string with
{ foo: 'bar' }
would result inFoo is bar
.However, going further from this I believe we encounter less agreement. Specifically, with an en-US message (c)
should formatting it to a string with
{ foo: 1 }
result in1 foo
or1 foos
?In fact, we may disagree on the results even with an en-US message (d)
when formatting it to a string with
{ foo: 1 }
; should that result in1 foo
or1 foos
?On a related note, we probably do want to define what happens when an en-US message (e)
is formatted with
{ foo: 1234 }
, because there an argument could be made for any variant.I think we should make explicit determinations
As I see it, this is in part a discussion on how do we want to conceptually present our selection or matching expressions. In MF1, one of the keywords
select
,plural
,selectordinal
is always required. In MF2, we only usematch
. Therefore we've effectively left it open so far whether with regard to selection we want to use methods that imply that we are performing e.g. "plural selection" or "select selection" as in MF1, or if we're performing "selection on a number" or "selection on a string".In #420 we are adding at least the
number
anddatetime
formatting functions to our base registry. I think at least one of the following additional functions is needed to deal with selection:plural
select
string
With just
plural
, we would in general default to "select selection" and require its explicit use for plural category consideration. The (e) message would still require some special consideration of numbers.With just
select
, we would default to "plural selection" for numbers and "select selection" otherwise. Usingselect
on a number would explicitly opt out of its plural category consideration, and would need to define what happens in (e).With
string
, the behaviour would in practice be the same as withselect
, but the conceptual sense of what's happening with expressions used for matching is different: the input value is in a sense cast to the given type, which comes with given selection behaviour.The question of whether to require some explicit function on each selector (i.e. the difference between messages (c) and (d)) may be considered separately. For example, one of
plural
/select
ornumber
/string
could always be required.The text was updated successfully, but these errors were encountered: