How does the text construct work for internationalization?
← Classes and OOP · Ref: Q113
EK9 has a built-in 'text' construct for internationalization. You define text components per locale, and the compiler validates that all locales have the same methods.
TEXT CONSTRUCT
Define text for a specific locale:
defines text for "en" Greetings hello "Hello!" welcomeUser -> name as String `Welcome, ${name}!`
TEXT METHODS
Methods can be simple (no parameters) or parameterised with typed arguments:
farewell
-> name as String
`Goodbye, ${name}!`
Parameters are interpolated with '${variable}' syntax.
MULTIPLE LOCALES
Define the same text component for each locale:
defines text for "fr" Greetings hello "Bonjour!" welcomeUser -> name as String `Bienvenue, ${name}!`
COMPILER VALIDATION
The compiler checks that all locales define exactly the same methods with the same parameter types. Missing or mismatched methods are compile-time errors.
RUNTIME LOCALE SELECTION
Create the text component with a locale string:
greetings <- Greetings("en") greetings.hello()
See Q37 for strings. See Q43 for escape and interpolation. See Q111 for components. See Q119 for constructs overview.
Example
defines module qa.oop.textconstruct defines text for "en" Greetings hello "Hello!" welcomeUser -> name as String `Welcome, ${name}!` farewell -> name as String `Goodbye, ${name}!` defines text for "fr" Greetings hello "Bonjour!" welcomeUser -> name as String `Bienvenue, ${name}!` farewell -> name as String `Au revoir, ${name}!` defines program TextDemo() stdout <- Stdout() // === ENGLISH TEXT === testName <- "Steve" en <- Greetings("en") stdout.println(en.hello()) stdout.println(en.welcomeUser(testName)) stdout.println(en.farewell(testName)) // === FRENCH TEXT === fr <- Greetings("fr") stdout.println(fr.hello()) stdout.println(fr.welcomeUser(testName)) stdout.println(fr.farewell(testName))
Common mistakes
E07150 — All locale variants of a text component must define exactly the same methods. Renaming 'farewell' to 'bonjour' in the fr variant means fr no longer has a 'farewell' method matching en, triggering E07150. See ek9 -h E07150 for details.
Incorrect:
bonjour
-> name as String
`Bonjour encore, ${name}!`
Correct:
farewell
-> name as String
`Au revoir, ${name}!`
E07155 — Each text type name must appear only once per locale. Changing fr to en creates a second 'Greetings' definition for locale en, triggering E07155 — duplicate text type for locale. See ek9 -h E07155 for details.
Incorrect:
defines text for "en"
Correct:
defines text for "fr"
E07900 — Language codes must follow the pattern [a-z]+(_[A-Z]+)?. Uppercase base 'EN' should be lowercase 'en'. Use 'en_GB' not 'en-GB' or 'en_gb'. See ek9 -h E07900 for details.
Incorrect:
defines text for "EN"
Correct:
defines text for "en"
Other ways to ask this
- How do I do i18n in EK9?
- How does EK9 handle multiple languages and locales?
- What is the text construct in EK9?
Coming from another language?
Java: ResourceBundle with .properties files, MessageFormat for parameters, no compile-time validation across locales. Python: gettext with .po files, string formatting, no compile-time locale validation. Rust: fluent-rs or gettext-rs crates, external file based. Go: go-i18n package, JSON/TOML message files, no compile-time cross-locale validation. Kotlin: same as Java ResourceBundle. EK9: language-level 'defines text for locale' construct, typed parameters with interpolation, compiler validates all locales have matching method signatures.
Keywords: construct, internationalization, locale, translation, language, text, object-oriented, validation, compiler, i18n, constant, interpolation