# Inflecting error/warning messages correctly

**URL:** <https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648>\
**Category:** General Usage\
**Created:** [August 26, 2024, 11:02pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648 "2024-08-26T23:02:23Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)\
**Post date:** [August 26, 2024, 11:02pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/1 "2024-08-26T23:02:23Z")

</div>

In my old Perl days I got a lot of great mileage out of the [Lingua::EN::Inflect](https://metacpan.org/pod/Lingua::EN::Inflect) module, which helped write messages like so:

```julia
print "I saw $n ", PL("cat", $n), "\n";

```

and depending on the value of `$n`, that would generate `"I saw 0 cats"`, `"I saw 1 cat"`, `"I saw 2 cats"`, etc.

Another precedent, but for R instead of Perl, is in the [CLI library](https://cli.r-lib.org/reference/pluralization.html). It’s not quite as ambitious.

I’ve done a bunch of googling today to see whether Julia has a similar module or mechanism, but I’ve come up empty so far. I did find [ResourceBundles](https://docs.juliahub.com/General/ResourceBundles) and some `gettext`-based stuff, but can’t really see how to use those in this way.

I don’t need to support multiple languages.

Any suggestions?

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [August 27, 2024, 2:12pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/2 "2024-08-27T14:12:15Z")

</div>

If you don’t need very smart pluralization, it seems you could do this with a simple function and no need for a full package. For example:

```julia-repl
julia> pluralize(n::Real, singular::AbstractString, plural::AbstractString=singular*"s") = n == 1 ? singular : plural
pluralize (generic function with 2 methods)

julia> n = 1; println("I saw $n $(pluralize(n, "cat"))!")
I saw 1 cat!

julia> n = 2; println("I saw $n $(pluralize(n, "cat"))!")
I saw 2 cats!

julia> n = 1; println("I saw $n $(pluralize(n, "doggy", "doggies"))!")
I saw 1 doggy!

julia> n = 2; println("I saw $n $(pluralize(n, "doggy", "doggies"))!")
I saw 2 doggies!

```

This will assume (by default) that pluralization is done by appending an `"s"`, but allows for a custom plural to be optionally specified instead. If your use case is relatively simple, this may be sufficient.

If you need variable word selection but are willing to specify words with both their singular and plural forms, it’s a tad more involved but can still be done relatively simply. If that’s your regime, then we can offer suggestions to that effect.

---

<div class="post-metadata">

**Author:** ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)\
**Post date:** [August 27, 2024, 3:05pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/3 "2024-08-27T15:05:24Z")

</div>

Thanks @mikmoore . Yeah, I know I can put something together for this like the function you suggested, but I don’t love putting stuff like this into domain-specific code when it’s really orthogonal functionality that would live better somewhere else.

If there’s not something already out there, I’ll probably make it a local package and let it ferment for a while, then possibly release publicly at a later date.

---

<div class="post-metadata">

**Author:** ![\_bernhard](https://avatars.discourse-cdn.com/v4/letter/_/bc79bd/32.png) [@\_bernhard](https://discourse.julialang.org/u/_bernhard)\
**Post date:** [August 27, 2024, 8:36pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/4 "2024-08-27T20:36:43Z")

</div>

> [@Ken\_Williams](#):
>
> I’ll probably make it a local package and let it **ferment** for a while, then possibly release publicly at a later date.

I mean, who doesn’t enjoy a properly aged Pkg kimchi? 😋

However, a quick google search turned up something that seems to do what you want.

> **[GitHub - TotalVerb/EnglishText.jl: Utilities for English-language quirks in Julia](https://github.com/TotalVerb/EnglishText.jl/)**
>
> Utilities for English-language quirks in Julia

While it hasn’t received any work in quite some time, it’s not ancient either and probably not too much effort to make it usable again. 🙂

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 27, 2024, 8:48pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/5 "2024-08-27T20:48:44Z")

</div>

> [@\_bernhard](#):
>
> While it hasn’t received any work in quite some time, it’s not ancient either and probably not too much effort to make it usable again.

It seems to work fine as-is. Just because something is old doesn’t mean it’s broken.

Just define e.g.

```julia
using EnglishText
pl(noun::AbstractString, n::Integer) = n != 1 ? pluralize(noun, classical=false) : noun

```

to mimic the Perl function mentined above.

---

<div class="post-metadata">

**Author:** ![\_bernhard](https://avatars.discourse-cdn.com/v4/letter/_/bc79bd/32.png) [@\_bernhard](https://discourse.julialang.org/u/_bernhard)\
**Post date:** [August 27, 2024, 8:53pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/6 "2024-08-27T20:53:19Z")

</div>

I didn’t mean to imply otherwise.

It’s just that I did not try it out but a quick glance over the files seemed fine - hence ‘not too much effort’.

My main point was simply to make @Ken_Williams aware of its existance.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [August 28, 2024, 12:38pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/7 "2024-08-28T12:38:15Z")

</div>

I ~~don’t know of such a library~~ (EDIT: except for EnglishText.jl, at least I don’t know the best library or general for more languages), except in Python that you could use with PythonCall.jl directly (should be ok, since I doubt this is speed-critical, but either way, someone should make a Julia package, wrapping Python, to use it indirectly, then it could later be rewritten as pure Julia if speed-critical, to get rid of Python dependency):

> **[inflect](https://pypi.org/project/inflect/)**
>
> Correctly generate plurals, singular nouns, ordinals, indefinite articles

It would be nice to have one, that not only supports English and exceptions like:

> “VAX” =\> “VAXen”; # SINGULAR =\> PLURAL

E.g. for our Icelandic currency, króna (ISK), plural krónur:

1 króna  
2 krónur  
…  
11 krónur  
…  
21 króna (singular word for used, also all nouns have 16 forms in Icelandic, 8 thereof singular; all adjectives have 120 forms)  
…  
101 króna …

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 28, 2024, 12:52pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/8 "2024-08-28T12:52:07Z")

</div>

> [@Palli](#):
>
> It would be nice to have one, that not only supports English and exceptions like:

EnglishText.jl indeed supports English and many common exceptions:

```julia
julia> pluralize("ox")
"oxen"

```

It currently pluralizes “krona” (which is usually written without accents in English) as “kronas” rather than “kronor” (the anglicized plural), but that rule could easily be added.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 28, 2024, 1:02pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/9 "2024-08-28T13:02:02Z")

</div>

> [@Palli](#):
>
> It would be nice to have one, that not only supports English and exceptions like:

It will probably be written by someone who (1) needs it, and (2) speaks the language. If you really need it, why not write it?

---

<div class="post-metadata">

**Author:** ![Ken\_Williams](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ken_williams/32/5289_2.png) [@Ken\_Williams](https://discourse.julialang.org/u/Ken_Williams)\
**Post date:** [August 28, 2024, 8:55pm UTC](https://discourse.julialang.org/t/inflecting-error-warning-messages-correctly/118648/10 "2024-08-28T20:55:32Z")

</div>

Thanks everyone for the great replies!

In the past day I’ve been reflecting on this and I think I may be attracted to the [CLI library](https://cli.r-lib.org/reference/pluralization.html) approach a little more than the [Lingua::EN::Inflect](https://metacpan.org/pod/Lingua::EN::Inflect) approach. The big difference being whether the package itself knows about your language (English, in this case - not Julia) and how plurals are formed, or whether you supply that knowledge as the caller.

Specifically, it’s the difference between these two options (using a pseudo-syntax `p""` I’m just making up):

- `p"There {verb:was} {n} {noun:apple} in the basket."` (`Inflect` style)
- `p"There {?was,were} {n} apple{?s} in the basket."` (`CLI` style)

In the first case, it “knows” how to conjugate the verb `was` and how to form the plural of `apple` if necessary.

In the second case, you manually tell it that info and it’s just providing the syntactic sugar to get the right strings selected.

It’s kind of interesting to me that often, the latter is a bit more concise and easy to read than the former, and it doesn’t have to be as smart either (and will therefore probably make fewer mistakes?).
