How do I declare a variable in EK9?
← Getting Started · Ref: Q22
EK9 provides several ways to declare variables and uses modifiers to control visibility, purity, and extensibility.
VARIABLE DECLARATIONS
1. Type inference with <- (idiomatic)
name <- "Steve" Inferred as String count <- 42 Inferred as Integer
2. Explicit type
name as String: "Steve"
Use when declaring base types for polymorphism.
3. Reassignment operators
name <- "Steve" Declaration (new variable) name := "John" Reassignment (existing variable) name :=? "Default" Guarded: only if currently unset
4. Class/record fields
greeting as String: "Hello" Private by default
5. Parameters and returns (explicit types required)
formatName() as pure -> first as String <- result as String: first
6. Named parameters
result <- formatName(first: "Steve", last: "Limb")
If ONE is named, ALL must be named, in declared order. Essential for dynamic functions:
multiplier <- (factor: count) is abstractOp as pure function result :=? operand * factor
MODIFIERS
public/protected/private Access (default: package-private) pure No side effects, enforced on overrides abstract Must be overridden override Required when replacing parent method open Allows extension (closed by default) default Auto-generates operators dispatcher Multi-method dispatch by argument type sanitized Input sanitization at call site
Naming: generic names ('value', 'data', 'item') rejected (E11031).
See Q49 for modifiers on functions. See Q93 for classes. See Q97 for records. See Q215 for sanitized. See Q28 for multiple variables. See Q127 for type inference. See Q290 for banned names. See Q292 for naming conventions.
Example
defines module qa.variables.declarations defines function formatName() as pure -> first as String last as String <- result as String: `${first} ${last}` abstractOp() as pure abstract -> operand as Integer <- result as Integer? defines class Greeter greeting as String: "Hello" Greeter() -> g as String greeting :=: g greet() -> name as String <- message as String: `${greeting}, ${name}` default operator ? defines program Declarations() stdout <- Stdout() // Type inference - idiomatic for local variables name <- "Steve" count <- 42 // Explicit type - useful when declaring a base type label as String: "Count" // Reassignment name := "John" // Using the explicitly typed variable stdout.println(`${label}: ${count}`) // Named parameters at call site full <- formatName(first: name, last: "Limb") stdout.println(full) // Dynamic function with named captures multiplier <- (factor: count) is abstractOp as pure function result :=? operand * factor stdout.println($multiplier(3)) greeter <- Greeter("Welcome") stdout.println(greeter.greet(name))
Common mistakes
E08180 — Class fields must be initialised inline with a value. An uninitialised field triggers E08180. Use a colon followed by a literal or constructor call. See ek9 -h E08180 for details.
Incorrect:
greeting as String
Correct:
greeting as String: "Hello"
E07520 — The ? operator is inherited from the base type and must use 'default' to auto-generate or 'override' for a custom implementation. Declaring bare 'operator ?' triggers E07520 because operator semantics require a Boolean return. See ek9 -h E07520 for details.
Incorrect:
operator ?
Correct:
default operator ?
E50001 — A typo in the function name 'formatNam' means the compiler cannot find any identifier with that name in scope. EK9 requires exact spelling for all identifiers. See ek9 -h E50001 for details.
Incorrect:
full <- formatNam(first: name, last: "Limb")
Correct:
full <- formatName(first: name, last: "Limb")
Other ways to ask this
- What are the different ways to declare variables in EK9?
- How does type inference work for local variables?
- What modifiers does EK9 support?
- What is the difference between <- and := and :=? operators?
Coming from another language?
Java: Type name = value with all classes open by default, Python: name = value with duck typing, Rust: let name: Type = value with immutability by default, Go: var name Type = value or name := value. EK9: <- for declaration with inference, explicit Type for API boundaries, := for reassignment, :=? for guarded assignment. Modifiers: Java has public/private/protected/abstract/final/static, EK9 replaces final with closed-by-default and has no static. EK9 adds pure, dispatcher, sanitized, and open.
Keywords: abstract, immutable, intro, sanitized, dispatcher, migrate, pure, guard, named, private, protected, default, variable, beginner, first, start, isset, parameter, open, declare, modifier, assignment, side-effect, return, safe, override, virtual, declaration, inference, null-safe, public