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
#!ek9 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 E08090 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: boolean, camelCase, collection, convention, descriptive, field, identifier, naming, parameter, pattern, style, variable