How do I use constants across modules in EK9?
← Constants and Immutability · Ref: Q142
EK9 constants belong to the module, not to individual files. Within the same module, constants are visible across all files without any import. For cross-module access, EK9 provides two mechanisms: fully qualified names and the references block.
SAME-MODULE ACCESS
Constants defined in one file are visible in all other files that define the same module. If two files both declare 'defines module com.example.app', they share the same constant namespace. No import or reference is needed.
FULLY QUALIFIED ACCESS
You can access a constant from another module using its fully qualified name:
value <- other.module::CONSTANT_NAME
The :: operator separates the module name from the constant name. This works anywhere without importing the module first.
REFERENCES IMPORT
The 'references' block imports symbols from other modules for short-name access:
references net.customer.geometry::Pi
After this declaration, you can use Pi directly instead of net.customer.geometry::Pi. This is purely a convenience; it does not change the constant's behaviour.
MIXING STYLES
You can mix short names (from references) and fully qualified names in the same file and even in the same expression. Use whichever is clearer in context. For widely-used constants, import via references. For one-off access, use the fully qualified form.
MODULE-LEVEL SCOPE
Constants are module-level declarations, just like classes, functions, and programs. They participate in the same visibility and access rules. A constant is accessible from any code that can reference its module.
See Q6 for how modules work in EK9. See Q13 for the difference between packages and modules. See Q140 for defining constants. See Q141 for copy-on-access protection.
Example
defines module qa.constants.crossmodule defines constant Pi <- 3.14159 maxItems <- 100 appName <- "ConstDemo" defines function circumference() -> radius as Float <- rtn as Float: 2.0 * Pi * radius describe() -> name as String <- rtn as String: `${appName}: ${name}` defines program CrossModuleConstantsDemo() stdout <- Stdout() // === SAME-MODULE ACCESS: constants visible without import === stdout.println(`Pi: ${Pi}`) stdout.println(`Max items: ${maxItems}`) stdout.println(`App: ${appName}`) // === CONSTANTS USED IN SAME-MODULE FUNCTIONS === circ <- circumference(5.0) stdout.println(`Circumference of radius 5: ${circ}`) desc <- describe("test") stdout.println(`Description: ${desc}`) // === CONSTANTS IN EXPRESSIONS ACROSS THE MODULE === halfMax <- maxItems / 2 stdout.println(`Half max: ${halfMax}`) fullGreeting <- appName + " v1.0" stdout.println(`Full: ${fullGreeting}`)
Common mistakes
E07890 — Module-level constants cannot be reassigned. Attempting to modify maxItems with := triggers E07890. Derive new values from constants using expressions instead. See ek9 -h E07890 for details.
Incorrect:
maxItems := 50
Correct:
halfMax <- maxItems / 2
E50001 — EK9 is case-sensitive. The constant is 'Pi' not 'pi'. Constant names must match exactly wherever referenced. See ek9 -h E50001 for details.
Incorrect:
stdout.println(`Pi: ${pi}`)
Correct:
stdout.println(`Pi: ${Pi}`)
E50060 — EK9 does not have toString(). Use string interpolation or the $ operator. See ek9 -h E50060 for details.
Incorrect:
stdout.println(maxItems.toString())
Correct:
stdout.println(`Max items: ${maxItems}`)
Other ways to ask this
- How do I access constants from another module?
- Can I share constants between files in EK9?
- How do references work with constants?
Coming from another language?
Java: public static final fields accessed via ClassName.CONSTANT, import statements for short access. Python: module-level variables, import or from-import. Go: exported constants (uppercase) accessible as package.Constant. Rust: pub const in module, use statement for import. EK9: module-level constants, visible across same-module files automatically, fully qualified access via :: or short names via references block.
Keywords: cross, constant, scope, access, module, qualified, reference, share, import