Softanza
StartFrançais
Softanza
Research · narration

Software Global Reach: Locale Management the Softanza Way

The Softanza library for Haro brings a refreshingly intuitive approach to locale management, wrapping the Softanza Engine's powerful internationalization capabilities in an API that feels natural and expressive.

by Mansour Ayouni · in the repository since 2025-10-01 · feature essay · area Internationalization

The Core: stzLocale object

Softanza's locale management centers around the object-oriented stzLocale class, which simplifies dynamic locale configuration. The library offers remarkable flexibility in locale creation using standard IETF language tags, descriptive hash lists, or partial information with smart inference.

Using standard language tags:

Haro
o1 = new stzLocale("ar-TN")
? o1.Abbreviation()  #--> ar_TN
? o1.CountryName()   #--> tunisia
? o1.LanguageName()  #--> arabic

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

Using descriptive hash lists:

Haro
StzLocaleQ([ :Country = :Tunisia ]) {
    ? Abbreviation()   #--> ar_TN
    ? CountryName()    #--> tunisia
}

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

The library intelligently infers missing information. Provide just a language, and it determines the default country:

Haro
o1 = new stzLocale([ :Language = "romanian" ])
? o1.Abbreviation()   #--> ro_RO
? o1.CountryName()    #--> romania

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

Provide only a country:

Haro
o1 = new stzLocale([ :Country = "Niger" ])
? o1.Abbreviation()   #--> fr_NE
? o1.LanguageName()   #--> french

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

Cultural Calendar Awareness

Different cultures start their week on different days. Softanza correctly handles locale-specific calendar ordering:

Haro
StzLocaleQ([ :Country = :Iran ]) {
    # Iran's week begins on Saturday
    ? NthDayOfWeek(1)             #--> saturday
    ? NativeNthDayOfWeek(1)       #--> شنبه
    ? NativeNthDayOfWeekSymbol(1) #--> د
}

o1 = new stzLocale("en_US")
? o1.FirstDayOfWeek()  #--> sunday

illustration

Locale-Aware Text Transformation

The library understands cultural nuances in text formatting. Title case rules vary by language:

Haro
StzLocaleQ([ :Language = :French ]) {
    ? ToTitlecase("in search of lost time")
    #--> In search of lost time  // French style
}

StzLocaleQ([ :Language = :English ]) {
    ? ToTitlecase("in search of lost time")
    #--> In Search Of Lost Time  // English style
}

illustration

Case conversion respects locale conventions:

Haro
o1 = new stzLocale("en_US")
? o1.ToLowercase("FDMLj")  #--> fdmlj
? o1.ToUppercase("FDMLj")  #--> FDMLJ

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

Country Phone Codes

International dialing codes are readily available:

Haro
? StzLocaleQ("ar_eg").CountryPhoneCode()  #--> +20
? StzLocaleQ([ :Country = :Niger ]).CountryPhoneCode()  #--> +227

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

Days and Months in Native Languages

The library excels at providing localized calendar data:

Haro
? NamesOfDaysIn(:Japanese)
#--> [ "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" ]

? NamesOfDaysIn(:Persian)
#--> [ "شنبه", "یکشنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنجشنبه", "جمعه" ]

illustration

You can bridge languages elegantly:

Haro
? Association([ NamesOfDaysIn(:English), NamesOfDaysIn(:Japanese) ])
#--> [
#     [ "Sunday", "日曜日" ],
#     [ "Monday", "月曜日" ],
#     ...
#   ]

illustration

Comprehensive Currency Information

Currency handling is thorough and culturally aware:

Haro
StzLocaleQ("ar_TN") {
    ? Currency()                #--> Tunisian Dinar
    ? CurrencyXT(:NativeName)   #--> دينار تونسي
    ? CurrencySymbol()          #--> د.ت.‏
    ? CurrencyAbbreviation()    #--> TND
    ? CurrencyFraction()        #--> Millime
    ? CurrencyBase()            #--> 1000
}

illustration

For complete currency details:

Haro
o1 = new stzLocale("ru_RU")
? o1.CurrencyInfo()
#--> [
#     [ "name", "Russian Ruble" ],
#     [ "nativename", "российский рубль" ],
#     [ "symbol", "₽" ],
#     [ "fractionalunit", "Kopek" ],
#     ...
#   ]

