Plural categories for all Unicode-registered languages, extracted from public XML data. These can be used in localisation systems to branch on a translation according to some incoming number. For instance, consider how “1 day” and “2 days” in English might be translated to Japanese, a language with no plurals.
(in-package :plurals)
(cardinal :en "1"):ONE
(in-package :plurals)
(cardinal :ja "1"):OTHER
plurals is written in portable Common Lisp and has no dependencies.
| Compiler | Status |
|---|---|
| SBCL | ✅ |
| ECL | ✅ |
| Clasp | ❓ |
| ABCL | ✅ |
| CCL | ✅ |
| Clisp | ✅ |
| Allegro | ✅ |
| LispWorks | ❓ |
Languages differ in how they decline nouns to match associated numbers. For instance, Germanic and Romance languages tend only to distinguish between “one” and “not one”:
| Language | One | Two | Three |
|---|---|---|---|
| English | One apple | Two apples | Three apples |
| German | Ein Apfel | Zwei Äpfel | Drei Äpfel |
| Latin | ŪNUM MALUM | DUO MALA | TRIA MALA |
Meanwhile, Arabic famously differentiates between 0, 1, 2, 3-10, 11-99, and
anything above 100. When programming a user interface in English, it might be
enough to manually detect a number and append an s where appropriate, but for
languages with complex plural transformations (“Äpfel” above) or multiple plural
categories like Arabic, this naive strategy breaks down.
The people at Unicode gathered these rules and noticed that humans divide
quantities into the following categories: zero, one, two, few, many, and other.
This plurals library provides functions for determining which of these
categories a given number belongs to, depending on a locale (like :en for
English).
The examples below use (in-package :plurals) for brevity, but you’re free to set
a local nickname as you wish.
You will notice that the numeric inputs are strings; this is due to a some plural rules taking into account the number of fraction digits, including trailing zeroes. In normal numeric form, those zeroes would be lost and accuracy would be reduced.
This is the ordinary case, where you’re trying to distinguish the category for basic counts of things. For instance in sentences like:
I have two cats.
While English treats all “not one” numbers as the same category…
(in-package :plurals)
(cardinal :en "2"):OTHER
…Hebrew does not!
(in-package :plurals)
(cardinal :he "2"):TWO
The “ordinal” categories are for “ordering”, for instance in phrases like:
He was 1st in the race, she was 2nd, and he was 3rd.
English speakers may be surprised to hear that many languages in fact don’t make this distinction.
(in-package :plurals)
(ordinal :en "3"):FEW
(in-package :plurals)
(ordinal :ja "3"):OTHER