What are the naming conventions for functions in EK9?

← Variable Naming Rules and Conventions · Ref: Q294

EK9 uses camelCase for standalone functions and methods, and PascalCase for programs, services, and abstract function types.

STANDALONE FUNCTIONS

camelCase, verb-first when performing an action: calculateTotal, formatDate, validateEmail. The name describes what the function does.

ABSTRACT FUNCTIONS

PascalCase because they serve as type contracts: Predicate, Comparator, Transformer, FormatName. Abstract functions define the signature that concrete implementations must follow.

METHODS

camelCase, verb-first: getName, setStatus, calculateDiscount, processPayment. Methods describe operations on the object.

PURE FUNCTIONS

Same camelCase naming. The 'as pure' modifier communicates purity; the name communicates intent. Use verbs that suggest computation: compute, calculate, format, validate, derive.

OPERATORS

Use standard operator symbols, not names: operator +, operator ==, operator $. Operator implementations do not need naming conventions since they follow the fixed operator set.

PROGRAMS

PascalCase nouns: HelloWorld, InventoryManager, DataMigrator. Programs are entry points and named like types.

SERVICES

PascalCase nouns: UserService, AuthenticationService, OrderProcessor. Services define REST endpoints and are named for their domain.

See Q292 for variable naming. See Q293 for type naming. See Q49 for function basics. See Q96 for operator overloading.

Example

defines module qa.naming.functions

  defines function

    calculateTotal() as pure
      ->
        unitPrice as Float
        quantity as Integer
      <- totalPrice as Float: unitPrice * Float(quantity)

    formatCurrency() as pure
      -> amount as Float
      <- formattedAmount as String: "USD " + $amount

    isEligibleForDiscount() as pure
      -> orderTotal as Float
      <- isEligible as Boolean?

      discountThreshold <- 100.0
      isEligible :=? orderTotal > discountThreshold

    ValidateInput() as pure abstract
      -> userInput as String
      <- isValid as Boolean?

  defines class

    OrderProcessor
      orderName as String: String()
      orderTotal as Float: 0.0

      OrderProcessor()
        ->
          name as String
          total as Float
        this.orderName :=: name
        this.orderTotal :=: total

      getOrderName() as pure
        <- rtn as String: orderName

      getOrderTotal() as pure
        <- rtn as Float: orderTotal

      applyDiscount()
        -> discountRate as Float
        orderTotal: orderTotal * (1.0 - discountRate)

      formatReceipt() as pure
        <- receipt as String: `Receipt: ${orderName} - ${formatCurrency(orderTotal)}`

      operator $ as pure
        <- rtn as String: `Order(${orderName}, ${orderTotal})`

      override operator ? as pure
        <- rtn as Boolean: orderName? and orderTotal?

  defines program

    FunctionConventionsDemo()
      stdout <- Stdout()

      // === STANDALONE FUNCTIONS: camelCase, verb-first ===

      totalPrice <- calculateTotal(29.99, 3)
      formattedPrice <- formatCurrency(totalPrice)
      stdout.println(`Total: ${formattedPrice}`)

      // === PURE FUNCTION: same camelCase ===

      isEligible <- isEligibleForDiscount(totalPrice)
      stdout.println(`Eligible for discount: ${isEligible}`)

      // === METHODS: camelCase, verb-first ===

      processor <- OrderProcessor("Laptop Bundle", totalPrice)
      stdout.println(processor.formatReceipt())
      processor.applyDiscount(0.10)
      stdout.println(processor.formatReceipt())

      // === ABSTRACT FUNCTION TYPE: PascalCase ===

      emailValidator <- () is ValidateInput as pure function
        isValid :=? userInput contains "@"

      testEmail <- "alice@example.com"
      stdout.println(`Valid email: ${emailValidator(testEmail)}`)

Common mistakes

E50060 — The method is named 'applyDiscount' not 'setDiscount'. Calling a method that does not exist on the type produces a resolution error. See ek9 -h E50060 for details.

Incorrect:

processor.setDiscount(0.10)

Correct:

processor.applyDiscount(0.10)
Other ways to ask this
  • How should I name functions and methods in EK9?
  • What naming style do EK9 programs and services use?
  • How do I name standalone functions versus methods in EK9?

Coming from another language?

Java: camelCase for methods (convention), PascalCase for classes, no standalone functions. Python: snake_case for functions and methods (PEP 8). Rust: snake_case for functions (enforced as warning). Go: camelCase for functions, PascalCase for exported. C++: no standard naming convention. Kotlin: camelCase for functions, PascalCase for classes. Swift: camelCase for functions and methods. JavaScript: camelCase for functions (convention). EK9: camelCase for functions and methods, PascalCase for programs, services, and abstract function types.

Keywords: convention, pure, program, camelCase, side-effect, operator, verb, service, immutable, method, function, identifier, naming, PascalCase