illustration

Geo-Linguistic Details

The library provides fine-grained access to geographical and linguistic information in both English and native representations:

Haro
StzLocaleQ("ar_TN") {
    ? CountryName()          #--> tunisia
    ? CountryNativeName()    #--> تونس
    ? LanguageName()         #--> arabic
    ? LanguageNativeName()   #--> العربية
}

StzLocaleQ("fa_IR") {
    ? CountryName()          #--> iran
    ? CountryNativeName()    #--> ايران
    ? LanguageName()         #--> persian
    ? LanguageNativeName()   #--> فارسی
}

illustration

Formatting Symbols

The API provides access to locale-specific formatting conventions:

Haro
o1 = new stzLocale("en_US")
? o1.DecimalPoint()      #--> "."
? o1.GroupSeparator()    #--> ","
? o1.Exponential()       #--> e
? o1.NegativeSign()      #--> "-"
? o1.PositiveSign()      #--> "+"
? o1.Percent()           #--> "%"
? o1.amText()            #--> AM
? o1.pmText()            #--> PM

run on 2026-10-08 20:43 at commit 4a184e6f0: kept its promise

Comparison with Other Frameworks

Softanza's approach to locale management stands out in the landscape of programming tools:

Feature Softanza (Haro) JavaScript (Intl) Python (Babel/locale) Java (Locale/ICU) Ruby (i18n)
Initialization Style Natural language hashes Constructor codes Module functions Static factory methods YAML config files
Inference ✅ Smart defaults (country→lang, lang→country) ❌ Explicit only ⚠️ Limited ❌ Explicit only ❌ Explicit only
Native Text ✅ Built-in (currency, days, months) ⚠️ Via DisplayNames API ✅ Via CLDR ✅ Via ICU ⚠️ Plugin-dependent
Currency Details ✅ Comprehensive (fraction, base, native) ⚠️ Basic formatting ✅ Via Babel ✅ Detailed ⚠️ Limited
Cultural Calendar ✅ Week start, native symbols ⚠️ Manual calculation ⚠️ Limited ✅ Full support ⚠️ Limited
Syntax Philosophy Conversational blocks Functional chaining Procedural Object-oriented Convention DSL
Query Functions ✅ Discovery APIs (e.g., CountriesforWhichDefaultLanguageIs) ❌ None ❌ None ❌ None ❌ None
Readability StzLocaleQ([:Country = :Iran]) new Intl.Locale('fa-IR') Locale('fa', 'IR') Locale.forLanguageTag("fa-IR") I18n.locale = :'fa-IR'

Key Differentiators:

  • Smart Inference: Softanza uniquely infers missing locale components, reducing boilerplate
  • Discovery APIs: Query functions like LanguagesForWhichDefaultCountryIs(:France) have no equivalent in other frameworks
  • Conversational Syntax: The StzLocaleQ block pattern reads like natural language
  • Comprehensive Currency: Currency fraction units and base values built-in (most frameworks require additional lookups)
  • Engine Foundation: Performance and stability inherited from the Softanza Engine's mature design

The Softanza Philosophy

What makes Softanza's locale management special is its commitment to three principles:

  1. Efficiency: Built on the Softanza Engine, leveraging battle-tested internationalization infrastructure
  2. Beauty: Expressive syntax that reads like natural language
  3. Practicality: Comprehensive coverage of real-world locale needs—from currency fractions to native symbols

The result is a library where locale management feels less like wrestling with APIs and more like having a conversation. Whether you need a quick currency symbol or comprehensive cultural information, Softanza provides it through an interface that's both powerful and pleasant to use.

Cite

Mansour Ayouni. "Software Global Reach: Locale Management the Softanza Way". Softanza narrations, 2025. https://mayouni.github.io/stzsite/en/narrations/stzlocale-locale-management-the-softanza-way.html

Run in Haro's name on 2026-10-08 20:43 inside the library at commit 4a184e6f0, block after block in one process: 7 of 14 blocks kept their promise; the others are illustrations. The code of the articles is Haro code. Where an article was written before the language took its present name, the name was changed and nothing else. Genre, area and series read from the file's name, the year from its first commit: derived, until the article carries its own header. The file on GitHub(opens in a new tab)