I wonder, are issues like these easier to manage with sentences structured like: “Number of foos scanned: 1”, or “Number of foo/bar scanned: 3/10”? I know it at least makes the plural issue go away for English (as both 1/2 work with a colon).
It is equally unnatural in all languages, therefore the best possible solution. It is worse than many impossible solutions, but they are, you know, impossible.
And, people have become used to it, so for younger people it seems perfectly normal; and everybody who hates it either doesn't use computers, or will die soon enough.
Since it does not actually hasten their death (or deaths -- a fine point), it is the clear winner.
It seems like Mozilla Fluent is a more sophisticated and modern attempt to solve these problems. It is still very new but works with browser and node javascript.
The article covers this, I recommend giving it a more careful read. Let's say you went this route. You've covered English and a handful of other languages (which have a special pluralization rule for 1, then everything else). So two numbers in the string, four branches. That's not so bad eh?
Now add branches for Brazilian Portuguese and Lingala, which has different strings for 0 or 1, not just 1.
Now add branches for Latvian and Latgalian, which use different strings when the number ends in 0, and still more different strings when the number ends in 1, except for 11.
Now add branches for Slovak and Czech, which don't just have different strings for 1, but additional strings for 2–4.
Now add branches for Irish Gaelic, which has different strings for 1, more for 2, yet more for 3–6, and again different strings for 7–10.
Now add branches for Arabic, which has different strings for 0, more strings for 1, other strings for 2, more strings for numbers ending with 03-10, additional strings for numbers ending with 00-02, excluding 0-2, and then everything else.
That's not even all of them. Who's peeing the bed now?
If you take the branch approach, you'll have hundreds of cases hardcoded into your source code for the languages you want to support. If instead the branches are in your i18n message syntax, each localized message can contain only the branches needed by that language, and your source code doesn't change at all – it just provides the numeric arguments to the i18n message itself to decide what to do with.
Localisation is one of several cases where I've come to the conclusion that frameworks that are supposed to help you end up doing more harm than good. What you really want is to express a bunch of functions that conform to a common interface: you pass in a number of files and a number of directories and you get back a user-facing string.
But we already have a very well-optimised system for expressing functions: whatever programming language we're actually working in. We already have the concept of a bundle of related functions that implements a particular polymorphic interface: a class.
Make an interface that represents what you need each translation - that is, language implementation - to provide. Write implementations of that interface, in collaboration with your translators (if your language doesn't let you write code in a way that a reasonably intelligent translator can read and verify, if not write, get a better language). Less awkward than gettext, and far more effective.
Many translators aren't comfortable with editing source code. They want to get a file, e.g. in XLIFF format [1], which they can then load into their translation management system, and then use a GUI or web based tool to enter the translations for each string, and then at the end export the updated file and send it back to the developers. Plus, the translation management system makes it easy to keep track of progress (what % of strings have been translated so far), automate review (require each translation to be signed off by a second translator), etc – but, translation management systems can't import/export source code, but they often can import/export message catalogs.
I wonder if you could create some kind of domain-specific language that would be easier for a translator to interact with, without said translator needing to understand the nuances of the underlying programming language, or deal with anything more complicated than non-nested if/case statements.
None of my translator friends has had anything good to say about those tools, though admittedly I know a small skewed sample of more technically-inclined types.
See also the "Plural-Forms" documentation in the GNU gettext manual – https://www.gnu.org/software/gettext/manual/html_node/Plural... – which also talks about supporting languages with much more complex pluralisation rules than English (particularly Slavic languages and Arabic)
Apple’s Stringsdict approaches this exact problem, though unfortunately first-party documentation is limited. It’s a pretty mature mechanism and yes pretty freely within apple’s own frameworks. See “plural and gender support” here:
22 comments
[ 4.2 ms ] story [ 66.0 ms ] threadAnd, people have become used to it, so for younger people it seems perfectly normal; and everybody who hates it either doesn't use computers, or will die soon enough.
Since it does not actually hasten their death (or deaths -- a fine point), it is the clear winner.
I don't see what logic connects statements before, and after "therefore", sorry.
Now add branches for Brazilian Portuguese and Lingala, which has different strings for 0 or 1, not just 1.
Now add branches for Latvian and Latgalian, which use different strings when the number ends in 0, and still more different strings when the number ends in 1, except for 11.
Now add branches for Slovak and Czech, which don't just have different strings for 1, but additional strings for 2–4.
Now add branches for Irish Gaelic, which has different strings for 1, more for 2, yet more for 3–6, and again different strings for 7–10.
Now add branches for Arabic, which has different strings for 0, more strings for 1, other strings for 2, more strings for numbers ending with 03-10, additional strings for numbers ending with 00-02, excluding 0-2, and then everything else.
That's not even all of them. Who's peeing the bed now?
If you take the branch approach, you'll have hundreds of cases hardcoded into your source code for the languages you want to support. If instead the branches are in your i18n message syntax, each localized message can contain only the branches needed by that language, and your source code doesn't change at all – it just provides the numeric arguments to the i18n message itself to decide what to do with.
In addition to the system described in the article, ICU message syntax is a common choice. Some examples are here: https://formatjs.io/guides/message-syntax/#plural-format
Here's a good reference for what pluralization rules are out there in the world: https://developer.mozilla.org/en-US/docs/Mozilla/Localizatio...
2011: https://news.ycombinator.com/item?id=2095334
But we already have a very well-optimised system for expressing functions: whatever programming language we're actually working in. We already have the concept of a bundle of related functions that implements a particular polymorphic interface: a class.
Make an interface that represents what you need each translation - that is, language implementation - to provide. Write implementations of that interface, in collaboration with your translators (if your language doesn't let you write code in a way that a reasonably intelligent translator can read and verify, if not write, get a better language). Less awkward than gettext, and far more effective.
[1] https://en.wikipedia.org/wiki/XLIFF
https://www.objc.io/issues/9-strings/string-localization/#Pl...