What are the naming conventions for variables in EK9?
← Variable Naming Rules and Conventions · Ref: Q292
EK9 uses camelCase for all variable names: local variables, fields, parameters, and return values. The compiler enforces descriptive naming, so every variable name should communicate its purpose.
LOCAL VARIABLES
Use camelCase with descriptive intent: customerName, orderCount, isActive, totalPrice. Infer types with <- for concise declarations. Avoid abbreviations: use customer not cust, message not msg.
FIELDS
Same as local variables. Fields are private by default and must be initialised inline: greeting as String: "Hello". Use descriptive names that describe the data, not the type: accountBalance not floatBalance.
PARAMETERS
Parameters require explicit types. Use names that describe what the parameter represents: -> firstName as String, not -> s as String. For multiple parameters, each on its own line under ->.
RETURN VALUES
Return values are named and describe the output: <- formattedName as String. The name documents what the function produces. Choose names like calculatedTotal, validatedInput, formattedOutput.
BOOLEAN NAMING
Use is/has/can/should prefixes: isActive, hasPermission, canEdit, shouldRetry. These make conditions read naturally: if isActive, while hasPermission.
COLLECTION NAMING
Use plural nouns: customers, orderItems, errorMessages. This distinguishes collections from single items and makes for-in loops read naturally: for customer in customers.
AVOID
Abbreviations (use customer not cust), Hungarian notation (not strName), type-in-name (not nameString), generic names (not item1, item2).
See Q22 for variable declarations. See Q293 for type naming. See Q294 for function naming.
Example
defines module qa.naming.variables defines class CustomerOrder customerName as String: String() orderItems as List of String: List() of String totalPrice as Float: 0.0 isComplete as Boolean: false CustomerOrder() -> name as String items as List of String price as Float this.customerName :=: name this.orderItems :=: items this.totalPrice :=: price getCustomerName() as pure <- rtn as String: customerName getOrderItems() as pure <- rtn as List of String: orderItems getTotalPrice() as pure <- rtn as Float: totalPrice markComplete() isComplete: true hasItems() as pure <- rtn as Boolean: length orderItems > 0 operator $ as pure <- rtn as String: `Order(${customerName}, ${length orderItems} items, ${totalPrice})` override operator ? as pure <- rtn as Boolean: customerName? and totalPrice? defines function formatOrderSummary() as pure -> customerName as String itemCount as Integer totalPrice as Float <- formattedSummary as String: `${customerName}: ${itemCount} items, total ${totalPrice}` isHighValueOrder() as pure -> orderTotal as Float <- isHighValue as Boolean? highValueThreshold <- 500.0 isHighValue :=? orderTotal > highValueThreshold defines program VariableConventionsDemo() stdout <- Stdout() // === LOCAL VARIABLES: camelCase, descriptive === customerName <- "Alice" orderCount <- 3 isActive <- true totalPrice <- 299.95 stdout.println(`Customer: ${customerName}, Orders: ${orderCount}`) stdout.println(`Active: ${isActive}, Total: ${totalPrice}`) // === BOOLEAN NAMING: is/has/can/should prefixes === hasPermission <- true canEdit <- isActive and hasPermission maxRetries <- 5 shouldRetry <- orderCount < maxRetries stdout.println(`Can edit: ${canEdit}, Should retry: ${shouldRetry}`) // === COLLECTION NAMING: plural nouns === orderItems <- ["Widget", "Gadget", "Sprocket"] errorMessages <- List() of String stdout.println(`Items: ${orderItems}`) stdout.println(`Errors: ${errorMessages}`) // === FIELDS AND METHODS: descriptive throughout === order <- CustomerOrder(customerName, orderItems, totalPrice) stdout.println($order) stdout.println(`Has items: ${order.hasItems()}`) // === RETURN VALUES: describe the output === formattedSummary <- formatOrderSummary(customerName, length orderItems, totalPrice) stdout.println(formattedSummary) // === HIGH VALUE CHECK === isExpensive <- isHighValueOrder(totalPrice) stdout.println(`High value: ${isExpensive}`)
Common mistakes
E11031 — The name 'obj' is non-descriptive and banned by the compiler. Use a name that describes what the variable represents. See ek9 -h E11031 for details.
Incorrect:
obj <- true canEdit <- isActive and obj
Correct:
hasPermission <- true canEdit <- isActive and hasPermission
E08090 — If 'canEdit' is declared but never used in any output or expression, the compiler rejects it as an unused variable. See ek9 -h E50050 for details.
Incorrect:
editSummary <- `Can edit: ${canEdit}, Should retry: ${shouldRetry}`
Correct:
stdout.println(`Can edit: ${canEdit}, Should retry: ${shouldRetry}`)
Other ways to ask this
- How should I name variables in EK9?
- What style should variable names follow in EK9?
- What naming pattern does EK9 use for fields and parameters?
Coming from another language?
Java: camelCase by convention (not enforced), fields often prefixed with m_ in Android. Python: snake_case for variables and functions (PEP 8), not enforced. Rust: snake_case for variables and functions (enforced as warning). Go: camelCase, exported names start with uppercase. C/C++: no standard, varies by project (camelCase, snake_case, Hungarian). Kotlin: camelCase by convention, similar to Java. JavaScript: camelCase by convention, not enforced. Swift: camelCase for variables. EK9: camelCase enforced by convention, descriptive naming enforced by compiler, no abbreviations or generic names allowed.
Keywords: variable, descriptive, camelCase, style, collection, boolean, convention, identifier, field, parameter, pattern, naming